diff --git a/Doc/Doxyfile b/Doc/Doxyfile new file mode 100644 index 00000000..312e7819 --- /dev/null +++ b/Doc/Doxyfile @@ -0,0 +1,1904 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "Chameleon-Mini" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = Doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST = YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = DoxygenPages ../Firmware/Chameleon-Mini + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.txt *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +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 or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +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 + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# 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 = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# 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, C++ and Fortran 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 = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# 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 + +# If CLANG_ASSISTED_PARSING is set to YES, then doxygen will use the clang parser +# for more acurate parsing at the cost of reduced performance. This can be +# particularly helpful with template rich C++ code for which doxygen's built-in +# parser lacks the necessairy type information. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified at INPUT and INCLUDE_PATH. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# 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 = YES + +# 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. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +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 left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a 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_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. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, 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 (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# 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. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# 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 = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. 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, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4 + +# 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 = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). 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 = YES + +# 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 = YES + +# 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 + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# 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 = NO + +# Load style sheet 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 related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see 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 = NO + +# 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 = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when 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 = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these 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. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. 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 + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = 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 also works with HAVE_DOT disabled, but 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 = NO + +# 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 use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# 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 Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +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 +# 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 = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# 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 = NO + +# 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 generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH 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 svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# 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 MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# 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 = NO + +# 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 diff --git a/Doc/Doxygen/html/3_d_e_s___c_b_c_8h_source.html b/Doc/Doxygen/html/3_d_e_s___c_b_c_8h_source.html new file mode 100644 index 00000000..f6cda524 --- /dev/null +++ b/Doc/Doxygen/html/3_d_e_s___c_b_c_8h_source.html @@ -0,0 +1,146 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Application/3DES_CBC.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
3DES_CBC.h
+
+
+
1 /*****************************************************************************
+
2 Written and Copyright (C) by Ingo von Maurich, Timo Kasper, David Oswald,
+
3 and the Embedded Security Group of Ruhr-Universitaet Bochum.
+
4 All rights reserved.
+
5 
+
6 Contact ingo.vonmaurich@rub.de for comments & questions.
+
7 This program is free software; You may use it or parts of it or
+
8 modifiy it under the following terms:
+
9 
+
10 (1) Usage and/or redistribution and/or modification of the software
+
11 or parts of the software is permitted for non-commercial use only.
+
12 If you are interested in a commercial use please contact
+
13 ingo.vonmaurich@rub.de.
+
14 
+
15 (2a) If this software or parts are used as part of a new software, you
+
16 must license the entire work, as a whole, under this License to anyone
+
17 who comes into possession of a copy. This License will therefore
+
18 apply, to the whole of the work, and all its parts, regardless of how
+
19 they are packaged.
+
20 
+
21 (2b) You may expand this license by your own license. In this case this
+
22 license still applies to the software as mentioned in (2a) and must
+
23 not be changed. The expansion must be clearly recognizable as such. In
+
24 any case of collision between the license and the expansion the
+
25 license is superior to the expansion.
+
26 
+
27 (3) If this software or parts are used as part of a new software, you
+
28 must provide equivalent access to the source code of the entire work,
+
29 as a whole, to anyone who comes into possession of a copy, in the same
+
30 way through the same place at no further charge, as for the binary
+
31 version.
+
32 
+
33 (4) This program is distributed in the hope that it will be useful,
+
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
+
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
36 (5) These notices must be retained in any copies of any part of this
+
37 documentation and/or software.
+
38 
+
39 (6) If this software is used credit must be given to the
+
40 "Embedded Security Group of Ruhr-Universitaet Bochum, Germany" as
+
41 to the authors of the parts of the software used. This can be in the form
+
42 of a textual message at program startup or at *beginning* of the
+
43 documentation (online or textual) provided with the package.
+
44 *****************************************************************************/
+
45 
+
46 void TripleDES_CBC_Encrypt(uint8_t * plaintext, uint8_t * ciphertext,
+
47  uint8_t * keys, uint8_t * iv, uint16_t block_length);
+
+ + + + diff --git a/Doc/Doxygen/html/_antenna_level_8h_source.html b/Doc/Doxygen/html/_antenna_level_8h_source.html new file mode 100644 index 00000000..02d0a274 --- /dev/null +++ b/Doc/Doxygen/html/_antenna_level_8h_source.html @@ -0,0 +1,150 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/AntennaLevel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
AntennaLevel.h
+
+
+
1 /*
+
2  * AntennaLevel.h
+
3  *
+
4  * Created on: 24.11.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ANTENNALEVEL_H_
+
9 #define ANTENNALEVEL_H_
+
10 
+
11 #include "Common.h"
+
12 
+
13 #define ANTENNA_LEVEL_R1 10E3
+
14 #define ANTENNA_LEVEL_R2 220E0
+
15 #define ANTENNA_LEVEL_VREF 1.0
+
16 #define ANTENNA_LEVEL_RES 4096
+
17 #define ANTENNA_LEVEL_OFFSET 190 /* LSB */
+
18 
+
19 #define ANTENNA_LEVEL_MILLIVOLT 1E3
+
20 #define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) )
+
21 #define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16)
+
22 #define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5))
+
23 #define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE)
+
24 
+
25 static inline
+
26 void AntennaLevelInit(void)
+
27 {
+
28  ADCA.CTRLA = ADC_ENABLE_bm;
+
29  ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;
+
30  ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
+
31  ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc;
+
32  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
+
33  ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc;
+
34 
+
35 }
+
36 
+
37 static inline
+
38 uint16_t AntennaLevelGet(void)
+
39 {
+
40  ADCA.CH0.CTRL |= ADC_CH_START_bm;
+
41  while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) );
+
42 
+
43  ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm;
+
44 
+
45  int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET;
+
46  if (Result < 0) Result = 0;
+
47 
+
48  return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR);
+
49 }
+
50 
+
51 #endif /* ANTENNALEVEL_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_application_8h_source.html b/Doc/Doxygen/html/_application_8h_source.html new file mode 100644 index 00000000..db3fa9c6 --- /dev/null +++ b/Doc/Doxygen/html/_application_8h_source.html @@ -0,0 +1,141 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Application/Application.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Application.h
+
+
+
1 /*
+
2  * Application.h
+
3  *
+
4  * Created on: 18.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef APPLICATION_H_
+
9 #define APPLICATION_H_
+
10 
+
11 #include "../Common.h"
+
12 #include "../Configuration.h"
+
13 
+
14 /* Applications */
+
15 #include "MifareClassic.h"
+
16 
+
17 /* Function wrappers */
+
18 INLINE void ApplicationInit(void) {
+
19  ActiveConfiguration.ApplicationInitFunc();
+
20 }
+
21 
+
22 INLINE void ApplicationTask(void) {
+
23  ActiveConfiguration.ApplicationTaskFunc();
+
24 }
+
25 
+
26 INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) {
+
27  return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount);
+
28 }
+
29 
+
30 INLINE void ApplicationReset(void) {
+
31  ActiveConfiguration.ApplicationResetFunc();
+
32 }
+
33 
+
34 INLINE void ApplicationGetUid(ConfigurationUidType Uid) {
+
35  ActiveConfiguration.ApplicationGetUidFunc(Uid);
+
36 }
+
37 
+
38 INLINE void ApplicationSetUid(ConfigurationUidType Uid) {
+
39  ActiveConfiguration.ApplicationSetUidFunc(Uid);
+
40 }
+
41 
+
42 #endif /* APPLICATION_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_button_8h_source.html b/Doc/Doxygen/html/_button_8h_source.html new file mode 100644 index 00000000..c0cb9654 --- /dev/null +++ b/Doc/Doxygen/html/_button_8h_source.html @@ -0,0 +1,139 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Button.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Button.h
+
+
+
1 /*
+
2  * Button.h
+
3  *
+
4  * Created on: 13.05.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef BUTTON_H_
+
9 #define BUTTON_H_
+
10 
+
11 #include "Common.h"
+
12 #include <avr/io.h>
+
13 #include "Application/Application.h"
+
14 
+
15 #define BUTTON_PORT PORTA
+
16 #define BUTTON_MASK PIN6_bm
+
17 #define BUTTON_PINCTRL PIN6CTRL
+
18 
+
19 typedef enum {
+
20  BUTTON_ACTION_NONE,
+
21  BUTTON_ACTION_UID_RANDOM,
+
22  BUTTON_ACTION_UID_LEFT_INCREMENT,
+
23  BUTTON_ACTION_UID_RIGHT_INCREMENT,
+
24  BUTTON_ACTION_UID_LEFT_DECREMENT,
+
25  BUTTON_ACTION_UID_RIGHT_DECREMENT,
+
26  BUTTON_ACTION_CYCLE_SETTINGS,
+
27 
+
28  /* This has to be last element */
+
29  BUTTON_ACTION_COUNT
+
30 } ButtonActionEnum;
+
31 
+
32 void ButtonInit(void);
+
33 void ButtonTick(void);
+
34 
+
35 void ButtonGetActionList(char* ListOut, uint16_t BufferSize);
+
36 void ButtonSetActionById(ButtonActionEnum Action);
+
37 void ButtonGetActionByName(char* ActionOut, uint16_t BufferSize);
+
38 bool ButtonSetActionByName(const char* Action);
+
39 
+
40 #endif /* BUTTON_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_chameleon-_mini_8h_source.html b/Doc/Doxygen/html/_chameleon-_mini_8h_source.html new file mode 100644 index 00000000..62f7b362 --- /dev/null +++ b/Doc/Doxygen/html/_chameleon-_mini_8h_source.html @@ -0,0 +1,123 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Chameleon-Mini.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Chameleon-Mini.h
+
+
+
1 #ifndef CHAMELEON_MINI_H
+
2 #define CHAMELEON_MINI_H
+
3 
+
4 #include <avr/io.h>
+
5 #include <avr/wdt.h>
+
6 #include <avr/interrupt.h>
+
7 #include <avr/power.h>
+
8 
+
9 #include "System.h"
+
10 #include "Memory.h"
+
11 #include "LED.h"
+
12 #include "Terminal/Terminal.h"
+
13 #include "Codec/Codec.h"
+
14 #include "Application/Application.h"
+
15 #include "Configuration.h"
+
16 #include "Random.h"
+
17 #include "Button.h"
+
18 #include "AntennaLevel.h"
+
19 #include "Settings.h"
+
20 
+
21 #define CHAMELEON_MINI_VERSION_STRING BUILD_DATE
+
22 
+
23 #endif //CHAMELEON_MINI_H
+
24 
+
+ + + + diff --git a/Doc/Doxygen/html/_codec_8h_source.html b/Doc/Doxygen/html/_codec_8h_source.html new file mode 100644 index 00000000..26e904e5 --- /dev/null +++ b/Doc/Doxygen/html/_codec_8h_source.html @@ -0,0 +1,173 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Codec/Codec.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Codec.h
+
+
+
1 /*
+
2  * CODEC.h
+
3  *
+
4  * Created on: 18.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef CODEC_H_
+
9 #define CODEC_H_
+
10 
+
11 #include <avr/io.h>
+
12 #include <stdint.h>
+
13 #include <stdbool.h>
+
14 #include "../Common.h"
+
15 #include "../Configuration.h"
+
16 
+
17 #include "ISO14443-2A.h"
+
18 
+
19 #define CODEC_DEMOD_POWER_PORT PORTB
+
20 #define CODEC_DEMOD_POWER_MASK PIN1_bm
+
21 #define CODEC_DEMOD_IN_PORT PORTB
+
22 #define CODEC_DEMOD_IN_MASK (CODEC_DEMOD_IN_MASK0 | CODEC_DEMOD_IN_MASK1)
+
23 #define CODEC_DEMOD_IN_MASK0 PIN0_bm
+
24 #define CODEC_DEMOD_IN_MASK1 PIN2_bm
+
25 #define CODEC_DEMOD_IN_PINCTRL0 PIN0CTRL
+
26 #define CODEC_DEMOD_IN_PINCTRL1 PIN2CTRL
+
27 #define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN0_gc
+
28 #define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc
+
29 #define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect
+
30 #define CODEC_LOADMOD_PORT PORTC
+
31 #define CODEC_LOADMOD_MASK PIN6_bm
+
32 #define CODEC_CARRIER_IN_PORT PORTC
+
33 #define CODEC_CARRIER_IN_MASK PIN2_bm
+
34 #define CODEC_CARRIER_IN_PINCTRL PIN2CTRL
+
35 #define CODEC_CARRIER_IN_EVMUX EVSYS_CHMUX_PORTC_PIN2_gc
+
36 #define CODEC_SUBCARRIER_PORT PORTC
+
37 #define CODEC_SUBCARRIER_MASK_PSK PIN0_bm
+
38 #define CODEC_SUBCARRIER_MASK_OOK PIN1_bm
+
39 #define CODEC_SUBCARRIER_MASK (CODEC_SUBCARRIER_MASK_PSK | CODEC_SUBCARRIER_MASK_OOK)
+
40 #define CODEC_SUBCARRIER_TIMER TCC0
+
41 #define CODEC_SUBCARRIER_CC_PSK CCA
+
42 #define CODEC_SUBCARRIER_CC_OOK CCB
+
43 #define CODEC_SUBCARRIER_CCEN_PSK TC0_CCAEN_bm
+
44 #define CODEC_SUBCARRIER_CCEN_OOK TC0_CCBEN_bm
+
45 #define CODEC_TIMER_SAMPLING TCC1
+
46 #define CODEC_TIMER_SAMPLING_CCA_VECT TCC1_CCA_vect
+
47 #define CODEC_TIMER_LOADMOD TCD1
+
48 #define CODEC_TIMER_OVF_VECT TCD1_OVF_vect
+
49 
+
50 #define CODEC_BUFFER_SIZE 256 /* Byte */
+
51 
+
52 #define CODEC_CARRIER_FREQ 13560000
+
53 
+
54 extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
+
55 
+
56 INLINE void CodecInit(void) {
+
57  ActiveConfiguration.CodecInitFunc();
+
58 }
+
59 
+
60 INLINE void CodecTask(void) {
+
61  ActiveConfiguration.CodecTaskFunc();
+
62 }
+
63 
+
64 INLINE void CodecSetDemodPower(bool bOnOff) {
+
65  CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK;
+
66 
+
67  if (bOnOff) {
+
68  CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK;
+
69  } else {
+
70  CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK;
+
71  }
+
72 }
+
73 
+
74 #endif /* CODEC_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_command_line_8h_source.html b/Doc/Doxygen/html/_command_line_8h_source.html new file mode 100644 index 00000000..b8acd755 --- /dev/null +++ b/Doc/Doxygen/html/_command_line_8h_source.html @@ -0,0 +1,117 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Terminal/CommandLine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
CommandLine.h
+
+
+
1 /*
+
2  * CommandLine.h
+
3  *
+
4  * Created on: 04.05.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef COMMANDLINE_H_
+
9 #define COMMANDLINE_H_
+
10 
+
11 #include "Terminal.h"
+
12 
+
13 void CommandLineInit(void);
+
14 bool CommandLineProcessByte(uint8_t Byte);
+
15 void CommandLineTick(void);
+
16 
+
17 
+
18 #endif /* COMMANDLINE_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_command_line_8txt.html b/Doc/Doxygen/html/_command_line_8txt.html new file mode 100644 index 00000000..60cbc25d --- /dev/null +++ b/Doc/Doxygen/html/_command_line_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/CommandLine.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/CommandLine.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_commands_8h_source.html b/Doc/Doxygen/html/_commands_8h_source.html new file mode 100644 index 00000000..55254c9a --- /dev/null +++ b/Doc/Doxygen/html/_commands_8h_source.html @@ -0,0 +1,200 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Terminal/Commands.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Commands.h
+
+
+
1 
+
2 
+
3 #ifndef COMMANDS_H_
+
4 #define COMMANDS_H_
+
5 
+
6 #include "../Common.h"
+
7 
+
8 #define MAX_COMMAND_LENGTH 16
+
9 #define MAX_STATUS_LENGTH 32
+
10 
+
11 
+
12 #define COMMAND_INFO_OK_ID 100
+
13 #define COMMAND_INFO_OK "OK"
+
14 #define COMMAND_INFO_OK_WITH_TEXT_ID 101
+
15 #define COMMAND_INFO_OK_WITH_TEXT "OK WITH TEXT"
+
16 #define COMMAND_INFO_XMODEM_WAIT_ID 110
+
17 #define COMMAND_INFO_XMODEM_WAIT "WAITING FOR XMODEM"
+
18 #define COMMAND_ERR_UNKNOWN_CMD_ID 200
+
19 #define COMMAND_ERR_UNKNOWN_CMD "UNKNOWN COMMAND"
+
20 #define COMMAND_ERR_INVALID_USAGE_ID 201
+
21 #define COMMAND_ERR_INVALID_USAGE "INVALID COMMAND USAGE"
+
22 #define COMMAND_ERR_INVALID_PARAM_ID 202
+
23 #define COMMAND_ERR_INVALID_PARAM "INVALID PARAMETER"
+
24 
+
25 
+
26 #define COMMAND_CHAR_TRUE '1'
+
27 #define COMMAND_CHAR_FALSE '0'
+
28 
+
29 #define COMMAND_UID_BUFSIZE 32
+
30 
+
31 typedef uint8_t CommandStatusIdType;
+
32 typedef const char CommandStatusMessageType[MAX_STATUS_LENGTH];
+
33 
+
34 typedef CommandStatusIdType (*CommandExecFuncType) (char* OutMessage);
+
35 typedef CommandStatusIdType (*CommandSetFuncType) (const char* InParam);
+
36 typedef CommandStatusIdType (*CommandGetFuncType) (char* OutParam);
+
37 
+
38 typedef struct {
+
39  char Command[MAX_COMMAND_LENGTH];
+
40  CommandExecFuncType ExecFunc;
+
41  CommandSetFuncType SetFunc;
+
42  CommandGetFuncType GetFunc;
+
43 } CommandEntryType;
+
44 
+
45 #define COMMAND_VERSION "VERSION"
+
46 CommandStatusIdType CommandGetVersion(char* OutParam);
+
47 
+
48 #define COMMAND_CONFIG "CONFIG"
+
49 CommandStatusIdType CommandExecConfig(char* OutMessage);
+
50 CommandStatusIdType CommandGetConfig(char* OutParam);
+
51 CommandStatusIdType CommandSetConfig(const char* InParam);
+
52 
+
53 #define COMMAND_UID "UID"
+
54 #define COMMAND_UID_RANDOM "RANDOM"
+
55 CommandStatusIdType CommandGetUid(char* OutParam);
+
56 CommandStatusIdType CommandSetUid(const char* InParam);
+
57 
+
58 #define COMMAND_READONLY "READONLY"
+
59 CommandStatusIdType CommandGetReadOnly(char* OutParam);
+
60 CommandStatusIdType CommandSetReadOnly(const char* InParam);
+
61 
+
62 #define COMMAND_UPLOAD "UPLOAD"
+
63 CommandStatusIdType CommandExecUpload(char* OutMessage);
+
64 
+
65 #define COMMAND_DOWNLOAD "DOWNLOAD"
+
66 CommandStatusIdType CommandExecDownload(char* OutMessage);
+
67 
+
68 #define COMMAND_RESET "RESET"
+
69 CommandStatusIdType CommandExecReset(char* OutMessage);
+
70 
+
71 #define COMMAND_UPGRADE "UPGRADE"
+
72 CommandStatusIdType CommandExecUpgrade(char* OutMessage);
+
73 
+
74 #define COMMAND_MEMSIZE "MEMSIZE"
+
75 CommandStatusIdType CommandGetMemSize(char* OutParam);
+
76 
+
77 #define COMMAND_UIDSIZE "UIDSIZE"
+
78 CommandStatusIdType CommandGetUidSize(char* OutParam);
+
79 
+
80 #define COMMAND_BUTTON "BUTTON"
+
81 CommandStatusIdType CommandExecButton(char* OutMessage);
+
82 CommandStatusIdType CommandGetButton(char* OutParam);
+
83 CommandStatusIdType CommandSetButton(const char* InParam);
+
84 
+
85 #define COMMAND_SETTING "SETTING"
+
86 CommandStatusIdType CommandGetSetting(char* OutParam);
+
87 CommandStatusIdType CommandSetSetting(const char* InParam);
+
88 
+
89 #define COMMAND_CLEAR "CLEAR"
+
90 CommandStatusIdType CommandExecClear(char* OutParam);
+
91 
+
92 #define COMMAND_HELP "HELP"
+
93 CommandStatusIdType CommandExecHelp(char* OutMessage);
+
94 
+
95 #define COMMAND_RSSI "RSSI"
+
96 CommandStatusIdType CommandGetRssi(char* OutParam);
+
97 
+
98 #define COMMAND_LIST_END ""
+
99 /* Defines the end of command list. This is no actual command */
+
100 
+
101 #endif /* COMMANDS_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_common_8h_source.html b/Doc/Doxygen/html/_common_8h_source.html new file mode 100644 index 00000000..99560e0b --- /dev/null +++ b/Doc/Doxygen/html/_common_8h_source.html @@ -0,0 +1,132 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Common.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Common.h
+
+
+
1 /*
+
2  * Common.h
+
3  *
+
4  * Created on: 20.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef COMMON_H_
+
9 #define COMMON_H_
+
10 
+
11 #include <stdio.h>
+
12 #include <stdbool.h>
+
13 #include <util/parity.h>
+
14 #include <util/delay.h>
+
15 #include <avr/pgmspace.h>
+
16 
+
17 #define ODD_PARITY(Value) (parity_even_bit(Value) ? 0 : 1)
+
18 
+
19 #define INLINE \
+
20  static inline __attribute__((always_inline))
+
21 
+
22 #define NIBBLE_TO_HEXCHAR(x) ( (x) < 0x0A ? (x) + '0' : (x) + 'A' - 0x0A )
+
23 #define HEXCHAR_TO_NIBBLE(x) ( (x) < 'A' ? (x) - '0' : (x) - 'A' + 0x0A )
+
24 #define VALID_HEXCHAR(x) ( ( (x) >= '0' && (x) <= '9' ) || ( (x) >= 'A' && (x) <= 'F' ) )
+
25 #define MIN(x,y) ( (x) < (y) ? (x) : (y) )
+
26 #define MAX(x,y) ( (x) > (y) ? (x) : (y) )
+
27 
+
28 #define BITS_PER_BYTE 8
+
29 
+
30 uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount);
+
31 uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn);
+
32 
+
33 #endif /* COMMON_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_configuration_8h_source.html b/Doc/Doxygen/html/_configuration_8h_source.html new file mode 100644 index 00000000..99e23fb4 --- /dev/null +++ b/Doc/Doxygen/html/_configuration_8h_source.html @@ -0,0 +1,178 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Configuration.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Configuration.h
+
+
+
1 /*
+
2  * Standards.h
+
3  *
+
4  * Created on: 15.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef STANDARDS_H_
+
9 #define STANDARDS_H_
+
10 
+
11 #include <stdint.h>
+
12 #include <stdbool.h>
+
13 
+
14 #define CONFIGURATION_NAME_LENGTH_MAX 16
+
15 #define CONFIGURATION_UID_SIZE_MAX 16
+
16 
+
17 typedef uint8_t ConfigurationUidType[CONFIGURATION_UID_SIZE_MAX];
+
18 
+
19 typedef enum {
+
20  /* This HAS to be the first element */
+
21  CONFIG_NONE = 0,
+
22 
+
23 #ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+
24  CONFIG_MF_ULTRALIGHT,
+
25 #endif
+
26 #ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+
27  CONFIG_MF_CLASSIC_1K,
+
28 #endif
+
29 #ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
+
30  CONFIG_MF_CLASSIC_4K,
+
31 #endif
+
32 #ifdef CONFIG_ISO15693_GEN_SUPPORT
+
33  CONFIG_ISO15693_GEN,
+
34 #endif
+
35 #ifdef CONFIG_ISO14443A_SNIFF_SUPPORT
+
36  CONFIG_ISO14443A_SNIFF,
+
37 #endif
+
38 #ifdef CONFIG_ISO15693_SNIFF_SUPPORT
+
39  CONFIG_ISO15693_SNIFF,
+
40 #endif
+
41  //CONFIG_MF_DESFIRE,
+
42  //CONFIG_ISO14443A_RELAY
+
43 
+
44 
+
45 
+
46  /* This HAS to be the last element */
+
47  CONFIG_COUNT
+
48 } ConfigurationEnum;
+
49 
+
50 typedef struct {
+
51  ConfigurationEnum ConfigurationID;
+
52  char ConfigurationName[CONFIGURATION_NAME_LENGTH_MAX];
+
53 
+
54  /* Codec used for this configuration */
+
55  void (*CodecInitFunc) (void);
+
56  void (*CodecTaskFunc) (void);
+
57 
+
58  /* Application used for this configuration */
+
59  void (*ApplicationInitFunc) (void);
+
60  void (*ApplicationResetFunc) (void);
+
61  void (*ApplicationTaskFunc) (void);
+
62  uint16_t (*ApplicationProcessFunc) (uint8_t* ByteBuffer, uint16_t ByteCount);
+
63  void (*ApplicationGetUidFunc) (ConfigurationUidType Uid);
+
64  void (*ApplicationSetUidFunc) (ConfigurationUidType Uid);
+
65 
+
66  uint16_t MemorySize;
+
67  uint8_t UidSize;
+
68  bool ReadOnly;
+
69 
+
70 } ConfigurationType;
+
71 
+
72 extern ConfigurationType ActiveConfiguration;
+
73 
+
74 void ConfigurationInit(void);
+
75 void ConfigurationSetById(ConfigurationEnum Configuration);
+
76 bool ConfigurationSetByName(const char* ConfigurationName);
+
77 void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount);
+
78 
+
79 #endif /* STANDARDS_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_configurations_8txt.html b/Doc/Doxygen/html/_configurations_8txt.html new file mode 100644 index 00000000..61a6985b --- /dev/null +++ b/Doc/Doxygen/html/_configurations_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/Configurations.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/Configurations.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_crypto1_8h_source.html b/Doc/Doxygen/html/_crypto1_8h_source.html new file mode 100644 index 00000000..dad32700 --- /dev/null +++ b/Doc/Doxygen/html/_crypto1_8h_source.html @@ -0,0 +1,124 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Application/Crypto1.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Crypto1.h
+
+
+
1 #ifndef CRYPTO1_H
+
2 #define CRYPTO1_H
+
3 
+
4 #include <stdint.h>
+
5 
+
6 /* Gets the current keystream-bit, without shifting the internal LFSR */
+
7 uint8_t Crypto1FilterOutput(void);
+
8 
+
9 /* Set up Crypto1 cipher using the given Key, Uid and CardNonce. Also encrypts
+
10  * the CardNonce in-place while in non-linear mode. */
+
11 void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]);
+
12 
+
13 /* Load the decrypted ReaderNonce into the Crypto1 state LFSR */
+
14 void Crypto1Auth(uint8_t EncryptedReaderNonce[4]);
+
15 
+
16 /* Generate 8 Bits of key stream */
+
17 uint8_t Crypto1Byte(void);
+
18 
+
19 /* Generate 4 Bits of key stream */
+
20 uint8_t Crypto1Nibble(void);
+
21 
+
22 /* Execute 'ClockCount' cycles on the PRNG state 'State' */
+
23 void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount);
+
24 
+
25 #endif //CRYPTO1_H
+
+ + + + diff --git a/Doc/Doxygen/html/_d_e_s_fire_8h_source.html b/Doc/Doxygen/html/_d_e_s_fire_8h_source.html new file mode 100644 index 00000000..b28ccecb --- /dev/null +++ b/Doc/Doxygen/html/_d_e_s_fire_8h_source.html @@ -0,0 +1,131 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Application/DESFire.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
DESFire.h
+
+
+
1 /*
+
2  * DESFire.h
+
3  *
+
4  * Created on: 03.06.2013
+
5  * Changed on: 06.06.2013
+
6  * Author: lmeier
+
7  */
+
8 
+
9 #ifndef DESFIRE_H_
+
10 #define DESFIRE_H_
+
11 
+
12 #include "Application.h"
+
13 #include "ISO14443AUtil.h"
+
14 
+
15 #define DESFIRE_UID_SIZE ISO14443A_UID_SIZE_DOUBLE //7 Byte
+
16 
+
17 void DESFireInit(void);
+
18 void DESFireReset(void);
+
19 
+
20 
+
21 uint16_t DESFireProcess(uint8_t* Buffer, uint16_t BitCount);
+
22 
+
23 boolean isValidKey(uint8_t keyNo);
+
24 void setAuthState(uint8_t aid, boolean value);
+
25 
+
26 /*
+
27  void DESFireTask(void);
+
28 void DESFireGetUid(ConfigurationUidType Uid);
+
29 void DESFireSetUid(ConfigurationUidType Uid);*/
+
30 
+
31 
+
32 #endif /* DESFIRE_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_d_f_u_8txt.html b/Doc/Doxygen/html/_d_f_u_8txt.html new file mode 100644 index 00000000..5731c3f2 --- /dev/null +++ b/Doc/Doxygen/html/_d_f_u_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/DFU.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/DFU.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_getting_started_8txt.html b/Doc/Doxygen/html/_getting_started_8txt.html new file mode 100644 index 00000000..1ae7fa83 --- /dev/null +++ b/Doc/Doxygen/html/_getting_started_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/GettingStarted.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/GettingStarted.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o14443-2_a_8h_source.html b/Doc/Doxygen/html/_i_s_o14443-2_a_8h_source.html new file mode 100644 index 00000000..38174f24 --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o14443-2_a_8h_source.html @@ -0,0 +1,123 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO14443-2A.h
+
+
+
1 /*
+
2  * ISO14443-2A.h
+
3  *
+
4  * Created on: 18.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO14443_2A_H_
+
9 #define ISO14443_2A_H_
+
10 
+
11 #include "Codec.h"
+
12 
+
13 #define ISO14443A_APP_NO_RESPONSE 0x0000
+
14 #define ISO14443A_APP_CUSTOM_PARITY 0x1000
+
15 
+
16 #define ISO14443A_BUFFER_PARITY_OFFSET (CODEC_BUFFER_SIZE/2)
+
17 
+
18 /* Codec Interface */
+
19 void ISO14443ACodecInit(void);
+
20 void ISO14443ACodecTask(void);
+
21 
+
22 
+
23 
+
24 #endif
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o14443-3_a_8h_source.html b/Doc/Doxygen/html/_i_s_o14443-3_a_8h_source.html new file mode 100644 index 00000000..f06bfa6f --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o14443-3_a_8h_source.html @@ -0,0 +1,216 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Application/ISO14443-3A.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO14443-3A.h
+
+
+
1 /*
+
2  * ISO14443-2A.h
+
3  *
+
4  * Created on: 19.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO14443_3A_H_
+
9 #define ISO14443_3A_H_
+
10 
+
11 #include "../Common.h"
+
12 
+
13 #define ISO14443A_UID_SIZE_SINGLE 4 /* bytes */
+
14 #define ISO14443A_UID_SIZE_DOUBLE 7
+
15 #define ISO14443A_UID_SIZE_TRIPLE 10
+
16 
+
17 #define ISO14443A_CMD_REQA 0x26
+
18 #define ISO14443A_CMD_WUPA 0x52
+
19 #define ISO14443A_CMD_SELECT_CL1 0x93
+
20 #define ISO14443A_CMD_SELECT_CL2 0x95
+
21 #define ISO14443A_CMD_SELECT_CL3 0x97
+
22 #define ISO14443A_CMD_HLTA 0x50
+
23 
+
24 #define ISO14443A_NVB_AC_START 0x20
+
25 #define ISO14443A_NVB_AC_END 0x70
+
26 
+
27 #define ISO14443A_CL_UID_OFFSET 0
+
28 #define ISO14443A_CL_UID_SIZE 4
+
29 #define ISO14443A_CL_BCC_OFFSET 4
+
30 #define ISO14443A_CL_BCC_SIZE 1 /* Byte */
+
31 #define ISO14443A_CL_FRAME_SIZE ((ISO14443A_CL_UID_SIZE + ISO14443A_CL_BCC_SIZE) * 8) /* UID[N...N+3] || BCCN */
+
32 #define ISO14443A_SAK_INCOMPLETE 0x04
+
33 #define ISO14443A_SAK_COMPLETE_COMPLIANT 0x20
+
34 #define ISO14443A_SAK_COMPLETE_NOT_COMPLIANT 0x00
+
35 
+
36 #define ISO14443A_ATQA_FRAME_SIZE (2 * 8) /* Bit */
+
37 #define ISO14443A_SAK_FRAME_SIZE (3 * 8) /* Bit */
+
38 
+
39 #define ISO14443A_UID0_RANDOM 0x08
+
40 #define ISO14443A_UID0_CT 0x88
+
41 
+
42 #define ISO14443A_CRCA_SIZE 2
+
43 
+
44 #define ISO14443A_CALC_BCC(ByteBuffer) \
+
45  ( ByteBuffer[0] ^ ByteBuffer[1] ^ ByteBuffer[2] ^ ByteBuffer[3] )
+
46 
+
47 void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount);
+
48 bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount);
+
49 
+
50 INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue);
+
51 INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue);
+
52 
+
53 INLINE
+
54 bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
+
55 {
+
56  uint8_t* DataPtr = (uint8_t*) Buffer;
+
57  uint8_t NVB = DataPtr[1];
+
58  //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
+
59  //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
+
60 
+
61  switch (NVB) {
+
62  case ISO14443A_NVB_AC_START:
+
63  /* Start of anticollision procedure.
+
64  * Send whole UID CLn + BCC */
+
65  DataPtr[0] = UidCL[0];
+
66  DataPtr[1] = UidCL[1];
+
67  DataPtr[2] = UidCL[2];
+
68  DataPtr[3] = UidCL[3];
+
69  DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
+
70 
+
71  *BitCount = ISO14443A_CL_FRAME_SIZE;
+
72 
+
73  return false;
+
74 
+
75  case ISO14443A_NVB_AC_END:
+
76  /* End of anticollision procedure.
+
77  * Send SAK CLn if we are selected. */
+
78  if ( (DataPtr[2] == UidCL[0]) &&
+
79  (DataPtr[3] == UidCL[1]) &&
+
80  (DataPtr[4] == UidCL[2]) &&
+
81  (DataPtr[5] == UidCL[3]) ) {
+
82 
+
83  DataPtr[0] = SAKValue;
+
84  ISO14443AAppendCRCA(Buffer, 1);
+
85 
+
86  *BitCount = ISO14443A_SAK_FRAME_SIZE;
+
87  return true;
+
88  } else {
+
89  /* We have not been selected. Don't send anything. */
+
90  *BitCount = 0;
+
91  return false;
+
92  }
+
93  default:
+
94  /* TODO: No anticollision supported */
+
95  *BitCount = 0;
+
96  return false;
+
97  }
+
98 }
+
99 
+
100 INLINE
+
101 bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue)
+
102 {
+
103  uint8_t* DataPtr = (uint8_t*) Buffer;
+
104 
+
105  if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){
+
106  DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
+
107  DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
+
108 
+
109  *BitCount = ISO14443A_ATQA_FRAME_SIZE;
+
110 
+
111  return true;
+
112  } else {
+
113  return false;
+
114  }
+
115 }
+
116 
+
117 #endif
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o14443-3_a_inline_8h_source.html b/Doc/Doxygen/html/_i_s_o14443-3_a_inline_8h_source.html new file mode 100644 index 00000000..b442b8f0 --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o14443-3_a_inline_8h_source.html @@ -0,0 +1,175 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/Firmware/Chameleon-Mini/Application/ISO14443-3AInline.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO14443-3AInline.h
+
+
+
1 /*
+
2  * ISO14443AUtilInline.h
+
3  *
+
4  * Created on: 11.06.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO14443_3AINLINE_H_
+
9 #define ISO14443_3AINLINE_H_
+
10 
+
11 
+
12 INLINE
+
13 bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
+
14 {
+
15  uint8_t* DataPtr = (uint8_t*) Buffer;
+
16  uint8_t NVB = DataPtr[1];
+
17  //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
+
18  //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
+
19 
+
20  switch (NVB) {
+
21  case ISO14443A_NVB_AC_START:
+
22  /* Start of anticollision procedure.
+
23  * Send whole UID CLn + BCC */
+
24  DataPtr[0] = UidCL[0];
+
25  DataPtr[1] = UidCL[1];
+
26  DataPtr[2] = UidCL[2];
+
27  DataPtr[3] = UidCL[3];
+
28  DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
+
29 
+
30  *BitCount = ISO14443A_CL_FRAME_SIZE;
+
31 
+
32  return false;
+
33 
+
34  case ISO14443A_NVB_AC_END:
+
35  /* End of anticollision procedure.
+
36  * Send SAK CLn if we are selected. */
+
37  if ( (DataPtr[2] == UidCL[0]) &&
+
38  (DataPtr[3] == UidCL[1]) &&
+
39  (DataPtr[4] == UidCL[2]) &&
+
40  (DataPtr[5] == UidCL[3]) ) {
+
41 
+
42  DataPtr[0] = SAKValue;
+
43  ISO14443AAppendCRCA(Buffer, 1);
+
44 
+
45  *BitCount = ISO14443A_SAK_FRAME_SIZE;
+
46  return true;
+
47  } else {
+
48  /* We have not been selected. Don't send anything. */
+
49  *BitCount = 0;
+
50  return false;
+
51  }
+
52  default:
+
53  /* TODO: No anticollision supported */
+
54  *BitCount = 0;
+
55  return false;
+
56  }
+
57 }
+
58 
+
59 INLINE
+
60 bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue)
+
61 {
+
62  uint8_t* DataPtr = (uint8_t*) Buffer;
+
63 
+
64  if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){
+
65  DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
+
66  DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
+
67 
+
68  *BitCount = ISO14443A_ATQA_FRAME_SIZE;
+
69 
+
70  return true;
+
71  } else {
+
72  return false;
+
73  }
+
74 }
+
75 
+
76 #endif
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o15693-2_8h_source.html b/Doc/Doxygen/html/_i_s_o15693-2_8h_source.html new file mode 100644 index 00000000..14552e26 --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o15693-2_8h_source.html @@ -0,0 +1,120 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Codec/ISO15693-2.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO15693-2.h
+
+
+
1 /*
+
2  * ISO15693-2.h
+
3  *
+
4  * Created on: 21.08.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO15693_2_H_
+
9 #define ISO15693_2_H_
+
10 
+
11 #include "Codec.h"
+
12 
+
13 #define ISO15693_APP_NO_RESPONSE 0x0000
+
14 
+
15 
+
16 /* Codec Interface */
+
17 void ISO15693CodecInit(void);
+
18 void ISO15693CodecTask(void);
+
19 
+
20 
+
21 #endif /* ISO15693_2_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o15693-3_8h_source.html b/Doc/Doxygen/html/_i_s_o15693-3_8h_source.html new file mode 100644 index 00000000..9f109e4f --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o15693-3_8h_source.html @@ -0,0 +1,198 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Application/ISO15693-3.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO15693-3.h
+
+
+
1 /*
+
2  * ISO15693-3.h
+
3  *
+
4  * Created on: 24.08.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO15693_3_H_
+
9 #define ISO15693_3_H_
+
10 
+
11 #include "../Common.h"
+
12 
+
13 #define ISO15693_CMD_INVENTORY 0x01
+
14 #define ISO15693_CMD_STAY_QUIET 0x02
+
15 #define ISO15693_CMD_READ_SINGLE 0x20
+
16 #define ISO15693_CMD_WRITE_SINGLE 0x21
+
17 #define ISO15693_CMD_LOCK_BLOCK 0x22
+
18 #define ISO15693_CMD_READ_MULTIPLE 0x23
+
19 #define ISO15693_CMD_WRITE_MULTIPLE 0x24
+
20 #define ISO15693_CMD_SELECT 0x25
+
21 #define ISO15693_CMD_RESET_TO_READY 0x26
+
22 #define ISO15693_CMD_WRITE_AFI 0x27
+
23 #define ISO15693_CMD_LOCK_AFI 0x28
+
24 #define ISO15693_CMD_WRITE_DSFID 0x29
+
25 #define ISO15693_CMD_LOCK_DSFID 0x2A
+
26 #define ISO15693_CMD_GET_SYS_INFO 0x2B
+
27 #define ISO15693_CMD_GET_BLOCK_SEC 0x2C
+
28 
+
29 #define ISO15693_REQ_FLAG_SUBCARRIER 0x01
+
30 #define ISO15693_REQ_FLAG_DATARATE 0x02
+
31 #define ISO15693_REQ_FLAG_INVENTORY 0x04
+
32 #define ISO15693_REQ_FLAG_PROT_EXT 0x08
+
33 #define ISO15693_REQ_FLAG_OPTION 0x40
+
34 #define ISO15693_REQ_FLAG_RFU 0x80
+
35 /* When INVENTORY flag is not set: */
+
36 #define ISO15693_REQ_FLAG_SELECT 0x10
+
37 #define ISO15693_REQ_FLAG_ADDRESS 0x20
+
38 /* When INVENTORY flag is set: */
+
39 #define ISO15693_REQ_FLAG_AFI 0x10
+
40 #define ISO15693_REQ_FLAG_NB_SLOTS 0x20
+
41 
+
42 #define ISO15693_RES_FLAG_ERROR 0x01
+
43 #define ISO15693_RES_FLAG_PROT_EXT 0x08
+
44 
+
45 #define ISO15693_CRC_SIZE 2 /* Byte */
+
46 
+
47 typedef uint8_t ISO15693UidType[8];
+
48 
+
49 void ISO15693AppendCRC(void* Buffer, uint16_t ByteCount);
+
50 bool ISO15693CheckCRC(void* Buffer, uint16_t ByteCount);
+
51 
+
52 INLINE
+
53 bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2)
+
54 {
+
55  if ( (Uid1[0] == Uid2[0])
+
56  && (Uid1[1] == Uid2[1])
+
57  && (Uid1[2] == Uid2[2])
+
58  && (Uid1[3] == Uid2[3])
+
59  && (Uid1[4] == Uid2[4])
+
60  && (Uid1[5] == Uid2[5])
+
61  && (Uid1[6] == Uid2[6])
+
62  && (Uid1[7] == Uid2[7]) ) {
+
63  return true;
+
64  } else {
+
65  return false;
+
66  }
+
67 }
+
68 
+
69 INLINE
+
70 void ISO15693CopyUid(uint8_t* DstUid, uint8_t* SrcUid)
+
71 {
+
72  DstUid[0] = SrcUid[0];
+
73  DstUid[1] = SrcUid[1];
+
74  DstUid[2] = SrcUid[2];
+
75  DstUid[3] = SrcUid[3];
+
76  DstUid[4] = SrcUid[4];
+
77  DstUid[5] = SrcUid[5];
+
78  DstUid[6] = SrcUid[6];
+
79  DstUid[7] = SrcUid[7];
+
80 }
+
81 
+
82 INLINE
+
83 bool ISO15693Addressed(uint8_t* Buffer, uint8_t* MyUid) {
+
84  if (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS) {
+
85  /* Addressed mode */
+
86  if ( ISO15693CompareUid(&Buffer[2], MyUid) ) {
+
87  /* Our UID addressed */
+
88  return true;
+
89  } else {
+
90  /* Our UID not addressed */
+
91  return false;
+
92  }
+
93  } else {
+
94  /* Non-Addressed mode */
+
95  return true;
+
96  }
+
97 }
+
98 
+
99 #endif /* ISO15693_3_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_i_s_o15693_generic_8h_source.html b/Doc/Doxygen/html/_i_s_o15693_generic_8h_source.html new file mode 100644 index 00000000..c3487e53 --- /dev/null +++ b/Doc/Doxygen/html/_i_s_o15693_generic_8h_source.html @@ -0,0 +1,123 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Application/ISO15693Generic.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
ISO15693Generic.h
+
+
+
1 /*
+
2  * ISO15693Generic.h
+
3  *
+
4  * Created on: 21.08.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef ISO15693GENERIC_H_
+
9 #define ISO15693GENERIC_H_
+
10 
+
11 #include "Application.h"
+
12 //#include "ISO15693-3.h"
+
13 
+
14 #define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE
+
15 #define ISO15693_GENERIC_MEM_SIZE 8192 //ISO15693_MAX_MEM_SIZE
+
16 
+
17 void ISO15693GenericAppInit(void);
+
18 void ISO15693GenericAppReset(void);
+
19 void ISO15693GenericAppTask(void);
+
20 
+
21 uint16_t ISO15693GenericAppProcess(uint8_t* Buffer, uint16_t ByteCount);
+
22 
+
23 
+
24 #endif /* ISO15693GENERIC_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_l_e_d_8h_source.html b/Doc/Doxygen/html/_l_e_d_8h_source.html new file mode 100644 index 00000000..769124a7 --- /dev/null +++ b/Doc/Doxygen/html/_l_e_d_8h_source.html @@ -0,0 +1,151 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LED.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
LED.h
+
+
+
1 /*
+
2  * LED.h
+
3  *
+
4  * Created on: 10.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef LED_H
+
9 #define LED_H
+
10 
+
11 #include <avr/io.h>
+
12 
+
13 #define LED_PORT PORTA
+
14 #define LED_GREEN PIN5_bm
+
15 #define LED_RED PIN4_bm
+
16 #define LED_MASK (LED_GREEN | LED_RED)
+
17 
+
18 extern uint8_t LEDPulseMask;
+
19 
+
20 static inline
+
21 void LEDInit(void) {
+
22  LED_PORT.DIRSET = LED_MASK;
+
23 }
+
24 
+
25 static inline
+
26 void LEDSetOn(uint8_t Mask) {
+
27  LED_PORT.OUTSET = Mask;
+
28 }
+
29 
+
30 static inline
+
31 void LEDSetOff(uint8_t Mask) {
+
32  LED_PORT.OUTCLR = Mask;
+
33 }
+
34 
+
35 static inline
+
36 void LEDToggle(uint8_t Mask) {
+
37  LED_PORT.OUTTGL = Mask;
+
38 }
+
39 
+
40 static inline
+
41 void LEDPulse(uint8_t Mask) {
+
42  LEDPulseMask = Mask;
+
43  LED_PORT.OUTSET = Mask;
+
44 }
+
45 
+
46 static inline
+
47 void LEDTick(void) {
+
48  LED_PORT.OUTCLR = LEDPulseMask;
+
49  LEDPulseMask = 0;
+
50 }
+
51 
+
52 #endif /* LED_H */
+
+ + + + diff --git a/Doc/Doxygen/html/_l_u_f_a_config_8h.html b/Doc/Doxygen/html/_l_u_f_a_config_8h.html new file mode 100644 index 00000000..fe342bca --- /dev/null +++ b/Doc/Doxygen/html/_l_u_f_a_config_8h.html @@ -0,0 +1,108 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFAConfig.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
LUFAConfig.h File Reference
+
+
+ +

LUFA Library Configuration Header File. +More...

+ +

Go to the source code of this file.

+

Detailed Description

+

LUFA Library Configuration Header File.

+

This header file is used to configure LUFA's compile time options, as an alternative to the compile time constants supplied through a makefile.

+

For information on what each token does, refer to the LUFA manual section "Summary of Compile Tokens".

+
+ + + + diff --git a/Doc/Doxygen/html/_l_u_f_a_config_8h_source.html b/Doc/Doxygen/html/_l_u_f_a_config_8h_source.html new file mode 100644 index 00000000..9c135646 --- /dev/null +++ b/Doc/Doxygen/html/_l_u_f_a_config_8h_source.html @@ -0,0 +1,166 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFAConfig.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
LUFAConfig.h
+
+
+Go to the documentation of this file.
1 /*
+
2  LUFA Library
+
3  Copyright (C) Dean Camera, 2012.
+
4 
+
5  dean [at] fourwalledcubicle [dot] com
+
6  www.lufa-lib.org
+
7 */
+
8 
+
9 /*
+
10  Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
11 
+
12  Permission to use, copy, modify, distribute, and sell this
+
13  software and its documentation for any purpose is hereby granted
+
14  without fee, provided that the above copyright notice appear in
+
15  all copies and that both that the copyright notice and this
+
16  permission notice and warranty disclaimer appear in supporting
+
17  documentation, and that the name of the author not be used in
+
18  advertising or publicity pertaining to distribution of the
+
19  software without specific, written prior permission.
+
20 
+
21  The author disclaim all warranties with regard to this
+
22  software, including all implied warranties of merchantability
+
23  and fitness. In no event shall the author be liable for any
+
24  special, indirect or consequential damages or any damages
+
25  whatsoever resulting from loss of use, data or profits, whether
+
26  in an action of contract, negligence or other tortious action,
+
27  arising out of or in connection with the use or performance of
+
28  this software.
+
29 */
+
30 
+
42 #ifndef _LUFA_CONFIG_H_
+
43 #define _LUFA_CONFIG_H_
+
44 
+
45  /* Non-USB Related Configuration Tokens: */
+
46 // #define DISABLE_TERMINAL_CODES
+
47 
+
48  /* USB Class Driver Related Tokens: */
+
49 // #define HID_HOST_BOOT_PROTOCOL_ONLY
+
50 // #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
+
51 // #define HID_USAGE_STACK_DEPTH {Insert Value Here}
+
52 // #define HID_MAX_COLLECTIONS {Insert Value Here}
+
53 // #define HID_MAX_REPORTITEMS {Insert Value Here}
+
54 // #define HID_MAX_REPORT_IDS {Insert Value Here}
+
55 // #define NO_CLASS_DRIVER_AUTOFLUSH
+
56 
+
57  /* General USB Driver Related Tokens: */
+
58  #define USE_STATIC_OPTIONS \
+
59  (USB_OPT_BUSEVENT_PRIMED | USB_DEVICE_OPT_FULLSPEED | USB_OPT_PLLCLKSRC /*USB_OPT_RC32MCLKSRC*/)
+
60  #define USB_DEVICE_ONLY
+
61 // #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
+
62 // #define NO_LIMITED_CONTROLLER_CONNECT
+
63 // #define NO_SOF_EVENTS
+
64 
+
65  /* USB Device Mode Driver Related Tokens: */
+
66 // #define USE_RAM_DESCRIPTORS
+
67  #define USE_FLASH_DESCRIPTORS
+
68 // #define USE_EEPROM_DESCRIPTORS
+
69 // #define NO_INTERNAL_SERIAL
+
70  #define FIXED_CONTROL_ENDPOINT_SIZE 8
+
71 // #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
+
72  #define FIXED_NUM_CONFIGURATIONS 1
+
73 // #define CONTROL_ONLY_DEVICE
+
74  #define MAX_ENDPOINT_INDEX 5
+
75 // #define NO_DEVICE_REMOTE_WAKEUP
+
76 // #define NO_DEVICE_SELF_POWER
+
77 
+
78 #endif
+
+ + + + diff --git a/Doc/Doxygen/html/_l_u_f_a_descriptors_8c.html b/Doc/Doxygen/html/_l_u_f_a_descriptors_8c.html new file mode 100644 index 00000000..09475696 --- /dev/null +++ b/Doc/Doxygen/html/_l_u_f_a_descriptors_8c.html @@ -0,0 +1,269 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFADescriptors.c File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
LUFADescriptors.c File Reference
+
+
+
#include "LUFADescriptors.h"
+
+ + + +

+Functions

uint16_t CALLBACK_USB_GetDescriptor (const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress)
 
+ + + + + + + + + + + +

+Variables

const USB_Descriptor_Device_t
+PROGMEM 
DeviceDescriptor
 
const
+USB_Descriptor_Configuration_t
+PROGMEM 
ConfigurationDescriptor
 
const USB_Descriptor_String_t
+PROGMEM 
LanguageString
 
const USB_Descriptor_String_t
+PROGMEM 
ManufacturerString
 
const USB_Descriptor_String_t
+PROGMEM 
ProductString
 
+

Detailed Description

+

USB Device Descriptors, for library use when in USB device mode. Descriptors are special computer-readable structures which the host requests upon device enumeration, to determine the device's capabilities and functions.

+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t CALLBACK_USB_GetDescriptor (const uint16_t wValue,
const uint8_t wIndex,
const void **const DescriptorAddress 
)
+
+

This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" documentation) by the application code so that the address and size of a requested descriptor can be given to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the USB host.

+ +
+
+

Variable Documentation

+ +
+
+ + + + +
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor
+
+

Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage of the device in one of its supported configurations, including information about any device interfaces and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting a configuration so that the host may correctly communicate with the USB device.

+ +
+
+ +
+
+ + + + +
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor
+
+Initial value:
=
+
{
+
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+
.USBSpecification = VERSION_BCD(01.10),
+
.Class = CDC_CSCP_CDCClass,
+
.SubClass = CDC_CSCP_NoSpecificSubclass,
+
.Protocol = CDC_CSCP_NoSpecificProtocol,
+
+
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+
.VendorID = 0x03EB,
+
.ProductID = 0x2044,
+
.ReleaseNumber = VERSION_BCD(00.01),
+
+
.ManufacturerStrIndex = 0x01,
+
.ProductStrIndex = 0x02,
+
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
+
+
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+
}
+

Device descriptor structure. This descriptor, located in FLASH memory, describes the overall device characteristics, including the supported USB version, control endpoint size and the number of device configurations. The descriptor is read out by the USB host when the enumeration process begins.

+ +
+
+ +
+
+ + + + +
const USB_Descriptor_String_t PROGMEM LanguageString
+
+Initial value:
=
+
{
+
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+
.UnicodeString = {LANGUAGE_ID_ENG}
+
}
+

Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate via the language ID table available at USB.org what languages the device supports for its string descriptors.

+ +
+
+ +
+
+ + + + +
const USB_Descriptor_String_t PROGMEM ManufacturerString
+
+Initial value:
=
+
{
+
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+
+
.UnicodeString = L"Dean Camera"
+
}
+

Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device Descriptor.

+ +
+
+ +
+
+ + + + +
const USB_Descriptor_String_t PROGMEM ProductString
+
+Initial value:
=
+
{
+
.Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
+
+
.UnicodeString = L"LUFA CDC Demo"
+
}
+

Product descriptor string. This is a Unicode string containing the product's details in human readable form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device Descriptor.

+ +
+
+
+ + + + diff --git a/Doc/Doxygen/html/_l_u_f_a_descriptors_8h.html b/Doc/Doxygen/html/_l_u_f_a_descriptors_8h.html new file mode 100644 index 00000000..e4167374 --- /dev/null +++ b/Doc/Doxygen/html/_l_u_f_a_descriptors_8h.html @@ -0,0 +1,233 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFADescriptors.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
LUFADescriptors.h File Reference
+
+
+
#include <avr/pgmspace.h>
+#include <LUFA/Drivers/USB/USB.h>
+
+

Go to the source code of this file.

+ + + + +

+Classes

struct  USB_Descriptor_Configuration_t
 
+ + + + + + + + + + + +

+Macros

#define CDC_NOTIFICATION_EPADDR   (ENDPOINT_DIR_IN | 2)
 
#define CDC_TX_EPADDR   (ENDPOINT_DIR_IN | 3)
 
#define CDC_RX_EPADDR   (ENDPOINT_DIR_OUT | 4)
 
#define CDC_NOTIFICATION_EPSIZE   8
 
#define CDC_TXRX_EPSIZE   16
 
+ + + +

+Functions

uint16_t CALLBACK_USB_GetDescriptor (const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3)
 
+

Detailed Description

+

Header file for Descriptors.c.

+

Macro Definition Documentation

+ +
+
+ + + + +
#define CDC_NOTIFICATION_EPADDR   (ENDPOINT_DIR_IN | 2)
+
+

Endpoint address of the CDC device-to-host notification IN endpoint.

+ +
+
+ +
+
+ + + + +
#define CDC_NOTIFICATION_EPSIZE   8
+
+

Size in bytes of the CDC device-to-host notification IN endpoint.

+ +
+
+ +
+
+ + + + +
#define CDC_RX_EPADDR   (ENDPOINT_DIR_OUT | 4)
+
+

Endpoint address of the CDC host-to-device data OUT endpoint.

+ +
+
+ +
+
+ + + + +
#define CDC_TX_EPADDR   (ENDPOINT_DIR_IN | 3)
+
+

Endpoint address of the CDC device-to-host data IN endpoint.

+ +
+
+ +
+
+ + + + +
#define CDC_TXRX_EPSIZE   16
+
+

Size in bytes of the CDC data IN and OUT endpoints.

+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t CALLBACK_USB_GetDescriptor (const uint16_t wValue,
const uint8_t wIndex,
const void **const DescriptorAddress 
)
+
+

This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" documentation) by the application code so that the address and size of a requested descriptor can be given to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the USB host.

+ +
+
+
+ + + + diff --git a/Doc/Doxygen/html/_l_u_f_a_descriptors_8h_source.html b/Doc/Doxygen/html/_l_u_f_a_descriptors_8h_source.html new file mode 100644 index 00000000..7470866e --- /dev/null +++ b/Doc/Doxygen/html/_l_u_f_a_descriptors_8h_source.html @@ -0,0 +1,174 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFADescriptors.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
LUFADescriptors.h
+
+
+Go to the documentation of this file.
1 /*
+
2  LUFA Library
+
3  Copyright (C) Dean Camera, 2012.
+
4 
+
5  dean [at] fourwalledcubicle [dot] com
+
6  www.lufa-lib.org
+
7 */
+
8 
+
9 /*
+
10  Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
11 
+
12  Permission to use, copy, modify, distribute, and sell this
+
13  software and its documentation for any purpose is hereby granted
+
14  without fee, provided that the above copyright notice appear in
+
15  all copies and that both that the copyright notice and this
+
16  permission notice and warranty disclaimer appear in supporting
+
17  documentation, and that the name of the author not be used in
+
18  advertising or publicity pertaining to distribution of the
+
19  software without specific, written prior permission.
+
20 
+
21  The author disclaim all warranties with regard to this
+
22  software, including all implied warranties of merchantability
+
23  and fitness. In no event shall the author be liable for any
+
24  special, indirect or consequential damages or any damages
+
25  whatsoever resulting from loss of use, data or profits, whether
+
26  in an action of contract, negligence or other tortious action,
+
27  arising out of or in connection with the use or performance of
+
28  this software.
+
29 */
+
30 
+
36 #ifndef _DESCRIPTORS_H_
+
37 #define _DESCRIPTORS_H_
+
38 
+
39  /* Includes: */
+
40  #include <avr/pgmspace.h>
+
41 
+
42  #include <LUFA/Drivers/USB/USB.h>
+
43 
+
44  /* Macros: */
+
46  #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2)
+
47 
+
49  #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3)
+
50 
+
52  #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4)
+
53 
+
55  #define CDC_NOTIFICATION_EPSIZE 8
+
56 
+
58  #define CDC_TXRX_EPSIZE 16
+
59 
+
60  /* Type Defines: */
+
65  typedef struct
+
66  {
+
67  USB_Descriptor_Configuration_Header_t Config;
+
68 
+
69  // CDC Control Interface
+
70  USB_Descriptor_Interface_t CDC_CCI_Interface;
+
71  USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+
72  USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+
73  USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+
74  USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
75 
+
76  // CDC Data Interface
+
77  USB_Descriptor_Interface_t CDC_DCI_Interface;
+
78  USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
+
79  USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
+ +
81 
+
82  /* Function Prototypes: */
+
83  uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+
84  const uint8_t wIndex,
+
85  const void** const DescriptorAddress)
+
86  ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
87 
+
88 #endif
+
89 
+
+ + + + diff --git a/Doc/Doxygen/html/_log_8h_source.html b/Doc/Doxygen/html/_log_8h_source.html new file mode 100644 index 00000000..6b05f8b0 --- /dev/null +++ b/Doc/Doxygen/html/_log_8h_source.html @@ -0,0 +1,148 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Log.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Log.h
+
+
+
1 #ifndef LOG_H_
+
2 #define LOG_H_
+
3 
+
4 #include "Common.h"
+
5 
+
6 typedef enum {
+
7  /* Generic */
+
8  LOG_INFO_GENERIC = 0x10,
+
9  LOG_INFO_CONFIG_CHANGED = 0x11,
+
10 
+
11  /* Codec */
+
12  LOG_INFO_RX_DATA = 0x20,
+
13  LOG_INFO_TX_DATA = 0x21,
+
14 
+
15  /* App */
+
16  LOG_INFO_APP_RESET = 0x30,
+
17  LOG_ERR_APP_AUTH_FAIL = 0x31,
+
18  LOG_ERR_APP_CHECKSUM_FAIL = 0x32,
+
19 
+
20  LOG_EMPTY = 0xFF
+
21 } LogEntryEnum;
+
22 
+
23 typedef enum {
+
24  LOG_MODE_OFF,
+
25  LOG_MODE_MEMORY,
+
26  LOG_MODE_TERMINAL
+
27 } LogModeEnum;
+
28 
+
29 typedef void (*LogFuncType) (LogEntryEnum Entry, void* Data, uint8_t Length);
+
30 
+
31 extern LogFuncType LogFunc;
+
32 
+
33 void LogInit(void);
+
34 void LogTick(void);
+
35 void LogTask(void);
+
36 
+
37 void LogMemClear(void);
+
38 uint16_t LogMemFree(void);
+
39 /* XModem callback */
+
40 bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+
41 
+
42 void LogSetModeById(LogModeEnum Mode);
+
43 bool LogSetModeByName(const char* Name);
+
44 void LogGetModeByName(char* Name, uint16_t BufferSize);
+
45 void LogGetModeList(char* List, uint16_t BufferSize);
+
46 
+
47 INLINE void LogEntry(LogEntryEnum Entry, void* Data, uint8_t Length) { LogFunc(Entry, Data, Length); }
+
48 
+
49 #endif /* LOG_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_logging_8txt.html b/Doc/Doxygen/html/_logging_8txt.html new file mode 100644 index 00000000..79a3b6aa --- /dev/null +++ b/Doc/Doxygen/html/_logging_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/Logging.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/Logging.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_main_page_8txt.html b/Doc/Doxygen/html/_main_page_8txt.html new file mode 100644 index 00000000..b9f89be8 --- /dev/null +++ b/Doc/Doxygen/html/_main_page_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/MainPage.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/MainPage.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_memory_8h_source.html b/Doc/Doxygen/html/_memory_8h_source.html new file mode 100644 index 00000000..88019fc8 --- /dev/null +++ b/Doc/Doxygen/html/_memory_8h_source.html @@ -0,0 +1,131 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Memory.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Memory.h
+
+
+
1 /*
+
2  * Flash.h
+
3  *
+
4  * Created on: 20.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef MEMORY_H_
+
9 #define MEMORY_H_
+
10 
+
11 #include "Common.h"
+
12 
+
13 #define MEMORY_FLASH_USART USARTD0
+
14 #define MEMORY_FLASH_PORT PORTD
+
15 #define MEMORY_FLASH_CS PIN4_bm
+
16 #define MEMORY_FLASH_MOSI PIN3_bm
+
17 #define MEMORY_FLASH_MISO PIN2_bm
+
18 #define MEMORY_FLASH_SCK PIN1_bm
+
19 
+
20 #define MEMORY_PAGE_SIZE 256
+
21 #define MEMORY_SIZE_PER_SETTING ((uint32_t) 256 * MEMORY_PAGE_SIZE) /* Multiple of memory page size */
+
22 
+
23 void MemoryInit(void);
+
24 void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount);
+
25 void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount);
+
26 void MemoryClear(void);
+
27 
+
28 /* For use with XModem */
+
29 bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+
30 bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+
31 
+
32 #endif /* MEMORY_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_mifare_classic_8h_source.html b/Doc/Doxygen/html/_mifare_classic_8h_source.html new file mode 100644 index 00000000..408468df --- /dev/null +++ b/Doc/Doxygen/html/_mifare_classic_8h_source.html @@ -0,0 +1,128 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Application/MifareClassic.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
MifareClassic.h
+
+
+
1 /*
+
2  * MifareClassic.h
+
3  *
+
4  * Created on: 13.05.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef MIFARECLASSIC_H_
+
9 #define MIFARECLASSIC_H_
+
10 
+
11 #include "Application.h"
+
12 #include "ISO14443-3A.h"
+
13 
+
14 #define MIFARE_CLASSIC_UID_SIZE ISO14443A_UID_SIZE_SINGLE
+
15 #define MIFARE_CLASSIC_1K_MEM_SIZE 1024
+
16 #define MIFARE_CLASSIC_4K_MEM_SIZE 4096
+
17 
+
18 void MifareClassicAppInit1K(void);
+
19 void MifareClassicAppInit4K(void);
+
20 void MifareClassicAppReset(void);
+
21 void MifareClassicAppTask(void);
+
22 
+
23 uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount);
+
24 
+
25 void MifareClassicGetUid(ConfigurationUidType Uid);
+
26 void MifareClassicSetUid(ConfigurationUidType Uid);
+
27 
+
28 
+
29 #endif /* MIFARECLASSIC_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_mifare_ultralight_8h_source.html b/Doc/Doxygen/html/_mifare_ultralight_8h_source.html new file mode 100644 index 00000000..086c20e8 --- /dev/null +++ b/Doc/Doxygen/html/_mifare_ultralight_8h_source.html @@ -0,0 +1,127 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini/branches/OpenSource/Firmware/Chameleon-Mini/Application/MifareUltralight.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
MifareUltralight.h
+
+
+
1 /*
+
2  * MifareUltralight.h
+
3  *
+
4  * Created on: 20.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef MIFAREULTRALIGHT_H_
+
9 #define MIFAREULTRALIGHT_H_
+
10 
+
11 #include "Application.h"
+
12 #include "ISO14443-3A.h"
+
13 
+
14 #define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE
+
15 #define MIFARE_ULTRALIGHT_MEM_SIZE 64
+
16 
+
17 void MifareUltralightAppInit(void);
+
18 void MifareUltralightAppReset(void);
+
19 void MifareUltralightAppTask(void);
+
20 
+
21 uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount);
+
22 
+
23 void MifareUltralightGetUid(ConfigurationUidType Uid);
+
24 void MifareUltralightSetUid(ConfigurationUidType Uid);
+
25 
+
26 
+
27 
+
28 #endif /* MIFAREULTRALIGHT_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_page__command_line.html b/Doc/Doxygen/html/_page__command_line.html new file mode 100644 index 00000000..80e5f9ab --- /dev/null +++ b/Doc/Doxygen/html/_page__command_line.html @@ -0,0 +1,183 @@ + + + + + + +Chameleon-Mini: The chameleon command line + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
The chameleon command line
+
+
+

The Chameleon-Mini enumerates as a CDC-ACM virtual serial interface. For a high level of compatibility to be both interfaced by a human as well as a user application, it supports a text-based command line, which can be accessed by using simple terminal software like hyper-terminal or teraterm. The serial settings, as in baudrate, stopp and parity bits are ignored on the Chameleon side. Note that there is no echo of entered characters at the Chameleon.

+

Command structure

+

Each of the following commands can result into 3 actions, depending on the character that is appended to it.

+
    +
  • <COMMAND>?: Indicates a request that will always return an information
  • +
  • <COMMAND>=<VALUE>: Indicates to set a value on the Chameleon
  • +
  • <COMMAND>: Indicates to execute a procedure on the Chameleon with an optional response
  • +
+

Note that some commands only support a subset of these 3 actions.

+

In order to perform the desired command action the command has to be suffixed with a carriage return (CR, 0D hexadecimal). In order to be more user-friendly when interfacing the Chameleon with a serial terminal, support for the backspace (08 hexadecimal) and escape (1B hexadecimal) key have been added. Any other control character as defined in the ASCII character set is ignored. Furthermore the Chameleon does not distinguish between uppercase and lowercase.

+

Supported Commands

+

The following list shows the supported commands and how they are used.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command Description
VERSION? Requests the version of the Chameleon
RESET Resets the Chameleon
UPGRADE Sets the Chameleon into firmware upgrade mode (DFU)
CONFIG Returns a comma-separated list of all supported configurations
CONFIG? Returns the currently used configuration
CONFIG=<NAME> Sets the current configuration to <NAME> (See Page_Configurations)
UIDSIZE? Returns the size of the current configuration's UID
UID? Returns the currently set UID
UID=<UID> Sets a new UID to be used in hexadecimal notation
READONLY? Returns the current state of the read-only mode
READONLY=[0;1] Activates or deactivates the read-only mode (Any writing to the memory is silently ignored)
MEMSIZE? Returns the memory size of the current configuration
UPLOAD Waits for an XModem connection to be established in order to upload a memory dump upto the memory size
DOWNLOAD Waits for an XModem connection to be established in order to download a memory dump with exactly the memory size
BUTTON Returns a comma-separated list of supported button press actions for the button
BUTTON? Returns the currently set button press action for BUTTON0
BUTTON=<NAME> Sets the current button press action for BUTTON0
SETTING? Returns the currently activated setting of the chameleon-mini
SETTING=<NUMBER> Sets the active setting of the chameleon-mini
CLEAR Clears the entire memory of the currently activated setting
+

Responses

+

Subsequent to ANY send command, the Chameleon responds with a status number and status message, separated by a colon and terminated with a carriage return and line feed (CR+LF, 0D+0A hexadecimal). Status numbers are of a 3 digit decimal format with the first digit showing the severity of the answer. Status numbers beginning with a '1' denote an informational item and those beginning with a '2' denote an error.

+ + + + + + + + + + + + + + + +
Response Description
100:OK The command executed successfully
101:OK WITH TEXT The command executed successfully and this answer is appended with an additional line of information, terminated with CR+LF
110:WAITING FOR XMODEM The Chameleon is waiting for an XMODEM connection to establish
200:UNKNOWN COMMAND This command is unknown to the Chameleon
201:INVALID COMMAND USAGE This action is not supported by this command
202:INVALID PARAM The format or value of the given parameter value is invalid
+

Accessing the command-line using a terminal software

+

In order to have quick access to the Chameleon's command-line without using any complicated software, we suggest using the TeraTerm terminal emulation software available for windows based operating systems.

+

Connecting and setting up

+

For establishing a connection to the Chameleon's command line, select File -> New Connection, choose the virtual serial port of the Chameleon and hit the "OK" button. TeraTerm now tries to open the serial port and should succeed without any error.

+

For easier use of the command-line using a terminal software the local-echo functionality should be activated, to be able to see what is typed into the chameleon. When using TeraTerm, this can be achieved by selecting Setup -> Terminal and check "Local Echo".

+

Uploading and Downloading dump files

+

In some configurations of the Chameleon, it is necessary to upload a card dump before it can be accessed by a reader. For doing so, the relatively simple and widely known XMODEM protocol is used.

+

To upload a dump file using TeraTerm, follow these steps.

+
    +
  1. Enter UPLOAD and wait for the 110:WAITING FOR XMODEM response
  2. +
  3. Select File -> Transfer -> XMODEM -> Send
  4. +
  5. In the dialog choose the binary dumpfile to be uploaded and make sure the option "Checksum" is checked in the lower left corner
  6. +
  7. Hitting the "Open" button will start the transfer. If no error is given to the user, the file has been uploaded sucessfully.
  8. +
+

To download the Chameleon's memory again, follow the instructions above except for using DOWNLOAD instead of UPLOAD and the Receive function of TeraTerm

+

Note that there is a 10 second timeout after entering UPLOAD respectively DOWNLOAD after which the standard command-line is activated again. So try again if the timeout is already over when the XMODEM transfer is about to start.

+
+ + + + diff --git a/Doc/Doxygen/html/_page__configurations.html b/Doc/Doxygen/html/_page__configurations.html new file mode 100644 index 00000000..4c7566cf --- /dev/null +++ b/Doc/Doxygen/html/_page__configurations.html @@ -0,0 +1,104 @@ + + + + + + +Chameleon-Mini: Available configurations + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Available configurations
+
+
+

The basic idea of the Chameleon-Mini was to integrate so-called configurations to define the device's behaviour. You can choose the active configuration via the command-line using the CONFIG command (See The chameleon command line).

+

Below is a list of the configurations with a brief description of what it is and how it works. In configurations where an actual card is simulated, the card memory has to be uploaded to the Chameleon before accessing it by a reader. This is done using the X-MODEM protocol on the command-line (See The chameleon command line).

+

Configurations

+

NONE

+

The Chameleon's RF interface is not activated and it behaves entirely passive.

+

MF_ULTRALIGHT / MF_CLASSIC_1K / MF_CLASSIC_4K

+

The Chameleon behaves like a Mifare Ultralight or Classic (with 1K or 4K EEPROM).

+

The memory layout of these configurations is as shown in the datasheets from NXP and thus fully compatible with the dumpfiles from libnfc.

+

ISO14443A_SNIFF / ISO15693_SNIFF

+

These are sniffing configurations, where no answers to any requests from a reader are done. Thus the Chameleon behaves completely passive, which is useful if a second card is present in the reader field. Then this configuration can be used in conjunction with one of the logging modes (See Logging capabilities) to sniff for data, e.g. the UID that is sent from the reader to the secondary card.

+

Note that especially with the ISO14443A sniffing mode, it may happen that the load modulation of the secondary card trips the codec and thus logs some garbled data.

+
+ + + + diff --git a/Doc/Doxygen/html/_page__firmware_upgrade.html b/Doc/Doxygen/html/_page__firmware_upgrade.html new file mode 100644 index 00000000..ba5affff --- /dev/null +++ b/Doc/Doxygen/html/_page__firmware_upgrade.html @@ -0,0 +1,98 @@ + + + + + + +Chameleon-Mini: Device Firmware Upgrade (DFU) + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Device Firmware Upgrade (DFU)
+
+
+

It is possible to upgrade the Firmware using the Atmel DFU Protocol as defined in application note AVR1916. With this possible, there is no need to use any other external programming hardware to upgrade the firmware.

+

The Atmel DFU protocol is supported by Atmel's FLIP software, which also contains batchisp and the open source software dfu-programmer. In order to flash a new firmware, the device has to be put into DFU mode. To do this, you can either use the command-line by sending the corresponding command or press the button on the device while powering it up.

+

Once the device is in DFU mode, it enumerates as an ATxmegaXYZ USB device and can now be accessed using the above mentioned software tools for erasing, programming and verifying a new firmware HEX file.

+

Depending on what tool you are using for the DFU firmware upgrade, you may have to install the corresponding driver.

+

Note that this procedure can easily be implemented in a command-line script, diminishing the need for user interaction and speeding up the process. The "make dfu-batchisp" or "make dfu-prog" command can be used to program the device using batchisp or dfu-programmer. Note that in both cases, the directory of the tools executables have to exist in the PATH environment variable.

+
+ + + + diff --git a/Doc/Doxygen/html/_page__getting_started.html b/Doc/Doxygen/html/_page__getting_started.html new file mode 100644 index 00000000..c6e2a482 --- /dev/null +++ b/Doc/Doxygen/html/_page__getting_started.html @@ -0,0 +1,104 @@ + + + + + + +Chameleon-Mini: Getting Started + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Getting Started
+
+
+

The first thing you should do is to program the fuse bits and the bootloader to the Chameleon-Mini. Use your preferred tool to set the fuse bits as follows:

+
    +
  • FUSE1: 0x00
  • +
  • FUSE2: 0xBE
  • +
  • FUSE4: 0xFF
  • +
  • FUSE5: 0xE8
  • +
+

Next, program the appropriate bootloader from the Firmware/Bootloader directory into the chip. The ATxmega chip now automatically enumerates with its DFU bootloader. Now you can use Atmel's FLIP software or the open source dfu-programmer to program the Chameleon-Mini.hex/.eep into the FLASH and EEPROM using the bootloader. For this you should follow the instructions of the particular DFU tool. For windows machines, there is an example batch file in the Firmware/Chameleon-Mini directory.

+

Once you have got the Chameleon up and running, it should enumerate as the LUFA CDC device. On windows, you should use the supplied LUFA VirtualSerial.inf in the Drivers folder. When the installation is successful, a new COM port or /dev/ttyS shows up on your system.

+

This serial port is your means of controlling the Chameleon-Mini from any computer either using a simple terminal emulator, like TeraTerm or your self-crafted scripts and applications.

+

More info on how to use the serial interface can be found here: The chameleon command line

+
+ + + + diff --git a/Doc/Doxygen/html/_page__logging.html b/Doc/Doxygen/html/_page__logging.html new file mode 100644 index 00000000..fd225baf --- /dev/null +++ b/Doc/Doxygen/html/_page__logging.html @@ -0,0 +1,115 @@ + + + + + + +Chameleon-Mini: Logging capabilities + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Logging capabilities
+
+
+

With the implemented logging mechanisms it is possible to trace an access to the Chameleon-Mini by a reader device.

+

Logging is either done via the internal RAM, where the log can be downloaded from via the terminal or using the terminal line directly. Note that in case of using the internal RAM for logging the information, the data is only stored until the Chameleon-Mini loses power. If the memory is full, the logging is disabled automatically.

+

The log format is very simple. Every log entry consists of a 1 byte entry identifier, a 1 byte length identifier and an arbitrary sized chunk of binary data with the length given in the byte before.

+ + + + + +
Byte 0 Byte 1 Byte 2 Byte 3 ... Byte Length+1
EntryId Length Data Data Data Data
+

The available Entry Ids are as follows:

+ + + + + + + + + +
EntryId (Hex) Description
20 Received data
21 Send data
30 Application reset
+

For getting or setting the logging mode, the LOGMODE? respectively LOGMODE=<MODE> command can be used on the terminal. For a list of possible logging modes enter LOGMODE.

+

In order to get the remaining bytes of the logging memory, the LOGMEM? command is to be used. Using LOGMEM=<CMD> it is possible to execute commands on the logging memory, like clearing or downloading it via XMODEM. To get a list of the available commands, enter LOGMEM.

+
+ + + + diff --git a/Doc/Doxygen/html/_page__uploading_downloading.html b/Doc/Doxygen/html/_page__uploading_downloading.html new file mode 100644 index 00000000..7a322623 --- /dev/null +++ b/Doc/Doxygen/html/_page__uploading_downloading.html @@ -0,0 +1,98 @@ + + + + + + +Chameleon-Mini: Uploading and Downloading Memory dumps + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Uploading and Downloading Memory dumps
+
+
+

In order to be able to emulate different card contents, one can upload or download the memory used for emulation.

+

The layout of the memory dump depends on the chosen configuration and is usually the same as the memory layout of the currently chosen card-emulation. The size of the memory dump also depends on the currently chosen configuration and can be requested with a specific command on the command-line.

+

In order to upload or download a memory dump, the user has to send the corresponding command on the command-line first and the Chameleon responds with a status message indicating that it is waiting for an X-MODEM connection. Depending on whether upload or download is chosen, the Chameleon then waits for 10 seconds to initiate an X-MODEM receive or send connection.

+

When waiting for a receiving X-MODEM connection, the X-MODEM NAK byte is sent upto 20 times with a delay of 500ms in order to establish a standard 128 byte frame-size X-MODEM connection with the simple checksum scheme. Within this time, the user has to get his X-MODEM client ready and choose the binary file to be uploaded into the memory.

+

In case of waiting for an X-MODEM send connection to establish, a wait time of 10 seconds is performed to receive the X-MODEM NAK byte. Within this time, the user has to start the X-MODEM receiver and set it to the standard 128 byte frame using the simple checksum scheme in order to receive the binary memory dump.

+
+ + + + diff --git a/Doc/Doxygen/html/_random_8h_source.html b/Doc/Doxygen/html/_random_8h_source.html new file mode 100644 index 00000000..43941998 --- /dev/null +++ b/Doc/Doxygen/html/_random_8h_source.html @@ -0,0 +1,117 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Random.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Random.h
+
+
+
1 /*
+
2  * Random.h
+
3  *
+
4  * Created on: 22.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef RANDOM_H_
+
9 #define RANDOM_H_
+
10 
+
11 #include "Common.h"
+
12 
+
13 void RandomInit(void);
+
14 uint8_t RandomGetByte(void);
+
15 void RandomGetBuffer(void* Buffer, uint8_t ByteCount);
+
16 void RandomTick(void);
+
17 
+
18 #endif /* RANDOM_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_settings_8h_source.html b/Doc/Doxygen/html/_settings_8h_source.html new file mode 100644 index 00000000..6d94252d --- /dev/null +++ b/Doc/Doxygen/html/_settings_8h_source.html @@ -0,0 +1,137 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Settings.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Settings.h
+
+
+
1 /*
+
2  * Settings.h
+
3  *
+
4  * Created on: 21.12.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef SETTINGS_H_
+
9 #define SETTINGS_H_
+
10 
+
11 #include "Button.h"
+
12 #include "Configuration.h"
+
13 
+
14 #define SETTINGS_COUNT 8
+
15 
+
16 typedef struct {
+
17  ButtonActionEnum ButtonAction;
+
18  ConfigurationEnum Configuration;
+
19 } SettingsEntryType;
+
20 
+
21 typedef struct {
+
22  uint8_t ActiveSetting;
+
23  SettingsEntryType* ActiveSettingPtr;
+
24  SettingsEntryType Settings[SETTINGS_COUNT];
+
25 } SettingsType;
+
26 
+
27 extern SettingsType GlobalSettings;
+
28 
+
29 void SettingsLoad(void);
+
30 void SettingsSave(void);
+
31 
+
32 void SettingsCycle(void);
+
33 void SettingsSetActiveById(uint8_t Setting);
+
34 uint8_t SettingsGetActiveById(void);
+
35 void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize);
+
36 bool SettingsSetActiveByName(const char* Setting);
+
37 
+
38 #endif /* SETTINGS_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_system_8h_source.html b/Doc/Doxygen/html/_system_8h_source.html new file mode 100644 index 00000000..897edc9e --- /dev/null +++ b/Doc/Doxygen/html/_system_8h_source.html @@ -0,0 +1,152 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/System.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
System.h
+
+
+
1 /*
+
2  * System.h
+
3  *
+
4  * Created on: 10.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef SYSTEM_H
+
9 #define SYSTEM_H
+
10 
+
11 #include <avr/io.h>
+
12 #include <avr/pgmspace.h>
+
13 #include <avr/interrupt.h>
+
14 #include <stddef.h>
+
15 #include <stdbool.h>
+
16 #include "Common.h"
+
17 
+
18 typedef uint16_t SystemRTCType;
+
19 
+
20 #define F_RTC 1000
+
21 #define SYSTEM_MILLISECONDS_TO_RTC_CYCLES(x) \
+
22  ( (uint16_t) ( (double) F_RTC * x / 1E3 + 0.5) )
+
23 
+
24 #define SYSTEM_TICK_FREQ 10
+
25 #define SYSTEM_TICK_MS (1000/SYSTEM_TICK_FREQ)
+
26 
+
27 void SystemInit(void);
+
28 void SystemReset(void);
+
29 void SystemEnterBootloader(void);
+
30 void SystemStartUSBClock(void);
+
31 void SystemStopUSBClock(void);
+
32 void SystemInterruptInit(void);
+
33 INLINE bool SystemTick100ms(void);
+
34 INLINE SystemRTCType SystemGetRTC(void);
+
35 
+
36 
+
37 INLINE SystemRTCType SystemGetRTC(void)
+
38 {
+
39  return RTC.CNT;
+
40 }
+
41 
+
42 INLINE bool SystemTick100ms(void)
+
43 {
+
44  if (TCE0.INTFLAGS & TC0_OVFIF_bm) {
+
45  TCE0.INTFLAGS = TC0_OVFIF_bm;
+
46 
+
47  return true;
+
48  }
+
49 
+
50  return false;
+
51 }
+
52 
+
53 #endif /* SYSTEM_H */
+
+ + + + diff --git a/Doc/Doxygen/html/_terminal_8h_source.html b/Doc/Doxygen/html/_terminal_8h_source.html new file mode 100644 index 00000000..74243c07 --- /dev/null +++ b/Doc/Doxygen/html/_terminal_8h_source.html @@ -0,0 +1,151 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Terminal/Terminal.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
Terminal.h
+
+
+
1 /*
+
2  * CommandLine.h
+
3  *
+
4  * Created on: 10.02.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef TERMINAL_H_
+
9 #define TERMINAL_H_
+
10 
+
11 #include "../Common.h"
+
12 #include "../LUFA/Drivers/USB/USB.h"
+
13 #include "XModem.h"
+
14 #include "CommandLine.h"
+
15 
+
16 #define TERMINAL_VBUS_PORT PORTD
+
17 #define TERMINAL_VBUS_MASK PIN5_bm
+
18 
+
19 #define TERMINAL_BUFFER_SIZE 256
+
20 
+
21 typedef enum {
+
22  TERMINAL_UNINITIALIZED,
+
23  TERMINAL_INITIALIZING,
+
24  TERMINAL_INITIALIZED,
+
25  TERMINAL_UNITIALIZING
+
26 } TerminalStateEnum;
+
27 
+
28 extern uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE];
+
29 extern USB_ClassInfo_CDC_Device_t TerminalHandle;
+
30 extern TerminalStateEnum TerminalState;
+
31 
+
32 void TerminalInit(void);
+
33 void TerminalTask(void);
+
34 void TerminalTick(void);
+
35 
+
36 /*void TerminalSendBuffer(void* Buffer, uint16_t ByteCount);*/
+
37 INLINE void TerminalSendByte(uint8_t Byte);
+
38 void TerminalSendBlock(void* Buffer, uint16_t ByteCount);
+
39 
+
40 INLINE void TerminalSendChar(char c);
+
41 void TerminalSendString(const char* s);
+
42 void TerminalSendStringP(const char* s);
+
43 
+
44 void EVENT_USB_Device_Connect(void);
+
45 void EVENT_USB_Device_Disconnect(void);
+
46 void EVENT_USB_Device_ConfigurationChanged(void);
+
47 void EVENT_USB_Device_ControlRequest(void);
+
48 
+
49 INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); }
+
50 INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); }
+
51 
+
52 #endif /* TERMINAL_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/_uploading_downloading_8txt.html b/Doc/Doxygen/html/_uploading_downloading_8txt.html new file mode 100644 index 00000000..2840a27c --- /dev/null +++ b/Doc/Doxygen/html/_uploading_downloading_8txt.html @@ -0,0 +1,95 @@ + + + + + + +Chameleon-Mini: DoxygenPages/UploadingDownloading.txt File Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
DoxygenPages/UploadingDownloading.txt File Reference
+
+
+
+ + + + diff --git a/Doc/Doxygen/html/_x_modem_8h_source.html b/Doc/Doxygen/html/_x_modem_8h_source.html new file mode 100644 index 00000000..e8b129d8 --- /dev/null +++ b/Doc/Doxygen/html/_x_modem_8h_source.html @@ -0,0 +1,120 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Terminal/XModem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
XModem.h
+
+
+
1 /*
+
2  * TerminalXModem.h
+
3  *
+
4  * Created on: 22.03.2013
+
5  * Author: skuser
+
6  */
+
7 
+
8 #ifndef XMODEM_H_
+
9 #define XMODEM_H_
+
10 
+
11 #include "../Common.h"
+
12 
+
13 typedef bool (*XModemCallbackType) (void* ByteBuffer, uint32_t BlockAddress, uint16_t ByteCount);
+
14 
+
15 void XModemReceive(XModemCallbackType CallbackFunc);
+
16 void XModemSend(XModemCallbackType CallbackFunc);
+
17 
+
18 bool XModemProcessByte(uint8_t Byte);
+
19 void XModemTick(void);
+
20 
+
21 #endif /* TERMINALXMODEM_H_ */
+
+ + + + diff --git a/Doc/Doxygen/html/annotated.html b/Doc/Doxygen/html/annotated.html new file mode 100644 index 00000000..ab46034d --- /dev/null +++ b/Doc/Doxygen/html/annotated.html @@ -0,0 +1,100 @@ + + + + + + +Chameleon-Mini: Class List + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
+ + + + diff --git a/Doc/Doxygen/html/bc_s.png b/Doc/Doxygen/html/bc_s.png new file mode 100644 index 00000000..224b29aa Binary files /dev/null and b/Doc/Doxygen/html/bc_s.png differ diff --git a/Doc/Doxygen/html/bdwn.png b/Doc/Doxygen/html/bdwn.png new file mode 100644 index 00000000..940a0b95 Binary files /dev/null and b/Doc/Doxygen/html/bdwn.png differ diff --git a/Doc/Doxygen/html/classes.html b/Doc/Doxygen/html/classes.html new file mode 100644 index 00000000..c928f089 --- /dev/null +++ b/Doc/Doxygen/html/classes.html @@ -0,0 +1,104 @@ + + + + + + +Chameleon-Mini: Class Index + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Index
+
+
+ + + + + + +
  U  
+
USB_Descriptor_Configuration_t   
+ +
+ + + + diff --git a/Doc/Doxygen/html/closed.png b/Doc/Doxygen/html/closed.png new file mode 100644 index 00000000..98cc2c90 Binary files /dev/null and b/Doc/Doxygen/html/closed.png differ diff --git a/Doc/Doxygen/html/dir_5de29d499bb29a41092979d00d22c134.html b/Doc/Doxygen/html/dir_5de29d499bb29a41092979d00d22c134.html new file mode 100644 index 00000000..21058709 --- /dev/null +++ b/Doc/Doxygen/html/dir_5de29d499bb29a41092979d00d22c134.html @@ -0,0 +1,111 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Application Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Application Directory Reference
+
+
+ + + + + + + + + + + + + + + + +

+Files

file  Application.h [code]
 
file  Crypto1.c
 
file  Crypto1.h [code]
 
file  ISO14443-3A.c
 
file  ISO14443-3A.h [code]
 
file  MifareClassic.c
 
file  MifareClassic.h [code]
 
+
+ + + + diff --git a/Doc/Doxygen/html/dir_74b6a3b63f61c160c0f14b7a283a4c9b.html b/Doc/Doxygen/html/dir_74b6a3b63f61c160c0f14b7a283a4c9b.html new file mode 100644 index 00000000..10e5acf8 --- /dev/null +++ b/Doc/Doxygen/html/dir_74b6a3b63f61c160c0f14b7a283a4c9b.html @@ -0,0 +1,99 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Firmware Directory Reference
+
+
+ + + + +

+Directories

directory  Chameleon-Mini
 
+
+ + + + diff --git a/Doc/Doxygen/html/dir_8465ec698d237f801ae9966d4551fcfa.html b/Doc/Doxygen/html/dir_8465ec698d237f801ae9966d4551fcfa.html new file mode 100644 index 00000000..c479aed7 --- /dev/null +++ b/Doc/Doxygen/html/dir_8465ec698d237f801ae9966d4551fcfa.html @@ -0,0 +1,151 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Chameleon-Mini Directory Reference
+
+
+ + + + + + + + +

+Directories

directory  Application
 
directory  Codec
 
directory  Terminal
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  AntennaLevel.h [code]
 
file  Button.c
 
file  Button.h [code]
 
file  Chameleon-Mini.c
 
file  Chameleon-Mini.h [code]
 
file  Common.c
 
file  Common.h [code]
 
file  Configuration.c
 
file  Configuration.h [code]
 
file  LED.c
 
file  LED.h [code]
 
file  LUFAConfig.h [code]
 LUFA Library Configuration Header File.
 
file  LUFADescriptors.c
 
file  LUFADescriptors.h [code]
 
file  Memory.c
 
file  Memory.h [code]
 
file  Random.c
 
file  Random.h [code]
 
file  Settings.c
 
file  Settings.h [code]
 
file  System.c
 
file  System.h [code]
 
+
+ + + + diff --git a/Doc/Doxygen/html/dir_ddeffaa734f77525428b0dd4068da9cb.html b/Doc/Doxygen/html/dir_ddeffaa734f77525428b0dd4068da9cb.html new file mode 100644 index 00000000..372c559e --- /dev/null +++ b/Doc/Doxygen/html/dir_ddeffaa734f77525428b0dd4068da9cb.html @@ -0,0 +1,113 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Terminal Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Terminal Directory Reference
+
+
+ + + + + + + + + + + + + + + + + + +

+Files

file  CommandLine.c
 
file  CommandLine.h [code]
 
file  Commands.c
 
file  Commands.h [code]
 
file  Terminal.c
 
file  Terminal.h [code]
 
file  XModem.c
 
file  XModem.h [code]
 
+
+ + + + diff --git a/Doc/Doxygen/html/dir_f5aab302412c0352d69464400cc5ee44.html b/Doc/Doxygen/html/dir_f5aab302412c0352d69464400cc5ee44.html new file mode 100644 index 00000000..c1d5c8a4 --- /dev/null +++ b/Doc/Doxygen/html/dir_f5aab302412c0352d69464400cc5ee44.html @@ -0,0 +1,105 @@ + + + + + + +Chameleon-Mini: C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/Codec Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
Codec Directory Reference
+
+
+ + + + + + + + + + +

+Files

file  Codec.c
 
file  Codec.h [code]
 
file  ISO14443-2A.c
 
file  ISO14443-2A.h [code]
 
+
+ + + + diff --git a/Doc/Doxygen/html/doxygen.css b/Doc/Doxygen/html/doxygen.css new file mode 100644 index 00000000..3ac28511 --- /dev/null +++ b/Doc/Doxygen/html/doxygen.css @@ -0,0 +1,1186 @@ +/* The standard CSS for doxygen 1.8.4 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 0px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view when not used as main index */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/Doc/Doxygen/html/doxygen.png b/Doc/Doxygen/html/doxygen.png new file mode 100644 index 00000000..3ff17d80 Binary files /dev/null and b/Doc/Doxygen/html/doxygen.png differ diff --git a/Doc/Doxygen/html/dynsections.js b/Doc/Doxygen/html/dynsections.js new file mode 100644 index 00000000..ed092c7f --- /dev/null +++ b/Doc/Doxygen/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} +function toggleLevel(level) +{ + $('table.directory tr').each(function(){ + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +Chameleon-Mini: File List + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 1234]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\-Firmware
 \-Chameleon-Mini
  o-Application
  |o*Application.h
  |o*Crypto1.h
  |o*ISO14443-3A.h
  |\*MifareClassic.h
  o-Codec
  |o*Codec.h
  |\*ISO14443-2A.h
  o-Terminal
  |o*CommandLine.h
  |o*Commands.h
  |o*Terminal.h
  |\*XModem.h
  o*AntennaLevel.h
  o*Button.h
  o*Chameleon-Mini.h
  o*Common.h
  o*Configuration.h
  o*LED.h
  o*LUFAConfig.hLUFA Library Configuration Header File
  o*LUFADescriptors.c
  o*LUFADescriptors.h
  o*Memory.h
  o*Random.h
  o*Settings.h
  \*System.h
+
+
+ + + + diff --git a/Doc/Doxygen/html/ftv2blank.png b/Doc/Doxygen/html/ftv2blank.png new file mode 100644 index 00000000..63c605bb Binary files /dev/null and b/Doc/Doxygen/html/ftv2blank.png differ diff --git a/Doc/Doxygen/html/ftv2cl.png b/Doc/Doxygen/html/ftv2cl.png new file mode 100644 index 00000000..132f6577 Binary files /dev/null and b/Doc/Doxygen/html/ftv2cl.png differ diff --git a/Doc/Doxygen/html/ftv2doc.png b/Doc/Doxygen/html/ftv2doc.png new file mode 100644 index 00000000..17edabff Binary files /dev/null and b/Doc/Doxygen/html/ftv2doc.png differ diff --git a/Doc/Doxygen/html/ftv2folderclosed.png b/Doc/Doxygen/html/ftv2folderclosed.png new file mode 100644 index 00000000..bb8ab35e Binary files /dev/null and b/Doc/Doxygen/html/ftv2folderclosed.png differ diff --git a/Doc/Doxygen/html/ftv2folderopen.png b/Doc/Doxygen/html/ftv2folderopen.png new file mode 100644 index 00000000..d6c7f676 Binary files /dev/null and b/Doc/Doxygen/html/ftv2folderopen.png differ diff --git a/Doc/Doxygen/html/ftv2lastnode.png b/Doc/Doxygen/html/ftv2lastnode.png new file mode 100644 index 00000000..63c605bb Binary files /dev/null and b/Doc/Doxygen/html/ftv2lastnode.png differ diff --git a/Doc/Doxygen/html/ftv2link.png b/Doc/Doxygen/html/ftv2link.png new file mode 100644 index 00000000..17edabff Binary files /dev/null and b/Doc/Doxygen/html/ftv2link.png differ diff --git a/Doc/Doxygen/html/ftv2mlastnode.png b/Doc/Doxygen/html/ftv2mlastnode.png new file mode 100644 index 00000000..0b63f6d3 Binary files /dev/null and b/Doc/Doxygen/html/ftv2mlastnode.png differ diff --git a/Doc/Doxygen/html/ftv2mnode.png b/Doc/Doxygen/html/ftv2mnode.png new file mode 100644 index 00000000..0b63f6d3 Binary files /dev/null and b/Doc/Doxygen/html/ftv2mnode.png differ diff --git a/Doc/Doxygen/html/ftv2mo.png b/Doc/Doxygen/html/ftv2mo.png new file mode 100644 index 00000000..4bfb80f7 Binary files /dev/null and b/Doc/Doxygen/html/ftv2mo.png differ diff --git a/Doc/Doxygen/html/ftv2node.png b/Doc/Doxygen/html/ftv2node.png new file mode 100644 index 00000000..63c605bb Binary files /dev/null and b/Doc/Doxygen/html/ftv2node.png differ diff --git a/Doc/Doxygen/html/ftv2ns.png b/Doc/Doxygen/html/ftv2ns.png new file mode 100644 index 00000000..72e3d71c Binary files /dev/null and b/Doc/Doxygen/html/ftv2ns.png differ diff --git a/Doc/Doxygen/html/ftv2plastnode.png b/Doc/Doxygen/html/ftv2plastnode.png new file mode 100644 index 00000000..c6ee22f9 Binary files /dev/null and b/Doc/Doxygen/html/ftv2plastnode.png differ diff --git a/Doc/Doxygen/html/ftv2pnode.png b/Doc/Doxygen/html/ftv2pnode.png new file mode 100644 index 00000000..c6ee22f9 Binary files /dev/null and b/Doc/Doxygen/html/ftv2pnode.png differ diff --git a/Doc/Doxygen/html/ftv2splitbar.png b/Doc/Doxygen/html/ftv2splitbar.png new file mode 100644 index 00000000..fe895f2c Binary files /dev/null and b/Doc/Doxygen/html/ftv2splitbar.png differ diff --git a/Doc/Doxygen/html/ftv2vertline.png b/Doc/Doxygen/html/ftv2vertline.png new file mode 100644 index 00000000..63c605bb Binary files /dev/null and b/Doc/Doxygen/html/ftv2vertline.png differ diff --git a/Doc/Doxygen/html/globals.html b/Doc/Doxygen/html/globals.html new file mode 100644 index 00000000..8cc142d4 --- /dev/null +++ b/Doc/Doxygen/html/globals.html @@ -0,0 +1,135 @@ + + + + + + +Chameleon-Mini: File Members + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented file members with links to the documentation:
+
+ + + + diff --git a/Doc/Doxygen/html/globals_defs.html b/Doc/Doxygen/html/globals_defs.html new file mode 100644 index 00000000..f37b388d --- /dev/null +++ b/Doc/Doxygen/html/globals_defs.html @@ -0,0 +1,116 @@ + + + + + + +Chameleon-Mini: File Members + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/Doc/Doxygen/html/globals_func.html b/Doc/Doxygen/html/globals_func.html new file mode 100644 index 00000000..93ac9531 --- /dev/null +++ b/Doc/Doxygen/html/globals_func.html @@ -0,0 +1,105 @@ + + + + + + +Chameleon-Mini: File Members + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/Doc/Doxygen/html/globals_vars.html b/Doc/Doxygen/html/globals_vars.html new file mode 100644 index 00000000..ebb75b9b --- /dev/null +++ b/Doc/Doxygen/html/globals_vars.html @@ -0,0 +1,116 @@ + + + + + + +Chameleon-Mini: File Members + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/Doc/Doxygen/html/index.html b/Doc/Doxygen/html/index.html new file mode 100644 index 00000000..9282333b --- /dev/null +++ b/Doc/Doxygen/html/index.html @@ -0,0 +1,99 @@ + + + + + + +Chameleon-Mini: Main Page + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + +
+ + + + +
+ +
+ +
+
+
Chameleon-Mini Documentation
+
+
+

Chameleon is a versatile emulator for ISO 14443 contactless smartcards. It is meant to be a programmable platform to assess security aspects in RFID environments and can be used in different attack scenarios like replay or relay attacks and even for emulating an existing smartcard, thus behaving as a perfect clone of a given card.

+

The Chameleon Project has been started by the Chair for Embedded Security at the German University in Bochum and has been licensed as open source to let everyone benefit from the work that has been done so far.

+

We are always looking forward to any means of contributing or contacting us.

+

Pages:

+ +
+ + + + diff --git a/Doc/Doxygen/html/jquery.js b/Doc/Doxygen/html/jquery.js new file mode 100644 index 00000000..c197801c --- /dev/null +++ b/Doc/Doxygen/html/jquery.js @@ -0,0 +1,31 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType; +if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1 +},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av); +ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length; +if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b +})}})(window); diff --git a/Doc/Doxygen/html/nav_f.png b/Doc/Doxygen/html/nav_f.png new file mode 100644 index 00000000..72a58a52 Binary files /dev/null and b/Doc/Doxygen/html/nav_f.png differ diff --git a/Doc/Doxygen/html/nav_g.png b/Doc/Doxygen/html/nav_g.png new file mode 100644 index 00000000..2093a237 Binary files /dev/null and b/Doc/Doxygen/html/nav_g.png differ diff --git a/Doc/Doxygen/html/nav_h.png b/Doc/Doxygen/html/nav_h.png new file mode 100644 index 00000000..33389b10 Binary files /dev/null and b/Doc/Doxygen/html/nav_h.png differ diff --git a/Doc/Doxygen/html/open.png b/Doc/Doxygen/html/open.png new file mode 100644 index 00000000..30f75c7e Binary files /dev/null and b/Doc/Doxygen/html/open.png differ diff --git a/Doc/Doxygen/html/pages.html b/Doc/Doxygen/html/pages.html new file mode 100644 index 00000000..90533178 --- /dev/null +++ b/Doc/Doxygen/html/pages.html @@ -0,0 +1,93 @@ + + + + + + +Chameleon-Mini: Related Pages + + + + + + + + + +
+
+
+ + + + + +
+
Chameleon-Mini +
+
+ + + + + + + + + + +
+ +
+ +
+
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+ +
+
+
+ + + + diff --git a/Doc/Doxygen/html/search/all_61.html b/Doc/Doxygen/html/search/all_61.html new file mode 100644 index 00000000..a78c8f98 --- /dev/null +++ b/Doc/Doxygen/html/search/all_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_61.js b/Doc/Doxygen/html/search/all_61.js new file mode 100644 index 00000000..8f0d2b86 --- /dev/null +++ b/Doc/Doxygen/html/search/all_61.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['available_20configurations',['Available configurations',['../_page__configurations.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/all_63.html b/Doc/Doxygen/html/search/all_63.html new file mode 100644 index 00000000..a46f8949 --- /dev/null +++ b/Doc/Doxygen/html/search/all_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_63.js b/Doc/Doxygen/html/search/all_63.js new file mode 100644 index 00000000..a52cf45d --- /dev/null +++ b/Doc/Doxygen/html/search/all_63.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['callback_5fusb_5fgetdescriptor',['CALLBACK_USB_GetDescriptor',['../_l_u_f_a_descriptors_8c.html#a4d7def6e037bf75e86c24e3adb18d705',1,'CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress): LUFADescriptors.c'],['../_l_u_f_a_descriptors_8h.html#a205665735698917df77439b51d372e64',1,'CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3): LUFADescriptors.c']]], + ['cdc_5fnotification_5fepaddr',['CDC_NOTIFICATION_EPADDR',['../_l_u_f_a_descriptors_8h.html#a375d8befdd497fa6548ed0f72cb0d85d',1,'LUFADescriptors.h']]], + ['cdc_5fnotification_5fepsize',['CDC_NOTIFICATION_EPSIZE',['../_l_u_f_a_descriptors_8h.html#a1cfffa25431375dde9c6c880212f43b6',1,'LUFADescriptors.h']]], + ['cdc_5frx_5fepaddr',['CDC_RX_EPADDR',['../_l_u_f_a_descriptors_8h.html#a5051b28e57390b0072358e2dc602083e',1,'LUFADescriptors.h']]], + ['cdc_5ftx_5fepaddr',['CDC_TX_EPADDR',['../_l_u_f_a_descriptors_8h.html#a2114400269fd643e0e3b597df6a8930d',1,'LUFADescriptors.h']]], + ['cdc_5ftxrx_5fepsize',['CDC_TXRX_EPSIZE',['../_l_u_f_a_descriptors_8h.html#aef7fa1919196a302fd0f8b1079e008be',1,'LUFADescriptors.h']]], + ['commandline_2etxt',['CommandLine.txt',['../_command_line_8txt.html',1,'']]], + ['configurationdescriptor',['ConfigurationDescriptor',['../_l_u_f_a_descriptors_8c.html#a59d882a5961a04a054fab63be98c3b80',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/all_64.html b/Doc/Doxygen/html/search/all_64.html new file mode 100644 index 00000000..64825015 --- /dev/null +++ b/Doc/Doxygen/html/search/all_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_64.js b/Doc/Doxygen/html/search/all_64.js new file mode 100644 index 00000000..f0844079 --- /dev/null +++ b/Doc/Doxygen/html/search/all_64.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['devicedescriptor',['DeviceDescriptor',['../_l_u_f_a_descriptors_8c.html#addd196cc2b517282c4dc2a694313b6ac',1,'LUFADescriptors.c']]], + ['dfu_2etxt',['DFU.txt',['../_d_f_u_8txt.html',1,'']]], + ['device_20firmware_20upgrade_20_28dfu_29',['Device Firmware Upgrade (DFU)',['../_page__firmware_upgrade.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/all_67.html b/Doc/Doxygen/html/search/all_67.html new file mode 100644 index 00000000..1eaa52e0 --- /dev/null +++ b/Doc/Doxygen/html/search/all_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_67.js b/Doc/Doxygen/html/search/all_67.js new file mode 100644 index 00000000..f4935d99 --- /dev/null +++ b/Doc/Doxygen/html/search/all_67.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['gettingstarted_2etxt',['GettingStarted.txt',['../_getting_started_8txt.html',1,'']]], + ['getting_20started',['Getting Started',['../_page__getting_started.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/all_6c.html b/Doc/Doxygen/html/search/all_6c.html new file mode 100644 index 00000000..131c9193 --- /dev/null +++ b/Doc/Doxygen/html/search/all_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_6c.js b/Doc/Doxygen/html/search/all_6c.js new file mode 100644 index 00000000..cfa18f3d --- /dev/null +++ b/Doc/Doxygen/html/search/all_6c.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['languagestring',['LanguageString',['../_l_u_f_a_descriptors_8c.html#a2706320165dd3831bf525233371d7af9',1,'LUFADescriptors.c']]], + ['lufaconfig_2eh',['LUFAConfig.h',['../_l_u_f_a_config_8h.html',1,'']]], + ['lufadescriptors_2ec',['LUFADescriptors.c',['../_l_u_f_a_descriptors_8c.html',1,'']]], + ['lufadescriptors_2eh',['LUFADescriptors.h',['../_l_u_f_a_descriptors_8h.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/all_6d.html b/Doc/Doxygen/html/search/all_6d.html new file mode 100644 index 00000000..650f0402 --- /dev/null +++ b/Doc/Doxygen/html/search/all_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_6d.js b/Doc/Doxygen/html/search/all_6d.js new file mode 100644 index 00000000..88fc1ea4 --- /dev/null +++ b/Doc/Doxygen/html/search/all_6d.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['mainpage_2etxt',['MainPage.txt',['../_main_page_8txt.html',1,'']]], + ['manufacturerstring',['ManufacturerString',['../_l_u_f_a_descriptors_8c.html#a84557c5ab5d188d8d7cfdbfe6de20f02',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/all_70.html b/Doc/Doxygen/html/search/all_70.html new file mode 100644 index 00000000..a28cb546 --- /dev/null +++ b/Doc/Doxygen/html/search/all_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_70.js b/Doc/Doxygen/html/search/all_70.js new file mode 100644 index 00000000..8cfe54f4 --- /dev/null +++ b/Doc/Doxygen/html/search/all_70.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['productstring',['ProductString',['../_l_u_f_a_descriptors_8c.html#ad68575f70b5d6ab576068eec9d59fafb',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/all_74.html b/Doc/Doxygen/html/search/all_74.html new file mode 100644 index 00000000..d7dabea0 --- /dev/null +++ b/Doc/Doxygen/html/search/all_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_74.js b/Doc/Doxygen/html/search/all_74.js new file mode 100644 index 00000000..109a5edb --- /dev/null +++ b/Doc/Doxygen/html/search/all_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['the_20chameleon_20command_20line',['The chameleon command line',['../_page__command_line.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/all_75.html b/Doc/Doxygen/html/search/all_75.html new file mode 100644 index 00000000..d99a4c70 --- /dev/null +++ b/Doc/Doxygen/html/search/all_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/all_75.js b/Doc/Doxygen/html/search/all_75.js new file mode 100644 index 00000000..928aff7c --- /dev/null +++ b/Doc/Doxygen/html/search/all_75.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['uploading_20and_20downloading_20memory_20dumps',['Uploading and Downloading Memory dumps',['../_page__uploading_downloading.html',1,'index']]], + ['uploadingdownloading_2etxt',['UploadingDownloading.txt',['../_uploading_downloading_8txt.html',1,'']]], + ['usb_5fdescriptor_5fconfiguration_5ft',['USB_Descriptor_Configuration_t',['../struct_u_s_b___descriptor___configuration__t.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/classes_75.html b/Doc/Doxygen/html/search/classes_75.html new file mode 100644 index 00000000..1cee543e --- /dev/null +++ b/Doc/Doxygen/html/search/classes_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/classes_75.js b/Doc/Doxygen/html/search/classes_75.js new file mode 100644 index 00000000..1c133fc0 --- /dev/null +++ b/Doc/Doxygen/html/search/classes_75.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['usb_5fdescriptor_5fconfiguration_5ft',['USB_Descriptor_Configuration_t',['../struct_u_s_b___descriptor___configuration__t.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/close.png b/Doc/Doxygen/html/search/close.png new file mode 100644 index 00000000..9342d3df Binary files /dev/null and b/Doc/Doxygen/html/search/close.png differ diff --git a/Doc/Doxygen/html/search/defines_63.html b/Doc/Doxygen/html/search/defines_63.html new file mode 100644 index 00000000..dd91b75a --- /dev/null +++ b/Doc/Doxygen/html/search/defines_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/defines_63.js b/Doc/Doxygen/html/search/defines_63.js new file mode 100644 index 00000000..df13009a --- /dev/null +++ b/Doc/Doxygen/html/search/defines_63.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['cdc_5fnotification_5fepaddr',['CDC_NOTIFICATION_EPADDR',['../_l_u_f_a_descriptors_8h.html#a375d8befdd497fa6548ed0f72cb0d85d',1,'LUFADescriptors.h']]], + ['cdc_5fnotification_5fepsize',['CDC_NOTIFICATION_EPSIZE',['../_l_u_f_a_descriptors_8h.html#a1cfffa25431375dde9c6c880212f43b6',1,'LUFADescriptors.h']]], + ['cdc_5frx_5fepaddr',['CDC_RX_EPADDR',['../_l_u_f_a_descriptors_8h.html#a5051b28e57390b0072358e2dc602083e',1,'LUFADescriptors.h']]], + ['cdc_5ftx_5fepaddr',['CDC_TX_EPADDR',['../_l_u_f_a_descriptors_8h.html#a2114400269fd643e0e3b597df6a8930d',1,'LUFADescriptors.h']]], + ['cdc_5ftxrx_5fepsize',['CDC_TXRX_EPSIZE',['../_l_u_f_a_descriptors_8h.html#aef7fa1919196a302fd0f8b1079e008be',1,'LUFADescriptors.h']]] +]; diff --git a/Doc/Doxygen/html/search/files_63.html b/Doc/Doxygen/html/search/files_63.html new file mode 100644 index 00000000..1dd7c8eb --- /dev/null +++ b/Doc/Doxygen/html/search/files_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_63.js b/Doc/Doxygen/html/search/files_63.js new file mode 100644 index 00000000..f548be47 --- /dev/null +++ b/Doc/Doxygen/html/search/files_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['commandline_2etxt',['CommandLine.txt',['../_command_line_8txt.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/files_64.html b/Doc/Doxygen/html/search/files_64.html new file mode 100644 index 00000000..97ed6f2c --- /dev/null +++ b/Doc/Doxygen/html/search/files_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_64.js b/Doc/Doxygen/html/search/files_64.js new file mode 100644 index 00000000..7a5c4698 --- /dev/null +++ b/Doc/Doxygen/html/search/files_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dfu_2etxt',['DFU.txt',['../_d_f_u_8txt.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/files_67.html b/Doc/Doxygen/html/search/files_67.html new file mode 100644 index 00000000..1df9025b --- /dev/null +++ b/Doc/Doxygen/html/search/files_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_67.js b/Doc/Doxygen/html/search/files_67.js new file mode 100644 index 00000000..0bc8ef6e --- /dev/null +++ b/Doc/Doxygen/html/search/files_67.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['gettingstarted_2etxt',['GettingStarted.txt',['../_getting_started_8txt.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/files_6c.html b/Doc/Doxygen/html/search/files_6c.html new file mode 100644 index 00000000..3eda986d --- /dev/null +++ b/Doc/Doxygen/html/search/files_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_6c.js b/Doc/Doxygen/html/search/files_6c.js new file mode 100644 index 00000000..585f39f1 --- /dev/null +++ b/Doc/Doxygen/html/search/files_6c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['lufaconfig_2eh',['LUFAConfig.h',['../_l_u_f_a_config_8h.html',1,'']]], + ['lufadescriptors_2ec',['LUFADescriptors.c',['../_l_u_f_a_descriptors_8c.html',1,'']]], + ['lufadescriptors_2eh',['LUFADescriptors.h',['../_l_u_f_a_descriptors_8h.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/files_6d.html b/Doc/Doxygen/html/search/files_6d.html new file mode 100644 index 00000000..8148b75c --- /dev/null +++ b/Doc/Doxygen/html/search/files_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_6d.js b/Doc/Doxygen/html/search/files_6d.js new file mode 100644 index 00000000..6a6a345d --- /dev/null +++ b/Doc/Doxygen/html/search/files_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['mainpage_2etxt',['MainPage.txt',['../_main_page_8txt.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/files_75.html b/Doc/Doxygen/html/search/files_75.html new file mode 100644 index 00000000..feb3a940 --- /dev/null +++ b/Doc/Doxygen/html/search/files_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/files_75.js b/Doc/Doxygen/html/search/files_75.js new file mode 100644 index 00000000..913fbf6d --- /dev/null +++ b/Doc/Doxygen/html/search/files_75.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['uploadingdownloading_2etxt',['UploadingDownloading.txt',['../_uploading_downloading_8txt.html',1,'']]] +]; diff --git a/Doc/Doxygen/html/search/functions_63.html b/Doc/Doxygen/html/search/functions_63.html new file mode 100644 index 00000000..ec8b6f13 --- /dev/null +++ b/Doc/Doxygen/html/search/functions_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/functions_63.js b/Doc/Doxygen/html/search/functions_63.js new file mode 100644 index 00000000..eee90873 --- /dev/null +++ b/Doc/Doxygen/html/search/functions_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['callback_5fusb_5fgetdescriptor',['CALLBACK_USB_GetDescriptor',['../_l_u_f_a_descriptors_8c.html#a4d7def6e037bf75e86c24e3adb18d705',1,'CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress): LUFADescriptors.c'],['../_l_u_f_a_descriptors_8h.html#a205665735698917df77439b51d372e64',1,'CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3): LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/mag_sel.png b/Doc/Doxygen/html/search/mag_sel.png new file mode 100644 index 00000000..81f6040a Binary files /dev/null and b/Doc/Doxygen/html/search/mag_sel.png differ diff --git a/Doc/Doxygen/html/search/nomatches.html b/Doc/Doxygen/html/search/nomatches.html new file mode 100644 index 00000000..b1ded27e --- /dev/null +++ b/Doc/Doxygen/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/Doc/Doxygen/html/search/pages_61.html b/Doc/Doxygen/html/search/pages_61.html new file mode 100644 index 00000000..3e8e1be8 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_61.js b/Doc/Doxygen/html/search/pages_61.js new file mode 100644 index 00000000..8f0d2b86 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_61.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['available_20configurations',['Available configurations',['../_page__configurations.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/pages_64.html b/Doc/Doxygen/html/search/pages_64.html new file mode 100644 index 00000000..fc94761a --- /dev/null +++ b/Doc/Doxygen/html/search/pages_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_64.js b/Doc/Doxygen/html/search/pages_64.js new file mode 100644 index 00000000..04333520 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['device_20firmware_20upgrade_20_28dfu_29',['Device Firmware Upgrade (DFU)',['../_page__firmware_upgrade.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/pages_67.html b/Doc/Doxygen/html/search/pages_67.html new file mode 100644 index 00000000..6b74d460 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_67.js b/Doc/Doxygen/html/search/pages_67.js new file mode 100644 index 00000000..f6b17336 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_67.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['getting_20started',['Getting Started',['../_page__getting_started.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/pages_6c.html b/Doc/Doxygen/html/search/pages_6c.html new file mode 100644 index 00000000..523b6a28 --- /dev/null +++ b/Doc/Doxygen/html/search/pages_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_6c.js b/Doc/Doxygen/html/search/pages_6c.js new file mode 100644 index 00000000..79e8c54f --- /dev/null +++ b/Doc/Doxygen/html/search/pages_6c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['logging_20capabilities',['Logging capabilities',['../_page__logging.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/pages_74.html b/Doc/Doxygen/html/search/pages_74.html new file mode 100644 index 00000000..15d3175b --- /dev/null +++ b/Doc/Doxygen/html/search/pages_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_74.js b/Doc/Doxygen/html/search/pages_74.js new file mode 100644 index 00000000..109a5edb --- /dev/null +++ b/Doc/Doxygen/html/search/pages_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['the_20chameleon_20command_20line',['The chameleon command line',['../_page__command_line.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/pages_75.html b/Doc/Doxygen/html/search/pages_75.html new file mode 100644 index 00000000..2c450dec --- /dev/null +++ b/Doc/Doxygen/html/search/pages_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/pages_75.js b/Doc/Doxygen/html/search/pages_75.js new file mode 100644 index 00000000..a398b7be --- /dev/null +++ b/Doc/Doxygen/html/search/pages_75.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['uploading_20and_20downloading_20memory_20dumps',['Uploading and Downloading Memory dumps',['../_page__uploading_downloading.html',1,'index']]] +]; diff --git a/Doc/Doxygen/html/search/search.css b/Doc/Doxygen/html/search/search.css new file mode 100644 index 00000000..4d7612ff --- /dev/null +++ b/Doc/Doxygen/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/Doc/Doxygen/html/search/search.js b/Doc/Doxygen/html/search/search.js new file mode 100644 index 00000000..6490c734 --- /dev/null +++ b/Doc/Doxygen/html/search/search.js @@ -0,0 +1,807 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100100001100100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100100001100000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000001100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 5: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 6: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "files", + 3: "functions", + 4: "variables", + 5: "defines", + 6: "pages" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var hexCode; + if (code<16) + { + hexCode="0"+code.toString(16); + } + else + { + hexCode=code.toString(16); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') + { + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/variables_63.js b/Doc/Doxygen/html/search/variables_63.js new file mode 100644 index 00000000..baab4f32 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['configurationdescriptor',['ConfigurationDescriptor',['../_l_u_f_a_descriptors_8c.html#a59d882a5961a04a054fab63be98c3b80',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/variables_64.html b/Doc/Doxygen/html/search/variables_64.html new file mode 100644 index 00000000..87ccbcc8 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/variables_64.js b/Doc/Doxygen/html/search/variables_64.js new file mode 100644 index 00000000..200675de --- /dev/null +++ b/Doc/Doxygen/html/search/variables_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['devicedescriptor',['DeviceDescriptor',['../_l_u_f_a_descriptors_8c.html#addd196cc2b517282c4dc2a694313b6ac',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/variables_6c.html b/Doc/Doxygen/html/search/variables_6c.html new file mode 100644 index 00000000..30533ad0 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/variables_6c.js b/Doc/Doxygen/html/search/variables_6c.js new file mode 100644 index 00000000..0c38fb81 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_6c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['languagestring',['LanguageString',['../_l_u_f_a_descriptors_8c.html#a2706320165dd3831bf525233371d7af9',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/variables_6d.html b/Doc/Doxygen/html/search/variables_6d.html new file mode 100644 index 00000000..ca885469 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/variables_6d.js b/Doc/Doxygen/html/search/variables_6d.js new file mode 100644 index 00000000..e0412b47 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['manufacturerstring',['ManufacturerString',['../_l_u_f_a_descriptors_8c.html#a84557c5ab5d188d8d7cfdbfe6de20f02',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/search/variables_70.html b/Doc/Doxygen/html/search/variables_70.html new file mode 100644 index 00000000..091e4bf8 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/Doc/Doxygen/html/search/variables_70.js b/Doc/Doxygen/html/search/variables_70.js new file mode 100644 index 00000000..8cfe54f4 --- /dev/null +++ b/Doc/Doxygen/html/search/variables_70.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['productstring',['ProductString',['../_l_u_f_a_descriptors_8c.html#ad68575f70b5d6ab576068eec9d59fafb',1,'LUFADescriptors.c']]] +]; diff --git a/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t-members.html b/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t-members.html new file mode 100644 index 00000000..be28d6d4 --- /dev/null +++ b/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t-members.html @@ -0,0 +1,98 @@ + + + + + + +Chameleon-Mini: Member List + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
USB_Descriptor_Configuration_t Member List
+
+
+ +

This is the complete list of members for USB_Descriptor_Configuration_t, including all inherited members.

+ +
+ + + + diff --git a/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t.html b/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t.html new file mode 100644 index 00000000..965a94d2 --- /dev/null +++ b/Doc/Doxygen/html/struct_u_s_b___descriptor___configuration__t.html @@ -0,0 +1,104 @@ + + + + + + +Chameleon-Mini: USB_Descriptor_Configuration_t Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Chameleon-Mini +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
USB_Descriptor_Configuration_t Struct Reference
+
+
+ +

#include <LUFADescriptors.h>

+

Detailed Description

+

Type define for the device configuration descriptor structure. This must be defined in the application code, as the configuration descriptor contains several sub-descriptors which vary between devices, and which describe the device's usage to the host.

+

The documentation for this struct was generated from the following file:
    +
  • C:/Dokumente und Einstellungen/skuser/Eigene Dateien/Chameleon-Mini-OpenSource/Firmware/Chameleon-Mini/LUFADescriptors.h
  • +
+
+ + + + diff --git a/Doc/Doxygen/html/sync_off.png b/Doc/Doxygen/html/sync_off.png new file mode 100644 index 00000000..3b443fc6 Binary files /dev/null and b/Doc/Doxygen/html/sync_off.png differ diff --git a/Doc/Doxygen/html/sync_on.png b/Doc/Doxygen/html/sync_on.png new file mode 100644 index 00000000..e08320fb Binary files /dev/null and b/Doc/Doxygen/html/sync_on.png differ diff --git a/Doc/Doxygen/html/tab_a.png b/Doc/Doxygen/html/tab_a.png new file mode 100644 index 00000000..3b725c41 Binary files /dev/null and b/Doc/Doxygen/html/tab_a.png differ diff --git a/Doc/Doxygen/html/tab_b.png b/Doc/Doxygen/html/tab_b.png new file mode 100644 index 00000000..e2b4a863 Binary files /dev/null and b/Doc/Doxygen/html/tab_b.png differ diff --git a/Doc/Doxygen/html/tab_h.png b/Doc/Doxygen/html/tab_h.png new file mode 100644 index 00000000..fd5cb705 Binary files /dev/null and b/Doc/Doxygen/html/tab_h.png differ diff --git a/Doc/Doxygen/html/tab_s.png b/Doc/Doxygen/html/tab_s.png new file mode 100644 index 00000000..ab478c95 Binary files /dev/null and b/Doc/Doxygen/html/tab_s.png differ diff --git a/Doc/Doxygen/html/tabs.css b/Doc/Doxygen/html/tabs.css new file mode 100644 index 00000000..9cf578f2 --- /dev/null +++ b/Doc/Doxygen/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/Doc/Doxygen/latex/Makefile b/Doc/Doxygen/latex/Makefile new file mode 100644 index 00000000..3cc085fe --- /dev/null +++ b/Doc/Doxygen/latex/Makefile @@ -0,0 +1,21 @@ +all: refman.pdf + +pdf: refman.pdf + +refman.pdf: clean refman.tex + pdflatex refman + makeindex refman.idx + pdflatex refman + latex_count=5 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + pdflatex refman ;\ + latex_count=`expr $$latex_count - 1` ;\ + done + makeindex refman.idx + pdflatex refman + + +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf diff --git a/Doc/Doxygen/latex/_command_line_8txt.tex b/Doc/Doxygen/latex/_command_line_8txt.tex new file mode 100644 index 00000000..a6eeefa7 --- /dev/null +++ b/Doc/Doxygen/latex/_command_line_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_command_line_8txt}{\section{Doxygen\-Pages/\-Command\-Line.txt File Reference} +\label{_command_line_8txt}\index{Doxygen\-Pages/\-Command\-Line.\-txt@{Doxygen\-Pages/\-Command\-Line.\-txt}} +} diff --git a/Doc/Doxygen/latex/_configurations_8txt.tex b/Doc/Doxygen/latex/_configurations_8txt.tex new file mode 100644 index 00000000..9173fce4 --- /dev/null +++ b/Doc/Doxygen/latex/_configurations_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_configurations_8txt}{\section{Doxygen\-Pages/\-Configurations.txt File Reference} +\label{_configurations_8txt}\index{Doxygen\-Pages/\-Configurations.\-txt@{Doxygen\-Pages/\-Configurations.\-txt}} +} diff --git a/Doc/Doxygen/latex/_d_f_u_8txt.tex b/Doc/Doxygen/latex/_d_f_u_8txt.tex new file mode 100644 index 00000000..f763cbb2 --- /dev/null +++ b/Doc/Doxygen/latex/_d_f_u_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_d_f_u_8txt}{\section{Doxygen\-Pages/\-D\-F\-U.txt File Reference} +\label{_d_f_u_8txt}\index{Doxygen\-Pages/\-D\-F\-U.\-txt@{Doxygen\-Pages/\-D\-F\-U.\-txt}} +} diff --git a/Doc/Doxygen/latex/_getting_started_8txt.tex b/Doc/Doxygen/latex/_getting_started_8txt.tex new file mode 100644 index 00000000..1946e771 --- /dev/null +++ b/Doc/Doxygen/latex/_getting_started_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_getting_started_8txt}{\section{Doxygen\-Pages/\-Getting\-Started.txt File Reference} +\label{_getting_started_8txt}\index{Doxygen\-Pages/\-Getting\-Started.\-txt@{Doxygen\-Pages/\-Getting\-Started.\-txt}} +} diff --git a/Doc/Doxygen/latex/_l_u_f_a_config_8h.tex b/Doc/Doxygen/latex/_l_u_f_a_config_8h.tex new file mode 100644 index 00000000..5c835569 --- /dev/null +++ b/Doc/Doxygen/latex/_l_u_f_a_config_8h.tex @@ -0,0 +1,14 @@ +\hypertarget{_l_u_f_a_config_8h}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Config.h File Reference} +\label{_l_u_f_a_config_8h}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Config.\-h@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Config.\-h}} +} + + +L\-U\-F\-A Library Configuration Header File. + + + + +\subsection{Detailed Description} +L\-U\-F\-A Library Configuration Header File. This header file is used to configure L\-U\-F\-A's compile time options, as an alternative to the compile time constants supplied through a makefile. + +For information on what each token does, refer to the L\-U\-F\-A manual section \char`\"{}\-Summary of Compile Tokens\char`\"{}. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_l_u_f_a_descriptors_8c.tex b/Doc/Doxygen/latex/_l_u_f_a_descriptors_8c.tex new file mode 100644 index 00000000..4cc805d6 --- /dev/null +++ b/Doc/Doxygen/latex/_l_u_f_a_descriptors_8c.tex @@ -0,0 +1,113 @@ +\hypertarget{_l_u_f_a_descriptors_8c}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.c File Reference} +\label{_l_u_f_a_descriptors_8c}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.\-c@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.\-c}} +} +{\ttfamily \#include \char`\"{}L\-U\-F\-A\-Descriptors.\-h\char`\"{}}\\* +\subsection*{Functions} +\begin{DoxyCompactItemize} +\item +uint16\-\_\-t \hyperlink{_l_u_f_a_descriptors_8c_a4d7def6e037bf75e86c24e3adb18d705}{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor} (const uint16\-\_\-t w\-Value, const uint8\-\_\-t w\-Index, const void $\ast$$\ast$const Descriptor\-Address) +\end{DoxyCompactItemize} +\subsection*{Variables} +\begin{DoxyCompactItemize} +\item +const U\-S\-B\-\_\-\-Descriptor\-\_\-\-Device\-\_\-t \\* +P\-R\-O\-G\-M\-E\-M \hyperlink{_l_u_f_a_descriptors_8c_addd196cc2b517282c4dc2a694313b6ac}{Device\-Descriptor} +\item +const \\* +\hyperlink{struct_u_s_b___descriptor___configuration__t}{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t} \\* +P\-R\-O\-G\-M\-E\-M \hyperlink{_l_u_f_a_descriptors_8c_a59d882a5961a04a054fab63be98c3b80}{Configuration\-Descriptor} +\item +const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t \\* +P\-R\-O\-G\-M\-E\-M \hyperlink{_l_u_f_a_descriptors_8c_a2706320165dd3831bf525233371d7af9}{Language\-String} +\item +const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t \\* +P\-R\-O\-G\-M\-E\-M \hyperlink{_l_u_f_a_descriptors_8c_a84557c5ab5d188d8d7cfdbfe6de20f02}{Manufacturer\-String} +\item +const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t \\* +P\-R\-O\-G\-M\-E\-M \hyperlink{_l_u_f_a_descriptors_8c_ad68575f70b5d6ab576068eec9d59fafb}{Product\-String} +\end{DoxyCompactItemize} + + +\subsection{Detailed Description} +U\-S\-B Device Descriptors, for library use when in U\-S\-B device mode. Descriptors are special computer-\/readable structures which the host requests upon device enumeration, to determine the device's capabilities and functions. + +\subsection{Function Documentation} +\hypertarget{_l_u_f_a_descriptors_8c_a4d7def6e037bf75e86c24e3adb18d705}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor@{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}} +\index{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor@{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor ( +\begin{DoxyParamCaption} +\item[{const uint16\-\_\-t}]{w\-Value, } +\item[{const uint8\-\_\-t}]{w\-Index, } +\item[{const void $\ast$$\ast$const}]{Descriptor\-Address} +\end{DoxyParamCaption} +)}}\label{_l_u_f_a_descriptors_8c_a4d7def6e037bf75e86c24e3adb18d705} +This function is called by the library when in device mode, and must be overridden (see library \char`\"{}\-U\-S\-B Descriptors\char`\"{} documentation) by the application code so that the address and size of a requested descriptor can be given to the U\-S\-B library. When the device receives a Get Descriptor request on the control endpoint, this function is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the U\-S\-B host. + +\subsection{Variable Documentation} +\hypertarget{_l_u_f_a_descriptors_8c_a59d882a5961a04a054fab63be98c3b80}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!Configuration\-Descriptor@{Configuration\-Descriptor}} +\index{Configuration\-Descriptor@{Configuration\-Descriptor}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{Configuration\-Descriptor}]{\setlength{\rightskip}{0pt plus 5cm}const {\bf U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t} P\-R\-O\-G\-M\-E\-M Configuration\-Descriptor}}\label{_l_u_f_a_descriptors_8c_a59d882a5961a04a054fab63be98c3b80} +Configuration descriptor structure. This descriptor, located in F\-L\-A\-S\-H memory, describes the usage of the device in one of its supported configurations, including information about any device interfaces and endpoints. The descriptor is read out by the U\-S\-B host during the enumeration process when selecting a configuration so that the host may correctly communicate with the U\-S\-B device. \hypertarget{_l_u_f_a_descriptors_8c_addd196cc2b517282c4dc2a694313b6ac}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!Device\-Descriptor@{Device\-Descriptor}} +\index{Device\-Descriptor@{Device\-Descriptor}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{Device\-Descriptor}]{\setlength{\rightskip}{0pt plus 5cm}const U\-S\-B\-\_\-\-Descriptor\-\_\-\-Device\-\_\-t P\-R\-O\-G\-M\-E\-M Device\-Descriptor}}\label{_l_u_f_a_descriptors_8c_addd196cc2b517282c4dc2a694313b6ac} +{\bfseries Initial value\-:} +\begin{DoxyCode} += +\{ + .Header = \{.Size = \textcolor{keyword}{sizeof}(USB\_Descriptor\_Device\_t), .Type = DTYPE\_Device\}, + + .USBSpecification = VERSION\_BCD(01.10), + .Class = CDC\_CSCP\_CDCClass, + .SubClass = CDC\_CSCP\_NoSpecificSubclass, + .Protocol = CDC\_CSCP\_NoSpecificProtocol, + + .Endpoint0Size = FIXED\_CONTROL\_ENDPOINT\_SIZE, + + .VendorID = 0x03EB, + .ProductID = 0x2044, + .ReleaseNumber = VERSION\_BCD(00.01), + + .ManufacturerStrIndex = 0x01, + .ProductStrIndex = 0x02, + .SerialNumStrIndex = USE\_INTERNAL\_SERIAL, + + .NumberOfConfigurations = FIXED\_NUM\_CONFIGURATIONS +\} +\end{DoxyCode} +Device descriptor structure. This descriptor, located in F\-L\-A\-S\-H memory, describes the overall device characteristics, including the supported U\-S\-B version, control endpoint size and the number of device configurations. The descriptor is read out by the U\-S\-B host when the enumeration process begins. \hypertarget{_l_u_f_a_descriptors_8c_a2706320165dd3831bf525233371d7af9}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!Language\-String@{Language\-String}} +\index{Language\-String@{Language\-String}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{Language\-String}]{\setlength{\rightskip}{0pt plus 5cm}const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t P\-R\-O\-G\-M\-E\-M Language\-String}}\label{_l_u_f_a_descriptors_8c_a2706320165dd3831bf525233371d7af9} +{\bfseries Initial value\-:} +\begin{DoxyCode} += +\{ + .Header = \{.Size = USB\_STRING\_LEN(1), .Type = DTYPE\_String\}, + + .UnicodeString = \{LANGUAGE\_ID\_ENG\} +\} +\end{DoxyCode} +Language descriptor structure. This descriptor, located in F\-L\-A\-S\-H memory, is returned when the host requests the string descriptor with index 0 (the first index). It is actually an array of 16-\/bit integers, which indicate via the language I\-D table available at U\-S\-B.\-org what languages the device supports for its string descriptors. \hypertarget{_l_u_f_a_descriptors_8c_a84557c5ab5d188d8d7cfdbfe6de20f02}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!Manufacturer\-String@{Manufacturer\-String}} +\index{Manufacturer\-String@{Manufacturer\-String}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{Manufacturer\-String}]{\setlength{\rightskip}{0pt plus 5cm}const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t P\-R\-O\-G\-M\-E\-M Manufacturer\-String}}\label{_l_u_f_a_descriptors_8c_a84557c5ab5d188d8d7cfdbfe6de20f02} +{\bfseries Initial value\-:} +\begin{DoxyCode} += +\{ + .Header = \{.Size = USB\_STRING\_LEN(11), .Type = DTYPE\_String\}, + + .UnicodeString = L\textcolor{stringliteral}{"Dean Camera"} +\} +\end{DoxyCode} +Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable form, and is read out upon request by the host when the appropriate string I\-D is requested, listed in the Device Descriptor. \hypertarget{_l_u_f_a_descriptors_8c_ad68575f70b5d6ab576068eec9d59fafb}{\index{L\-U\-F\-A\-Descriptors.\-c@{L\-U\-F\-A\-Descriptors.\-c}!Product\-String@{Product\-String}} +\index{Product\-String@{Product\-String}!LUFADescriptors.c@{L\-U\-F\-A\-Descriptors.\-c}} +\subsubsection[{Product\-String}]{\setlength{\rightskip}{0pt plus 5cm}const U\-S\-B\-\_\-\-Descriptor\-\_\-\-String\-\_\-t P\-R\-O\-G\-M\-E\-M Product\-String}}\label{_l_u_f_a_descriptors_8c_ad68575f70b5d6ab576068eec9d59fafb} +{\bfseries Initial value\-:} +\begin{DoxyCode} += +\{ + .Header = \{.Size = USB\_STRING\_LEN(13), .Type = DTYPE\_String\}, + + .UnicodeString = L\textcolor{stringliteral}{"LUFA CDC Demo"} +\} +\end{DoxyCode} +Product descriptor string. This is a Unicode string containing the product's details in human readable form, and is read out upon request by the host when the appropriate string I\-D is requested, listed in the Device Descriptor. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_l_u_f_a_descriptors_8h.tex b/Doc/Doxygen/latex/_l_u_f_a_descriptors_8h.tex new file mode 100644 index 00000000..1313c921 --- /dev/null +++ b/Doc/Doxygen/latex/_l_u_f_a_descriptors_8h.tex @@ -0,0 +1,62 @@ +\hypertarget{_l_u_f_a_descriptors_8h}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.h File Reference} +\label{_l_u_f_a_descriptors_8h}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.\-h@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-L\-U\-F\-A\-Descriptors.\-h}} +} +{\ttfamily \#include $<$avr/pgmspace.\-h$>$}\\* +{\ttfamily \#include $<$L\-U\-F\-A/\-Drivers/\-U\-S\-B/\-U\-S\-B.\-h$>$}\\* +\subsection*{Classes} +\begin{DoxyCompactItemize} +\item +struct \hyperlink{struct_u_s_b___descriptor___configuration__t}{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t} +\end{DoxyCompactItemize} +\subsection*{Macros} +\begin{DoxyCompactItemize} +\item +\#define \hyperlink{_l_u_f_a_descriptors_8h_a375d8befdd497fa6548ed0f72cb0d85d}{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R}~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-I\-N $|$ 2) +\item +\#define \hyperlink{_l_u_f_a_descriptors_8h_a2114400269fd643e0e3b597df6a8930d}{C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R}~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-I\-N $|$ 3) +\item +\#define \hyperlink{_l_u_f_a_descriptors_8h_a5051b28e57390b0072358e2dc602083e}{C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R}~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-O\-U\-T $|$ 4) +\item +\#define \hyperlink{_l_u_f_a_descriptors_8h_a1cfffa25431375dde9c6c880212f43b6}{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E}~8 +\item +\#define \hyperlink{_l_u_f_a_descriptors_8h_aef7fa1919196a302fd0f8b1079e008be}{C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E}~16 +\end{DoxyCompactItemize} +\subsection*{Functions} +\begin{DoxyCompactItemize} +\item +uint16\-\_\-t \hyperlink{_l_u_f_a_descriptors_8h_a205665735698917df77439b51d372e64}{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor} (const uint16\-\_\-t w\-Value, const uint8\-\_\-t w\-Index, const void $\ast$$\ast$const Descriptor\-Address) A\-T\-T\-R\-\_\-\-W\-A\-R\-N\-\_\-\-U\-N\-U\-S\-E\-D\-\_\-\-R\-E\-S\-U\-L\-T A\-T\-T\-R\-\_\-\-N\-O\-N\-\_\-\-N\-U\-L\-L\-\_\-\-P\-T\-R\-\_\-\-A\-R\-G(3) +\end{DoxyCompactItemize} + + +\subsection{Detailed Description} +Header file for Descriptors.\-c. + +\subsection{Macro Definition Documentation} +\hypertarget{_l_u_f_a_descriptors_8h_a375d8befdd497fa6548ed0f72cb0d85d}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R}} +\index{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R}]{\setlength{\rightskip}{0pt plus 5cm}\#define C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-A\-D\-D\-R~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-I\-N $|$ 2)}}\label{_l_u_f_a_descriptors_8h_a375d8befdd497fa6548ed0f72cb0d85d} +Endpoint address of the C\-D\-C device-\/to-\/host notification I\-N endpoint. \hypertarget{_l_u_f_a_descriptors_8h_a1cfffa25431375dde9c6c880212f43b6}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E@{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E}} +\index{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E@{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E}]{\setlength{\rightskip}{0pt plus 5cm}\#define C\-D\-C\-\_\-\-N\-O\-T\-I\-F\-I\-C\-A\-T\-I\-O\-N\-\_\-\-E\-P\-S\-I\-Z\-E~8}}\label{_l_u_f_a_descriptors_8h_a1cfffa25431375dde9c6c880212f43b6} +Size in bytes of the C\-D\-C device-\/to-\/host notification I\-N endpoint. \hypertarget{_l_u_f_a_descriptors_8h_a5051b28e57390b0072358e2dc602083e}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R}} +\index{C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R}]{\setlength{\rightskip}{0pt plus 5cm}\#define C\-D\-C\-\_\-\-R\-X\-\_\-\-E\-P\-A\-D\-D\-R~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-O\-U\-T $|$ 4)}}\label{_l_u_f_a_descriptors_8h_a5051b28e57390b0072358e2dc602083e} +Endpoint address of the C\-D\-C host-\/to-\/device data O\-U\-T endpoint. \hypertarget{_l_u_f_a_descriptors_8h_a2114400269fd643e0e3b597df6a8930d}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R}} +\index{C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R@{C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R}]{\setlength{\rightskip}{0pt plus 5cm}\#define C\-D\-C\-\_\-\-T\-X\-\_\-\-E\-P\-A\-D\-D\-R~(E\-N\-D\-P\-O\-I\-N\-T\-\_\-\-D\-I\-R\-\_\-\-I\-N $|$ 3)}}\label{_l_u_f_a_descriptors_8h_a2114400269fd643e0e3b597df6a8930d} +Endpoint address of the C\-D\-C device-\/to-\/host data I\-N endpoint. \hypertarget{_l_u_f_a_descriptors_8h_aef7fa1919196a302fd0f8b1079e008be}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E@{C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E}} +\index{C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E@{C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E}]{\setlength{\rightskip}{0pt plus 5cm}\#define C\-D\-C\-\_\-\-T\-X\-R\-X\-\_\-\-E\-P\-S\-I\-Z\-E~16}}\label{_l_u_f_a_descriptors_8h_aef7fa1919196a302fd0f8b1079e008be} +Size in bytes of the C\-D\-C data I\-N and O\-U\-T endpoints. + +\subsection{Function Documentation} +\hypertarget{_l_u_f_a_descriptors_8h_a205665735698917df77439b51d372e64}{\index{L\-U\-F\-A\-Descriptors.\-h@{L\-U\-F\-A\-Descriptors.\-h}!C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor@{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}} +\index{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor@{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}!LUFADescriptors.h@{L\-U\-F\-A\-Descriptors.\-h}} +\subsubsection[{C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t C\-A\-L\-L\-B\-A\-C\-K\-\_\-\-U\-S\-B\-\_\-\-Get\-Descriptor ( +\begin{DoxyParamCaption} +\item[{const uint16\-\_\-t}]{w\-Value, } +\item[{const uint8\-\_\-t}]{w\-Index, } +\item[{const void $\ast$$\ast$const}]{Descriptor\-Address} +\end{DoxyParamCaption} +)}}\label{_l_u_f_a_descriptors_8h_a205665735698917df77439b51d372e64} +This function is called by the library when in device mode, and must be overridden (see library \char`\"{}\-U\-S\-B Descriptors\char`\"{} documentation) by the application code so that the address and size of a requested descriptor can be given to the U\-S\-B library. When the device receives a Get Descriptor request on the control endpoint, this function is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the U\-S\-B host. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_logging_8txt.tex b/Doc/Doxygen/latex/_logging_8txt.tex new file mode 100644 index 00000000..5bc74178 --- /dev/null +++ b/Doc/Doxygen/latex/_logging_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_logging_8txt}{\section{Doxygen\-Pages/\-Logging.txt File Reference} +\label{_logging_8txt}\index{Doxygen\-Pages/\-Logging.\-txt@{Doxygen\-Pages/\-Logging.\-txt}} +} diff --git a/Doc/Doxygen/latex/_main_page_8txt.tex b/Doc/Doxygen/latex/_main_page_8txt.tex new file mode 100644 index 00000000..81b70341 --- /dev/null +++ b/Doc/Doxygen/latex/_main_page_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_main_page_8txt}{\section{Doxygen\-Pages/\-Main\-Page.txt File Reference} +\label{_main_page_8txt}\index{Doxygen\-Pages/\-Main\-Page.\-txt@{Doxygen\-Pages/\-Main\-Page.\-txt}} +} diff --git a/Doc/Doxygen/latex/_page__command_line.tex b/Doc/Doxygen/latex/_page__command_line.tex new file mode 100644 index 00000000..320b893a --- /dev/null +++ b/Doc/Doxygen/latex/_page__command_line.tex @@ -0,0 +1,78 @@ +The Chameleon-\/\-Mini enumerates as a C\-D\-C-\/\-A\-C\-M virtual serial interface. For a high level of compatibility to be both interfaced by a human as well as a user application, it supports a text-\/based command line, which can be accessed by using simple terminal software like hyper-\/terminal or teraterm. The serial settings, as in baudrate, stopp and parity bits are ignored on the Chameleon side. Note that there is no echo of entered characters at the Chameleon. + +\section*{Command structure } + +Each of the following commands can result into 3 actions, depending on the character that is appended to it. +\begin{DoxyItemize} +\item {\ttfamily $<$C\-O\-M\-M\-A\-N\-D$>$?}\-: Indicates a request that will always return an information +\item {\ttfamily $<$C\-O\-M\-M\-A\-N\-D$>$=$<$V\-A\-L\-U\-E$>$}\-: Indicates to set a value on the Chameleon +\item {\ttfamily $<$C\-O\-M\-M\-A\-N\-D$>$}\-: Indicates to execute a procedure on the Chameleon with an optional response +\end{DoxyItemize} + +Note that some commands only support a subset of these 3 actions. + +In order to perform the desired command action the command has to be suffixed with a carriage return (C\-R, 0\-D hexadecimal). In order to be more user-\/friendly when interfacing the Chameleon with a serial terminal, support for the backspace (08 hexadecimal) and escape (1\-B hexadecimal) key have been added. Any other control character as defined in the A\-S\-C\-I\-I character set is ignored. Furthermore the Chameleon does not distinguish between uppercase and lowercase. + +\section*{Supported Commands } + +The following list shows the supported commands and how they are used. \begin{TabularC}{2} +\hline +\rowcolor{lightgray}{\bf Command }&{\bf Description }\\\cline{1-2} +{\ttfamily V\-E\-R\-S\-I\-O\-N?} &Requests the version of the Chameleon \\\cline{1-2} +{\ttfamily R\-E\-S\-E\-T} &Resets the Chameleon \\\cline{1-2} +{\ttfamily U\-P\-G\-R\-A\-D\-E} &Sets the Chameleon into firmware upgrade mode (D\-F\-U) \\\cline{1-2} +{\ttfamily C\-O\-N\-F\-I\-G} &Returns a comma-\/separated list of all supported configurations \\\cline{1-2} +{\ttfamily C\-O\-N\-F\-I\-G?} &Returns the currently used configuration \\\cline{1-2} +{\ttfamily C\-O\-N\-F\-I\-G=$<$N\-A\-M\-E$>$} &Sets the current configuration to {\ttfamily $<$N\-A\-M\-E$>$} (See Page\-\_\-\-Configurations) \\\cline{1-2} +{\ttfamily U\-I\-D\-S\-I\-Z\-E?} &Returns the size of the current configuration's U\-I\-D \\\cline{1-2} +{\ttfamily U\-I\-D?} &Returns the currently set U\-I\-D \\\cline{1-2} +{\ttfamily U\-I\-D=$<$U\-I\-D$>$} &Sets a new U\-I\-D to be used in hexadecimal notation \\\cline{1-2} +{\ttfamily R\-E\-A\-D\-O\-N\-L\-Y?} &Returns the current state of the read-\/only mode \\\cline{1-2} +{\ttfamily R\-E\-A\-D\-O\-N\-L\-Y=\mbox{[}0;1\mbox{]}} &Activates or deactivates the read-\/only mode (Any writing to the memory is silently ignored) \\\cline{1-2} +{\ttfamily M\-E\-M\-S\-I\-Z\-E?} &Returns the memory size of the current configuration \\\cline{1-2} +{\ttfamily U\-P\-L\-O\-A\-D} &Waits for an X\-Modem connection to be established in order to upload a memory dump upto the memory size \\\cline{1-2} +{\ttfamily D\-O\-W\-N\-L\-O\-A\-D} &Waits for an X\-Modem connection to be established in order to download a memory dump with exactly the memory size \\\cline{1-2} +{\ttfamily B\-U\-T\-T\-O\-N} &Returns a comma-\/separated list of supported button press actions for the button \\\cline{1-2} +{\ttfamily B\-U\-T\-T\-O\-N?} &Returns the currently set button press action for B\-U\-T\-T\-O\-N0 \\\cline{1-2} +{\ttfamily B\-U\-T\-T\-O\-N=$<$N\-A\-M\-E$>$} &Sets the current button press action for B\-U\-T\-T\-O\-N0 \\\cline{1-2} +{\ttfamily S\-E\-T\-T\-I\-N\-G?} &Returns the currently activated setting of the chameleon-\/mini \\\cline{1-2} +{\ttfamily S\-E\-T\-T\-I\-N\-G=$<$N\-U\-M\-B\-E\-R$>$} &Sets the active setting of the chameleon-\/mini \\\cline{1-2} +{\ttfamily C\-L\-E\-A\-R} &Clears the entire memory of the currently activated setting \\\cline{1-2} +\end{TabularC} +\section*{Responses } + +Subsequent to A\-N\-Y send command, the Chameleon responds with a status number and status message, separated by a colon and terminated with a carriage return and line feed (C\-R+\-L\-F, 0\-D+0\-A hexadecimal). Status numbers are of a 3 digit decimal format with the first digit showing the severity of the answer. Status numbers beginning with a '1' denote an informational item and those beginning with a '2' denote an error. \begin{TabularC}{2} +\hline +\rowcolor{lightgray}{\bf Response }&{\bf Description }\\\cline{1-2} +{\ttfamily 100\-:O\-K} &The command executed successfully \\\cline{1-2} +{\ttfamily 101\-:O\-K W\-I\-T\-H T\-E\-X\-T} &The command executed successfully and this answer is appended with an additional line of information, terminated with C\-R+\-L\-F \\\cline{1-2} +{\ttfamily 110\-:W\-A\-I\-T\-I\-N\-G F\-O\-R X\-M\-O\-D\-E\-M} &The Chameleon is waiting for an X\-M\-O\-D\-E\-M connection to establish \\\cline{1-2} +{\ttfamily 200\-:U\-N\-K\-N\-O\-W\-N C\-O\-M\-M\-A\-N\-D} &This command is unknown to the Chameleon \\\cline{1-2} +{\ttfamily 201\-:I\-N\-V\-A\-L\-I\-D C\-O\-M\-M\-A\-N\-D U\-S\-A\-G\-E} &This action is not supported by this command \\\cline{1-2} +{\ttfamily 202\-:I\-N\-V\-A\-L\-I\-D P\-A\-R\-A\-M} &The format or value of the given parameter value is invalid \\\cline{1-2} +\end{TabularC} +\section*{Accessing the command-\/line using a terminal software } + +In order to have quick access to the Chameleon's command-\/line without using any complicated software, we suggest using the Tera\-Term terminal emulation software available for windows based operating systems. + +\subsection*{Connecting and setting up } + +For establishing a connection to the Chameleon's command line, select File -\/$>$ New Connection, choose the virtual serial port of the Chameleon and hit the \char`\"{}\-O\-K\char`\"{} button. Tera\-Term now tries to open the serial port and should succeed without any error. + +For easier use of the command-\/line using a terminal software the local-\/echo functionality should be activated, to be able to see what is typed into the chameleon. When using Tera\-Term, this can be achieved by selecting Setup -\/$>$ Terminal and check \char`\"{}\-Local Echo\char`\"{}. + +\subsection*{Uploading and Downloading dump files } + +In some configurations of the Chameleon, it is necessary to upload a card dump before it can be accessed by a reader. For doing so, the relatively simple and widely known X\-M\-O\-D\-E\-M protocol is used. + +To upload a dump file using Tera\-Term, follow these steps. +\begin{DoxyEnumerate} +\item Enter {\ttfamily U\-P\-L\-O\-A\-D} and wait for the {\ttfamily 110\-:W\-A\-I\-T\-I\-N\-G F\-O\-R X\-M\-O\-D\-E\-M} response +\item Select File -\/$>$ Transfer -\/$>$ X\-M\-O\-D\-E\-M -\/$>$ Send +\item In the dialog choose the binary dumpfile to be uploaded and make sure the option \char`\"{}\-Checksum\char`\"{} is checked in the lower left corner +\item Hitting the \char`\"{}\-Open\char`\"{} button will start the transfer. If no error is given to the user, the file has been uploaded sucessfully. +\end{DoxyEnumerate} + +To download the Chameleon's memory again, follow the instructions above except for using {\ttfamily D\-O\-W\-N\-L\-O\-A\-D} instead of {\ttfamily U\-P\-L\-O\-A\-D} and the Receive function of Tera\-Term + +Note that there is a 10 second timeout after entering {\ttfamily U\-P\-L\-O\-A\-D} respectively {\ttfamily D\-O\-W\-N\-L\-O\-A\-D} after which the standard command-\/line is activated again. So try again if the timeout is already over when the X\-M\-O\-D\-E\-M transfer is about to start. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_page__configurations.tex b/Doc/Doxygen/latex/_page__configurations.tex new file mode 100644 index 00000000..a34bcd39 --- /dev/null +++ b/Doc/Doxygen/latex/_page__configurations.tex @@ -0,0 +1,21 @@ +The basic idea of the Chameleon-\/\-Mini was to integrate so-\/called configurations to define the device's behaviour. You can choose the active configuration via the command-\/line using the {\ttfamily C\-O\-N\-F\-I\-G} command (See \hyperlink{Page_CommandLine}{The chameleon command line}). + +Below is a list of the configurations with a brief description of what it is and how it works. In configurations where an actual card is simulated, the card memory has to be uploaded to the Chameleon before accessing it by a reader. This is done using the X-\/\-M\-O\-D\-E\-M protocol on the command-\/line (See \hyperlink{Page_CommandLine}{The chameleon command line}). + +\section*{Configurations } + +\subsection*{{\ttfamily N\-O\-N\-E} } + +The Chameleon's R\-F interface is not activated and it behaves entirely passive. + +\subsection*{{\ttfamily M\-F\-\_\-\-U\-L\-T\-R\-A\-L\-I\-G\-H\-T} / {\ttfamily M\-F\-\_\-\-C\-L\-A\-S\-S\-I\-C\-\_\-1\-K} / {\ttfamily M\-F\-\_\-\-C\-L\-A\-S\-S\-I\-C\-\_\-4\-K} } + +The Chameleon behaves like a Mifare Ultralight or Classic (with 1\-K or 4\-K E\-E\-P\-R\-O\-M). + +The memory layout of these configurations is as shown in the datasheets from N\-X\-P and thus fully compatible with the dumpfiles from libnfc. + +\subsection*{{\ttfamily I\-S\-O14443\-A\-\_\-\-S\-N\-I\-F\-F} / {\ttfamily I\-S\-O15693\-\_\-\-S\-N\-I\-F\-F} } + +These are sniffing configurations, where no answers to any requests from a reader are done. Thus the Chameleon behaves completely passive, which is useful if a second card is present in the reader field. Then this configuration can be used in conjunction with one of the logging modes (See \hyperlink{Page_Logging}{Logging capabilities}) to sniff for data, e.\-g. the U\-I\-D that is sent from the reader to the secondary card. + +Note that especially with the I\-S\-O14443\-A sniffing mode, it may happen that the load modulation of the secondary card trips the codec and thus logs some garbled data. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_page__firmware_upgrade.tex b/Doc/Doxygen/latex/_page__firmware_upgrade.tex new file mode 100644 index 00000000..01521a1e --- /dev/null +++ b/Doc/Doxygen/latex/_page__firmware_upgrade.tex @@ -0,0 +1,9 @@ +It is possible to upgrade the Firmware using the Atmel D\-F\-U Protocol as defined in application note A\-V\-R1916. With this possible, there is no need to use any other external programming hardware to upgrade the firmware. + +The Atmel D\-F\-U protocol is supported by Atmel's F\-L\-I\-P software, which also contains {\ttfamily batchisp} and the open source software {\ttfamily dfu-\/programmer}. In order to flash a new firmware, the device has to be put into D\-F\-U mode. To do this, you can either use the command-\/line by sending the corresponding command or press the button on the device while powering it up. + +Once the device is in D\-F\-U mode, it enumerates as an A\-Txmega\-X\-Y\-Z U\-S\-B device and can now be accessed using the above mentioned software tools for erasing, programming and verifying a new firmware H\-E\-X file. + +Depending on what tool you are using for the D\-F\-U firmware upgrade, you may have to install the corresponding driver. + +Note that this procedure can easily be implemented in a command-\/line script, diminishing the need for user interaction and speeding up the process. The \char`\"{}make dfu-\/batchisp\char`\"{} or \char`\"{}make dfu-\/prog\char`\"{} command can be used to program the device using batchisp or dfu-\/programmer. Note that in both cases, the directory of the tools executables have to exist in the P\-A\-T\-H environment variable. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_page__getting_started.tex b/Doc/Doxygen/latex/_page__getting_started.tex new file mode 100644 index 00000000..7c49c7f4 --- /dev/null +++ b/Doc/Doxygen/latex/_page__getting_started.tex @@ -0,0 +1,15 @@ +The first thing you should do is to program the fuse bits and the bootloader to the Chameleon-\/\-Mini. Use your preferred tool to set the fuse bits as follows\-: +\begin{DoxyItemize} +\item F\-U\-S\-E1\-: 0x00 +\item F\-U\-S\-E2\-: 0x\-B\-E +\item F\-U\-S\-E4\-: 0x\-F\-F +\item F\-U\-S\-E5\-: 0x\-E8 +\end{DoxyItemize} + +Next, program the appropriate bootloader from the Firmware/\-Bootloader directory into the chip. The A\-Txmega chip now automatically enumerates with its D\-F\-U bootloader. Now you can use Atmel's F\-L\-I\-P software or the open source dfu-\/programmer to program the Chameleon-\/\-Mini.\-hex/.eep into the F\-L\-A\-S\-H and E\-E\-P\-R\-O\-M using the bootloader. For this you should follow the instructions of the particular D\-F\-U tool. For windows machines, there is an example batch file in the Firmware/\-Chameleon-\/\-Mini directory. + +Once you have got the Chameleon up and running, it should enumerate as the L\-U\-F\-A C\-D\-C device. On windows, you should use the supplied L\-U\-F\-A Virtual\-Serial.\-inf in the Drivers folder. When the installation is successful, a new C\-O\-M port or /dev/tty\-S shows up on your system. + +This serial port is your means of controlling the Chameleon-\/\-Mini from any computer either using a simple terminal emulator, like Tera\-Term or your self-\/crafted scripts and applications. + +More info on how to use the serial interface can be found here\-: \hyperlink{Page_CommandLine}{The chameleon command line} \ No newline at end of file diff --git a/Doc/Doxygen/latex/_page__logging.tex b/Doc/Doxygen/latex/_page__logging.tex new file mode 100644 index 00000000..2e372608 --- /dev/null +++ b/Doc/Doxygen/latex/_page__logging.tex @@ -0,0 +1,21 @@ +With the implemented logging mechanisms it is possible to trace an access to the Chameleon-\/\-Mini by a reader device. + +Logging is either done via the internal R\-A\-M, where the log can be downloaded from via the terminal or using the terminal line directly. Note that in case of using the internal R\-A\-M for logging the information, the data is only stored until the Chameleon-\/\-Mini loses power. If the memory is full, the logging is disabled automatically. + +The log format is very simple. Every log entry consists of a 1 byte entry identifier, a 1 byte length identifier and an arbitrary sized chunk of binary data with the length given in the byte before. + +\begin{TabularC}{6} +\hline +\rowcolor{lightgray}{\bf Byte 0 }&{\bf Byte 1 }&{\bf Byte 2 }&{\bf Byte 3 }&{\bf ... }&{\bf Byte Length+1 }\\\cline{1-6} +Entry\-Id &Length &Data &Data &Data &Data \\\cline{1-6} +\end{TabularC} +The available Entry Ids are as follows\-: \begin{TabularC}{2} +\hline +\rowcolor{lightgray}{\bf Entry\-Id (Hex) }&{\bf Description }\\\cline{1-2} +20 &Received data \\\cline{1-2} +21 &Send data \\\cline{1-2} +30 &Application reset \\\cline{1-2} +\end{TabularC} +For getting or setting the logging mode, the {\ttfamily L\-O\-G\-M\-O\-D\-E?} respectively {\ttfamily L\-O\-G\-M\-O\-D\-E=$<$M\-O\-D\-E$>$} command can be used on the terminal. For a list of possible logging modes enter {\ttfamily L\-O\-G\-M\-O\-D\-E}. + +In order to get the remaining bytes of the logging memory, the {\ttfamily L\-O\-G\-M\-E\-M?} command is to be used. Using {\ttfamily L\-O\-G\-M\-E\-M=$<$C\-M\-D$>$} it is possible to execute commands on the logging memory, like clearing or downloading it via X\-M\-O\-D\-E\-M. To get a list of the available commands, enter {\ttfamily L\-O\-G\-M\-E\-M}. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_page__uploading_downloading.tex b/Doc/Doxygen/latex/_page__uploading_downloading.tex new file mode 100644 index 00000000..59248733 --- /dev/null +++ b/Doc/Doxygen/latex/_page__uploading_downloading.tex @@ -0,0 +1,9 @@ +In order to be able to emulate different card contents, one can upload or download the memory used for emulation. + +The layout of the memory dump depends on the chosen configuration and is usually the same as the memory layout of the currently chosen card-\/emulation. The size of the memory dump also depends on the currently chosen configuration and can be requested with a specific command on the command-\/line. + +In order to upload or download a memory dump, the user has to send the corresponding command on the command-\/line first and the Chameleon responds with a status message indicating that it is waiting for an X-\/\-M\-O\-D\-E\-M connection. Depending on whether upload or download is chosen, the Chameleon then waits for 10 seconds to initiate an X-\/\-M\-O\-D\-E\-M receive or send connection. + +When waiting for a receiving X-\/\-M\-O\-D\-E\-M connection, the X-\/\-M\-O\-D\-E\-M N\-A\-K byte is sent upto 20 times with a delay of 500ms in order to establish a standard 128 byte frame-\/size X-\/\-M\-O\-D\-E\-M connection with the simple checksum scheme. Within this time, the user has to get his X-\/\-M\-O\-D\-E\-M client ready and choose the binary file to be uploaded into the memory. + +In case of waiting for an X-\/\-M\-O\-D\-E\-M send connection to establish, a wait time of 10 seconds is performed to receive the X-\/\-M\-O\-D\-E\-M N\-A\-K byte. Within this time, the user has to start the X-\/\-M\-O\-D\-E\-M receiver and set it to the standard 128 byte frame using the simple checksum scheme in order to receive the binary memory dump. \ No newline at end of file diff --git a/Doc/Doxygen/latex/_uploading_downloading_8txt.tex b/Doc/Doxygen/latex/_uploading_downloading_8txt.tex new file mode 100644 index 00000000..b82fb307 --- /dev/null +++ b/Doc/Doxygen/latex/_uploading_downloading_8txt.tex @@ -0,0 +1,3 @@ +\hypertarget{_uploading_downloading_8txt}{\section{Doxygen\-Pages/\-Uploading\-Downloading.txt File Reference} +\label{_uploading_downloading_8txt}\index{Doxygen\-Pages/\-Uploading\-Downloading.\-txt@{Doxygen\-Pages/\-Uploading\-Downloading.\-txt}} +} diff --git a/Doc/Doxygen/latex/annotated.tex b/Doc/Doxygen/latex/annotated.tex new file mode 100644 index 00000000..567666bd --- /dev/null +++ b/Doc/Doxygen/latex/annotated.tex @@ -0,0 +1,4 @@ +\section{Class List} +Here are the classes, structs, unions and interfaces with brief descriptions\-:\begin{DoxyCompactList} +\item\contentsline{section}{\hyperlink{struct_u_s_b___descriptor___configuration__t}{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t} }{\pageref{struct_u_s_b___descriptor___configuration__t}}{} +\end{DoxyCompactList} diff --git a/Doc/Doxygen/latex/dir_5de29d499bb29a41092979d00d22c134.tex b/Doc/Doxygen/latex/dir_5de29d499bb29a41092979d00d22c134.tex new file mode 100644 index 00000000..66382daa --- /dev/null +++ b/Doc/Doxygen/latex/dir_5de29d499bb29a41092979d00d22c134.tex @@ -0,0 +1,20 @@ +\hypertarget{dir_5de29d499bb29a41092979d00d22c134}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application Directory Reference} +\label{dir_5de29d499bb29a41092979d00d22c134}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application Directory Reference@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application Directory Reference}} +} +\subsection*{Files} +\begin{DoxyCompactItemize} +\item +file {\bfseries Application.\-h} +\item +file {\bfseries Crypto1.\-c} +\item +file {\bfseries Crypto1.\-h} +\item +file {\bfseries I\-S\-O14443-\/3\-A.\-c} +\item +file {\bfseries I\-S\-O14443-\/3\-A.\-h} +\item +file {\bfseries Mifare\-Classic.\-c} +\item +file {\bfseries Mifare\-Classic.\-h} +\end{DoxyCompactItemize} diff --git a/Doc/Doxygen/latex/dir_74b6a3b63f61c160c0f14b7a283a4c9b.tex b/Doc/Doxygen/latex/dir_74b6a3b63f61c160c0f14b7a283a4c9b.tex new file mode 100644 index 00000000..a1f0a6c2 --- /dev/null +++ b/Doc/Doxygen/latex/dir_74b6a3b63f61c160c0f14b7a283a4c9b.tex @@ -0,0 +1,8 @@ +\hypertarget{dir_74b6a3b63f61c160c0f14b7a283a4c9b}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware Directory Reference} +\label{dir_74b6a3b63f61c160c0f14b7a283a4c9b}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware Directory Reference@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware Directory Reference}} +} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\item +directory \hyperlink{dir_8465ec698d237f801ae9966d4551fcfa}{Chameleon-\/\-Mini} +\end{DoxyCompactItemize} diff --git a/Doc/Doxygen/latex/dir_8465ec698d237f801ae9966d4551fcfa.tex b/Doc/Doxygen/latex/dir_8465ec698d237f801ae9966d4551fcfa.tex new file mode 100644 index 00000000..0242bc57 --- /dev/null +++ b/Doc/Doxygen/latex/dir_8465ec698d237f801ae9966d4551fcfa.tex @@ -0,0 +1,59 @@ +\hypertarget{dir_8465ec698d237f801ae9966d4551fcfa}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini Directory Reference} +\label{dir_8465ec698d237f801ae9966d4551fcfa}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini Directory Reference@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini Directory Reference}} +} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\item +directory \hyperlink{dir_5de29d499bb29a41092979d00d22c134}{Application} +\item +directory \hyperlink{dir_f5aab302412c0352d69464400cc5ee44}{Codec} +\item +directory \hyperlink{dir_ddeffaa734f77525428b0dd4068da9cb}{Terminal} +\end{DoxyCompactItemize} +\subsection*{Files} +\begin{DoxyCompactItemize} +\item +file {\bfseries Antenna\-Level.\-h} +\item +file {\bfseries Button.\-c} +\item +file {\bfseries Button.\-h} +\item +file {\bfseries Chameleon-\/\-Mini.\-c} +\item +file {\bfseries Chameleon-\/\-Mini.\-h} +\item +file {\bfseries Common.\-c} +\item +file {\bfseries Common.\-h} +\item +file {\bfseries Configuration.\-c} +\item +file {\bfseries Configuration.\-h} +\item +file {\bfseries L\-E\-D.\-c} +\item +file {\bfseries L\-E\-D.\-h} +\item +file \hyperlink{_l_u_f_a_config_8h}{L\-U\-F\-A\-Config.\-h} +\begin{DoxyCompactList}\small\item\em L\-U\-F\-A Library Configuration Header File. \end{DoxyCompactList}\item +file \hyperlink{_l_u_f_a_descriptors_8c}{L\-U\-F\-A\-Descriptors.\-c} +\item +file \hyperlink{_l_u_f_a_descriptors_8h}{L\-U\-F\-A\-Descriptors.\-h} +\item +file {\bfseries Memory.\-c} +\item +file {\bfseries Memory.\-h} +\item +file {\bfseries Random.\-c} +\item +file {\bfseries Random.\-h} +\item +file {\bfseries Settings.\-c} +\item +file {\bfseries Settings.\-h} +\item +file {\bfseries System.\-c} +\item +file {\bfseries System.\-h} +\end{DoxyCompactItemize} diff --git a/Doc/Doxygen/latex/dir_ddeffaa734f77525428b0dd4068da9cb.tex b/Doc/Doxygen/latex/dir_ddeffaa734f77525428b0dd4068da9cb.tex new file mode 100644 index 00000000..741b3ffc --- /dev/null +++ b/Doc/Doxygen/latex/dir_ddeffaa734f77525428b0dd4068da9cb.tex @@ -0,0 +1,22 @@ +\hypertarget{dir_ddeffaa734f77525428b0dd4068da9cb}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal Directory Reference} +\label{dir_ddeffaa734f77525428b0dd4068da9cb}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal Directory Reference@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal Directory Reference}} +} +\subsection*{Files} +\begin{DoxyCompactItemize} +\item +file {\bfseries Command\-Line.\-c} +\item +file {\bfseries Command\-Line.\-h} +\item +file {\bfseries Commands.\-c} +\item +file {\bfseries Commands.\-h} +\item +file {\bfseries Terminal.\-c} +\item +file {\bfseries Terminal.\-h} +\item +file {\bfseries X\-Modem.\-c} +\item +file {\bfseries X\-Modem.\-h} +\end{DoxyCompactItemize} diff --git a/Doc/Doxygen/latex/dir_f5aab302412c0352d69464400cc5ee44.tex b/Doc/Doxygen/latex/dir_f5aab302412c0352d69464400cc5ee44.tex new file mode 100644 index 00000000..d65f6e1c --- /dev/null +++ b/Doc/Doxygen/latex/dir_f5aab302412c0352d69464400cc5ee44.tex @@ -0,0 +1,14 @@ +\hypertarget{dir_f5aab302412c0352d69464400cc5ee44}{\section{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Codec Directory Reference} +\label{dir_f5aab302412c0352d69464400cc5ee44}\index{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Codec Directory Reference@{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Codec Directory Reference}} +} +\subsection*{Files} +\begin{DoxyCompactItemize} +\item +file {\bfseries Codec.\-c} +\item +file {\bfseries Codec.\-h} +\item +file {\bfseries I\-S\-O14443-\/2\-A.\-c} +\item +file {\bfseries I\-S\-O14443-\/2\-A.\-h} +\end{DoxyCompactItemize} diff --git a/Doc/Doxygen/latex/doxygen.sty b/Doc/Doxygen/latex/doxygen.sty new file mode 100644 index 00000000..199abf8d --- /dev/null +++ b/Doc/Doxygen/latex/doxygen.sty @@ -0,0 +1,464 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} + +% Packages used by this style file +\RequirePackage{alltt} +\RequirePackage{array} +\RequirePackage{calc} +\RequirePackage{float} +\RequirePackage{ifthen} +\RequirePackage{verbatim} +\RequirePackage[table]{xcolor} +\RequirePackage{xtab} + +%---------- Internal commands used in this style file ---------------- + +\newcommand{\ensurespace}[1]{% + \begingroup% + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@% + \penalty -100\vskip\z@\@plus -\dimen@% + \vskip\dimen@% + \penalty 9999% + \vskip -\dimen@% + \vskip\z@skip% hide the previous |\vskip| from |\addvspace| + \endgroup% +} + +\newcommand{\DoxyLabelFont}{} +\newcommand{\entrylabel}[1]{% + {% + \parbox[b]{\labelwidth-4pt}{% + \makebox[0pt][l]{\DoxyLabelFont#1}% + \vspace{1.5\baselineskip}% + }% + }% +} + +\newenvironment{DoxyDesc}[1]{% + \ensurespace{4\baselineskip}% + \begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +\newsavebox{\xrefbox} +\newlength{\xreflength} +\newcommand{\xreflabel}[1]{% + \sbox{\xrefbox}{#1}% + \setlength{\xreflength}{\wd\xrefbox}% + \ifthenelse{\xreflength>\labelwidth}{% + \begin{minipage}{\textwidth}% + \setlength{\parindent}{0pt}% + \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}% + \end{minipage}% + }{% + \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}% + }% +} + +%---------- Commands used by doxygen LaTeX output generator ---------- + +% Used by
 ... 
+\newenvironment{DoxyPre}{% + \small% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} + +% Used by @code ... @endcode +\newenvironment{DoxyCode}{% + \par% + \scriptsize% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} + +% Used by @example, @include, @includelineno and @dontinclude +\newenvironment{DoxyCodeInclude}{% + \DoxyCode% +}{% + \endDoxyCode% +} + +% Used by @verbatim ... @endverbatim +\newenvironment{DoxyVerb}{% + \footnotesize% + \verbatim% +}{% + \endverbatim% + \normalsize% +} + +% Used by @verbinclude +\newenvironment{DoxyVerbInclude}{% + \DoxyVerb% +}{% + \endDoxyVerb% +} + +% Used by numbered lists (using '-#' or
    ...
) +\newenvironment{DoxyEnumerate}{% + \enumerate% +}{% + \endenumerate% +} + +% Used by bullet lists (using '-', @li, @arg, or
    ...
) +\newenvironment{DoxyItemize}{% + \itemize% +}{% + \enditemize% +} + +% Used by description lists (using
...
) +\newenvironment{DoxyDescription}{% + \description% +}{% + \enddescription% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if caption is specified) +\newenvironment{DoxyImage}{% + \begin{figure}[H]% + \begin{center}% +}{% + \end{center}% + \end{figure}% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if no caption is specified) +\newenvironment{DoxyImageNoCaption}{% +}{% +} + +% Used by @attention +\newenvironment{DoxyAttention}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @author and @authors +\newenvironment{DoxyAuthor}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @date +\newenvironment{DoxyDate}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @invariant +\newenvironment{DoxyInvariant}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @note +\newenvironment{DoxyNote}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @post +\newenvironment{DoxyPostcond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @pre +\newenvironment{DoxyPrecond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @copyright +\newenvironment{DoxyCopyright}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @remark +\newenvironment{DoxyRemark}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @return and @returns +\newenvironment{DoxyReturn}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @since +\newenvironment{DoxySince}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @see +\newenvironment{DoxySeeAlso}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @version +\newenvironment{DoxyVersion}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @warning +\newenvironment{DoxyWarning}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @internal +\newenvironment{DoxyInternal}[1]{% + \paragraph*{#1}% +}{% +} + +% Used by @par and @paragraph +\newenvironment{DoxyParagraph}[1]{% + \begin{list}{}{% + \settowidth{\labelwidth}{40pt}% + \setlength{\leftmargin}{\labelwidth}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{-4pt}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +% Used by parameter lists +\newenvironment{DoxyParams}[2][]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablefirsthead{}% + \tablehead{}% + \ifthenelse{\equal{#1}{}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.805\textwidth}|}}% + {\ifthenelse{\equal{#1}{1}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\centering}p{0.10\textwidth}|% + >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.678\textwidth}|}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\centering}p{0.10\textwidth}|% + >{\centering\hspace{0pt}}p{0.15\textwidth}|% + >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.501\textwidth}|}}% + }\hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for fields of simple structs +\newenvironment{DoxyFields}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.15\textwidth}|% + p{0.63\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for parameters within a detailed function description +\newenvironment{DoxyParamCaption}{% + \renewcommand{\item}[2][]{##1 {\em ##2}}% +}{% +} + +% Used by return value lists +\newenvironment{DoxyRetVals}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used by exception lists +\newenvironment{DoxyExceptions}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used by template parameter lists +\newenvironment{DoxyTemplParams}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for member lists +\newenvironment{DoxyCompactItemize}{% + \begin{itemize}% + \setlength{\itemsep}{-3pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \setlength{\partopsep}{0pt}% +}{% + \end{itemize}% +} + +% Used for member descriptions +\newenvironment{DoxyCompactList}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + \setlength{\itemsep}{0pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \renewcommand{\makelabel}{\hfill}% + }% +}{% + \end{list}% +} + +% Used for reference lists (@bug, @deprecated, @todo, etc.) +\newenvironment{DoxyRefList}{% + \begin{list}{}{% + \setlength{\labelwidth}{10pt}% + \setlength{\leftmargin}{\labelwidth}% + \addtolength{\leftmargin}{\labelsep}% + \renewcommand{\makelabel}{\xreflabel}% + }% +}{% + \end{list}% +} + +% Used by @bug, @deprecated, @todo, etc. +\newenvironment{DoxyRefDesc}[1]{% + \begin{list}{}{% + \renewcommand\makelabel[1]{\textbf{##1}}% + \settowidth\labelwidth{\makelabel{#1}}% + \setlength\leftmargin{\labelwidth+\labelsep}% + }% +}{% + \end{list}% +} + +% Used by parameter lists and simple sections +\newenvironment{Desc} +{\begin{list}{}{% + \settowidth{\labelwidth}{40pt}% + \setlength{\leftmargin}{\labelwidth}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{-4pt}% + \renewcommand{\makelabel}{\entrylabel}% + } +}{% + \end{list}% +} + +% Used by tables +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}% +\newlength{\tmplength}% +\newenvironment{TabularC}[1]% +{% +\setlength{\tmplength}% + {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)}% + \par\begin{xtabular*}{\linewidth}% + {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|}% +}% +{\end{xtabular*}\par}% + +% Used for member group headers +\newenvironment{Indent}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + }% + \item[]\ignorespaces% +}{% + \unskip% + \end{list}% +} + +% Used when hyperlinks are turned off +\newcommand{\doxyref}[3]{% + \textbf{#1} (\textnormal{#2}\,\pageref{#3})% +} + +% Used for syntax highlighting +\definecolor{comment}{rgb}{0.5,0.0,0.0} +\definecolor{keyword}{rgb}{0.0,0.5,0.0} +\definecolor{keywordtype}{rgb}{0.38,0.25,0.125} +\definecolor{keywordflow}{rgb}{0.88,0.5,0.0} +\definecolor{preprocessor}{rgb}{0.5,0.38,0.125} +\definecolor{stringliteral}{rgb}{0.0,0.125,0.25} +\definecolor{charliteral}{rgb}{0.0,0.5,0.5} +\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0} +\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43} +\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0} +\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0} diff --git a/Doc/Doxygen/latex/files.tex b/Doc/Doxygen/latex/files.tex new file mode 100644 index 00000000..d891f614 --- /dev/null +++ b/Doc/Doxygen/latex/files.tex @@ -0,0 +1,26 @@ +\section{File List} +Here is a list of all documented files with brief descriptions\-:\begin{DoxyCompactList} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Antenna\-Level.\-h} }{\pageref{_antenna_level_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Button.\-h} }{\pageref{_button_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Chameleon-\/\-Mini.\-h} }{\pageref{_chameleon-_mini_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Common.\-h} }{\pageref{_common_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Configuration.\-h} }{\pageref{_configuration_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries L\-E\-D.\-h} }{\pageref{_l_e_d_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\hyperlink{_l_u_f_a_config_8h}{L\-U\-F\-A\-Config.\-h} \\*L\-U\-F\-A Library Configuration Header File }{\pageref{_l_u_f_a_config_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\hyperlink{_l_u_f_a_descriptors_8c}{L\-U\-F\-A\-Descriptors.\-c} }{\pageref{_l_u_f_a_descriptors_8c}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\hyperlink{_l_u_f_a_descriptors_8h}{L\-U\-F\-A\-Descriptors.\-h} }{\pageref{_l_u_f_a_descriptors_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Memory.\-h} }{\pageref{_memory_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Random.\-h} }{\pageref{_random_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries Settings.\-h} }{\pageref{_settings_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/{\bfseries System.\-h} }{\pageref{_system_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application/{\bfseries Application.\-h} }{\pageref{_application_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application/{\bfseries Crypto1.\-h} }{\pageref{_crypto1_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application/{\bfseries I\-S\-O14443-\/3\-A.\-h} }{\pageref{_i_s_o14443-3_a_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Application/{\bfseries Mifare\-Classic.\-h} }{\pageref{_mifare_classic_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Codec/{\bfseries Codec.\-h} }{\pageref{_codec_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Codec/{\bfseries I\-S\-O14443-\/2\-A.\-h} }{\pageref{_i_s_o14443-2_a_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal/{\bfseries Command\-Line.\-h} }{\pageref{_command_line_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal/{\bfseries Commands.\-h} }{\pageref{_commands_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal/{\bfseries Terminal.\-h} }{\pageref{_terminal_8h}}{} +\item\contentsline{section}{C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\-Terminal/{\bfseries X\-Modem.\-h} }{\pageref{_x_modem_8h}}{} +\end{DoxyCompactList} diff --git a/Doc/Doxygen/latex/index.tex b/Doc/Doxygen/latex/index.tex new file mode 100644 index 00000000..266b3d82 --- /dev/null +++ b/Doc/Doxygen/latex/index.tex @@ -0,0 +1,13 @@ +Chameleon is a versatile emulator for I\-S\-O 14443 contactless smartcards. It is meant to be a programmable platform to assess security aspects in R\-F\-I\-D environments and can be used in different attack scenarios like replay or relay attacks and even for emulating an existing smartcard, thus behaving as a perfect clone of a given card. + +The Chameleon Project has been started by the Chair for Embedded Security at the German University in Bochum and has been licensed as open source to let everyone benefit from the work that has been done so far. + +We are always looking forward to any means of contributing or contacting us. + +{\itshape Pages\-:} +\begin{DoxyItemize} +\item \hyperlink{Page_GettingStarted}{Getting Started} +\item \hyperlink{Page_CommandLine}{The chameleon command line} +\item \hyperlink{Page_FirmwareUpgrade}{Device Firmware Upgrade (D\-F\-U)} +\item \hyperlink{Page_UploadingDownloading}{Uploading and Downloading Memory dumps} +\end{DoxyItemize} \ No newline at end of file diff --git a/Doc/Doxygen/latex/make.bat b/Doc/Doxygen/latex/make.bat new file mode 100644 index 00000000..817e9f5e --- /dev/null +++ b/Doc/Doxygen/latex/make.bat @@ -0,0 +1,25 @@ +del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf + +pdflatex refman +echo ---- +makeindex refman.idx +echo ---- +pdflatex refman + +setlocal enabledelayedexpansion +set count=5 +:repeat +set content=X +for /F "tokens=*" %%T in ( 'findstr /C:"Rerun LaTeX" refman.log' ) do set content="%%~T" +if !content! == X for /F "tokens=*" %%T in ( 'findstr /C:"Rerun to get cross-references right" refman.log' ) do set content="%%~T" +if !content! == X goto :skip +set /a count-=1 +if !count! EQU 0 goto :skip + +echo ---- +pdflatex refman +goto :repeat +:skip +endlocal +makeindex refman.idx +pdflatex refman diff --git a/Doc/Doxygen/latex/refman.log b/Doc/Doxygen/latex/refman.log new file mode 100644 index 00000000..2b145751 --- /dev/null +++ b/Doc/Doxygen/latex/refman.log @@ -0,0 +1,122 @@ +This is pdfTeX, Version 3.1415926-2.3-1.40.12 (MiKTeX 2.9) (preloaded format=pdflatex 2012.12.22) 4 OCT 2013 11:18 +entering extended mode +**refman + +("C:\Dokumente und Einstellungen\skuser\Eigene Dateien\Chameleon-Mini\Doc\Doxyg +en\latex\refman.tex" +LaTeX2e <2011/06/27> +Babel and hyphenation patterns for english, afrikaans, ancientgreek, ar +abic, armenian, assamese, basque, bengali, bokmal, bulgarian, catalan, coptic, +croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, ga +lician, german, german-x-2009-06-19, greek, gujarati, hindi, hungarian, iceland +ic, indonesian, interlingua, irish, italian, kannada, kurmanji, lao, latin, lat +vian, lithuanian, malayalam, marathi, mongolian, mongolianlmc, monogreek, ngerm +an, ngerman-x-2009-06-19, nynorsk, oriya, panjabi, pinyin, polish, portuguese, +romanian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, swis +sgerman, tamil, telugu, turkish, turkmen, ukenglish, ukrainian, uppersorbian, u +senglishmax, welsh, loaded. +("C:\Programme\MiKTeX 2.9\tex\latex\base\book.cls" +Document Class: book 2007/10/19 v1.4h Standard LaTeX document class +("C:\Programme\MiKTeX 2.9\tex\latex\base\bk10.clo" +File: bk10.clo 2007/10/19 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@chapter=\count80 +\c@section=\count81 +\c@subsection=\count82 +\c@subsubsection=\count83 +\c@paragraph=\count84 +\c@subparagraph=\count85 +\c@figure=\count86 +\c@table=\count87 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) +("C:\Programme\MiKTeX 2.9\tex\latex\tools\calc.sty" +Package: calc 2007/08/22 v4.3 Infix arithmetic (KKT,FJ) +\calc@Acount=\count88 +\calc@Bcount=\count89 +\calc@Adimen=\dimen103 +\calc@Bdimen=\dimen104 +\calc@Askip=\skip43 +\calc@Bskip=\skip44 +LaTeX Info: Redefining \setlength on input line 76. +LaTeX Info: Redefining \addtolength on input line 77. +\calc@Ccount=\count90 +\calc@Cskip=\skip45 +) +("C:\Dokumente und Einstellungen\skuser\Eigene Dateien\Chameleon-Mini\Doc\Doxyg +en\latex\doxygen.sty" +Package: doxygen + ("C:\Programme\MiKTeX 2.9\tex\latex\base\alltt.sty" +Package: alltt 1997/06/16 v2.0g defines alltt environment +) +("C:\Programme\MiKTeX 2.9\tex\latex\tools\array.sty" +Package: array 2008/09/09 v2.4c Tabular extension package (FMi) +\col@sep=\dimen105 +\extrarowheight=\dimen106 +\NC@list=\toks14 +\extratabsurround=\skip46 +\backup@length=\skip47 +) +("C:\Programme\MiKTeX 2.9\tex\latex\float\float.sty" +Package: float 2001/11/08 v1.3d Float enhancements (AL) +\c@float@type=\count91 +\float@exts=\toks15 +\float@box=\box26 +\@float@everytoks=\toks16 +\@floatcapt=\box27 +) +("C:\Programme\MiKTeX 2.9\tex\latex\base\ifthen.sty" +Package: ifthen 2001/05/26 v1.1c Standard LaTeX ifthen package (DPC) +) +("C:\Programme\MiKTeX 2.9\tex\latex\tools\verbatim.sty" +Package: verbatim 2003/08/22 v1.5q LaTeX2e package for verbatim enhancements +\every@verbatim=\toks17 +\verbatim@line=\toks18 +\verbatim@in@stream=\read1 +) +("C:\Dokumente und Einstellungen\skuser\Anwendungsdaten\MiKTeX\2.9\tex\latex\xc +olor\xcolor.sty" +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) + ("C:\Programme\MiKTeX 2.9\tex\latex\00miktex\color.cfg" +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: pdftex.def on input line 225. + +("C:\Programme\MiKTeX 2.9\tex\latex\pdftex-def\pdftex.def" +File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX + +("C:\Programme\MiKTeX 2.9\tex\generic\oberdiek\infwarerr.sty" +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) +("C:\Programme\MiKTeX 2.9\tex\generic\oberdiek\ltxcmds.sty" +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +) +\Gread@gobject=\count92 +) + +! LaTeX Error: File `colortbl.sty' not found. + +Type X to quit or to proceed, +or enter new name. (Default extension: sty) + +Enter file name: +! Emergency stop. + + +l.261 \long + \def\@secondoffive#1#2#3#4#5{#2} +End of file on the terminal! + + +Here is how much of TeX's memory you used: + 1003 strings out of 494045 + 13251 string characters out of 3149929 + 66639 words of memory out of 3000000 + 4346 multiletter control sequences out of 15000+200000 + 3640 words of font info for 14 fonts, out of 3000000 for 9000 + 715 hyphenation exceptions out of 8191 + 27i,0n,21p,236b,36s stack positions out of 5000i,500n,10000p,200000b,50000s +! ==> Fatal error occurred, no output PDF file produced! diff --git a/Doc/Doxygen/latex/refman.tex b/Doc/Doxygen/latex/refman.tex new file mode 100644 index 00000000..bac0c1c0 --- /dev/null +++ b/Doc/Doxygen/latex/refman.tex @@ -0,0 +1,174 @@ +\documentclass[twoside]{book} + +% Packages required by doxygen +\usepackage{calc} +\usepackage{doxygen} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{makeidx} +\usepackage{multicol} +\usepackage{multirow} +\usepackage{textcomp} +\usepackage[table]{xcolor} + +% Font selection +\usepackage[T1]{fontenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{amssymb} +\usepackage{sectsty} +\renewcommand{\familydefault}{\sfdefault} +\allsectionsfont{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\renewcommand{\DoxyLabelFont}{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} + +% Page & text layout +\usepackage{geometry} +\geometry{% + a4paper,% + top=2.5cm,% + bottom=2.5cm,% + left=2.5cm,% + right=2.5cm% +} +\tolerance=750 +\hfuzz=15pt +\hbadness=750 +\setlength{\emergencystretch}{15pt} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\makeatletter +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@parafont% + }% +} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@subparafont% + }% +} +\makeatother + +% Headers & footers +\usepackage{fancyhdr} +\pagestyle{fancyplain} +\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}} +\fancyhead[CE]{\fancyplain{}{}} +\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}} +\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}} +\fancyhead[CO]{\fancyplain{}{}} +\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} +\fancyfoot[LE]{\fancyplain{}{}} +\fancyfoot[CE]{\fancyplain{}{}} +\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated on Sun Dec 22 2013 16:28:51 for Chameleon-Mini by Doxygen }} +\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated on Sun Dec 22 2013 16:28:51 for Chameleon-Mini by Doxygen }} +\fancyfoot[CO]{\fancyplain{}{}} +\fancyfoot[RO]{\fancyplain{}{}} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\chaptermark}[1]{% + \markboth{#1}{}% +} +\renewcommand{\sectionmark}[1]{% + \markright{\thesection\ #1}% +} + +% Indices & bibliography +\usepackage{natbib} +\usepackage[titles]{tocloft} +\setcounter{tocdepth}{3} +\setcounter{secnumdepth}{5} +\makeindex + +% Hyperlinks (required, but should be loaded last) +\usepackage{ifpdf} +\ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} +\else + \usepackage[ps2pdf,pagebackref=true]{hyperref} +\fi +\hypersetup{% + colorlinks=true,% + linkcolor=blue,% + citecolor=blue,% + unicode% +} + +% Custom commands +\newcommand{\clearemptydoublepage}{% + \newpage{\pagestyle{empty}\cleardoublepage}% +} + + +%===== C O N T E N T S ===== + +\begin{document} + +% Titlepage & ToC +\hypersetup{pageanchor=false} +\pagenumbering{roman} +\begin{titlepage} +\vspace*{7cm} +\begin{center}% +{\Large Chameleon-\/\-Mini }\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.4}\\ +\vspace*{0.5cm} +{\small Sun Dec 22 2013 16:28:51}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} +\hypersetup{pageanchor=true} + +%--- Begin generated contents --- +\chapter{Main Page} +\label{index}\hypertarget{index}{}\input{index} +\chapter{The chameleon command line} +\label{Page_CommandLine} +\hypertarget{Page_CommandLine}{} +\input{_page__command_line} +\chapter{Device Firmware Upgrade (D\-F\-U)} +\label{Page_FirmwareUpgrade} +\hypertarget{Page_FirmwareUpgrade}{} +\input{_page__firmware_upgrade} +\chapter{Getting Started} +\label{Page_GettingStarted} +\hypertarget{Page_GettingStarted}{} +\input{_page__getting_started} +\chapter{Uploading and Downloading Memory dumps} +\label{Page_UploadingDownloading} +\hypertarget{Page_UploadingDownloading}{} +\input{_page__uploading_downloading} +\chapter{Class Index} +\input{annotated} +\chapter{File Index} +\input{files} +\chapter{Class Documentation} +\input{struct_u_s_b___descriptor___configuration__t} +\chapter{File Documentation} +\input{_command_line_8txt} +\input{_d_f_u_8txt} +\input{_getting_started_8txt} +\input{_main_page_8txt} +\input{_uploading_downloading_8txt} +\input{_l_u_f_a_config_8h} +\input{_l_u_f_a_descriptors_8c} +\input{_l_u_f_a_descriptors_8h} +%--- End generated contents --- + +% Index +\newpage +\phantomsection +\addcontentsline{toc}{part}{Index} +\printindex + +\end{document} diff --git a/Doc/Doxygen/latex/struct_u_s_b___descriptor___configuration__t.tex b/Doc/Doxygen/latex/struct_u_s_b___descriptor___configuration__t.tex new file mode 100644 index 00000000..5a0cb00c --- /dev/null +++ b/Doc/Doxygen/latex/struct_u_s_b___descriptor___configuration__t.tex @@ -0,0 +1,15 @@ +\hypertarget{struct_u_s_b___descriptor___configuration__t}{\section{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t Struct Reference} +\label{struct_u_s_b___descriptor___configuration__t}\index{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t@{U\-S\-B\-\_\-\-Descriptor\-\_\-\-Configuration\-\_\-t}} +} + + +{\ttfamily \#include $<$L\-U\-F\-A\-Descriptors.\-h$>$} + + + +\subsection{Detailed Description} +Type define for the device configuration descriptor structure. This must be defined in the application code, as the configuration descriptor contains several sub-\/descriptors which vary between devices, and which describe the device's usage to the host. + +The documentation for this struct was generated from the following file\-:\begin{DoxyCompactItemize} +\item +C\-:/\-Dokumente und Einstellungen/skuser/\-Eigene Dateien/\-Chameleon-\/\-Mini-\/\-Open\-Source/\-Firmware/\-Chameleon-\/\-Mini/\hyperlink{_l_u_f_a_descriptors_8h}{L\-U\-F\-A\-Descriptors.\-h}\end{DoxyCompactItemize} diff --git a/Doc/DoxygenPages/CommandLine.txt b/Doc/DoxygenPages/CommandLine.txt new file mode 100644 index 00000000..bb2a9aa2 --- /dev/null +++ b/Doc/DoxygenPages/CommandLine.txt @@ -0,0 +1,103 @@ +/** @file */ + +/** @page Page_CommandLine The chameleon command line + * The Chameleon-Mini enumerates as a CDC-ACM virtual serial interface. + * For a high level of compatibility to be both interfaced by a human as well as + * a user application, it supports a text-based command line, which can be accessed by using + * simple terminal software like hyper-terminal or teraterm. + * The serial settings, as in baudrate, stopp and parity bits are ignored + * on the Chameleon side. + * Note that there is no echo of entered characters at the Chameleon. + * + * Command structure + * ================= + * + * Each of the following commands can result into 3 actions, + * depending on the character that is appended to it. + * - `?`: Indicates a request that will always return an information + * - `=`: Indicates to set a value on the Chameleon + * - ``: Indicates to execute a procedure on the Chameleon with an optional response + * + * Note that some commands only support a subset of these 3 actions. + * + * In order to perform the desired command action the command has to be + * suffixed with a carriage return (CR, 0D hexadecimal). + * In order to be more user-friendly when interfacing the Chameleon with a + * serial terminal, support for the backspace (08 hexadecimal) and + * escape (1B hexadecimal) key have been added. + * Any other control character as defined in the ASCII character set is ignored. + * Furthermore the Chameleon does not distinguish between uppercase and lowercase. + * + * Supported Commands + * ================== + * + * The following list shows the supported commands and how they are used. + * Command | Description + * --------------------- | ----------- + * `VERSION?` | Requests the version of the Chameleon + * `RESET` | Resets the Chameleon + * `UPGRADE` | Sets the Chameleon into firmware upgrade mode (DFU) + * `CONFIG` | Returns a comma-separated list of all supported configurations + * `CONFIG?` | Returns the currently used configuration + * `CONFIG=` | Sets the current configuration to `` (See @ref Page_Configurations) + * `UIDSIZE?` | Returns the size of the current configuration's UID + * `UID?` | Returns the currently set UID + * `UID=` | Sets a new UID to be used in hexadecimal notation + * `READONLY?` | Returns the current state of the read-only mode + * `READONLY=[0;1]` | Activates or deactivates the read-only mode (Any writing to the memory is silently ignored) + * `MEMSIZE?` | Returns the memory size of the current configuration + * `UPLOAD` | Waits for an XModem connection to be established in order to upload a memory dump upto the memory size + * `DOWNLOAD` | Waits for an XModem connection to be established in order to download a memory dump with exactly the memory size + * `BUTTON` | Returns a comma-separated list of supported button press actions for the button + * `BUTTON?` | Returns the currently set button press action for BUTTON0 + * `BUTTON=` | Sets the current button press action for BUTTON0 + * `SETTING?` | Returns the currently activated setting of the chameleon-mini + * `SETTING=` | Sets the active setting of the chameleon-mini + * `CLEAR` | Clears the entire memory of the currently activated setting + * + * Responses + * ========= + * + * Subsequent to ANY send command, the Chameleon responds with a status number and status message, separated by a colon and terminated with a carriage return and line feed (CR+LF, 0D+0A hexadecimal). Status numbers are of a 3 digit decimal format with the first digit showing the severity of the answer. Status numbers beginning with a '1' denote an informational item and those beginning with a '2' denote an error. + * Response | Description + * ---------------------------- | ----------- + * `100:OK` | The command executed successfully + * `101:OK WITH TEXT` | The command executed successfully and this answer is appended with an additional line of information, terminated with CR+LF + * `110:WAITING FOR XMODEM` | The Chameleon is waiting for an XMODEM connection to establish + * `200:UNKNOWN COMMAND` | This command is unknown to the Chameleon + * `201:INVALID COMMAND USAGE` | This action is not supported by this command + * `202:INVALID PARAM` | The format or value of the given parameter value is invalid + * + * Accessing the command-line using a terminal software + * ==================================================== + * In order to have quick access to the Chameleon's command-line without using any complicated software, + * we suggest using the TeraTerm terminal emulation software available for windows based operating systems. + * + * Connecting and setting up + * ------------------------- + * For establishing a connection to the Chameleon's command line, select File -> New Connection, choose + * the virtual serial port of the Chameleon and hit the "OK" button. TeraTerm now tries to open the serial port + * and should succeed without any error. + * + * For easier use of the command-line using a terminal software the local-echo functionality should be activated, + * to be able to see what is typed into the chameleon. When using TeraTerm, this can be achieved by selecting + * Setup -> Terminal and check "Local Echo". + * + * Uploading and Downloading dump files + * ------------------------------------ + * In some configurations of the Chameleon, it is necessary to upload a card dump before it can be accessed by a reader. + * For doing so, the relatively simple and widely known XMODEM protocol is used. + * + * To upload a dump file using TeraTerm, follow these steps. + * 1. Enter `UPLOAD` and wait for the `110:WAITING FOR XMODEM` response + * 2. Select File -> Transfer -> XMODEM -> Send + * 3. In the dialog choose the binary dumpfile to be uploaded and make sure the option "Checksum" is checked in the lower left corner + * 4. Hitting the "Open" button will start the transfer. If no error is given to the user, the file has been uploaded sucessfully. + * + * To download the Chameleon's memory again, follow the instructions above except for using `DOWNLOAD` instead of `UPLOAD` + * and the Receive function of TeraTerm + * + * Note that there is a 10 second timeout after entering `UPLOAD` respectively `DOWNLOAD` + * after which the standard command-line is activated again. So try again if the timeout is already + * over when the XMODEM transfer is about to start. + */ \ No newline at end of file diff --git a/Doc/DoxygenPages/DFU.txt b/Doc/DoxygenPages/DFU.txt new file mode 100644 index 00000000..bf4f6e35 --- /dev/null +++ b/Doc/DoxygenPages/DFU.txt @@ -0,0 +1,27 @@ +/** @file */ + +/** @page Page_FirmwareUpgrade Device Firmware Upgrade (DFU) + * It is possible to upgrade the Firmware using the Atmel DFU Protocol + * as defined in application note AVR1916. With this possible, there is no need to + * use any other external programming hardware to upgrade the firmware. + * + * The Atmel DFU protocol is supported by Atmel's FLIP software, which also contains + * `batchisp` and the open source software `dfu-programmer`. + * In order to flash a new firmware, the device has to be put into DFU mode. + * To do this, you can either use the command-line by sending the corresponding + * command or press the button on the device while powering it up. + * + * Once the device is in DFU mode, it enumerates as an ATxmegaXYZ USB device and + * can now be accessed using the above mentioned software tools for erasing, + * programming and verifying a new firmware HEX file. + * + * Depending on what tool you are using for the DFU firmware upgrade, + * you may have to install the corresponding driver. + * + * Note that this procedure can easily be implemented in a command-line script, + * diminishing the need for user interaction and speeding up the process. + * The "make dfu-batchisp" or "make dfu-prog" command can be used to program + * the device using batchisp or dfu-programmer. + * Note that in both cases, the directory of the tools executables have to exist + * in the PATH environment variable. + */ diff --git a/Doc/DoxygenPages/GettingStarted.txt b/Doc/DoxygenPages/GettingStarted.txt new file mode 100644 index 00000000..3373176c --- /dev/null +++ b/Doc/DoxygenPages/GettingStarted.txt @@ -0,0 +1,29 @@ +/** @file */ + +/** @page Page_GettingStarted Getting Started + * The first thing you should do is to program the fuse bits and the bootloader + * to the Chameleon-Mini. + * Use your preferred tool to set the fuse bits as follows: + * + * - FUSE1: 0x00 + * - FUSE2: 0xBE + * - FUSE4: 0xFF + * - FUSE5: 0xE8 + * + * Next, program the appropriate bootloader from the Firmware/Bootloader directory into the chip. + * The ATxmega chip now automatically enumerates with its DFU bootloader. + * Now you can use Atmel's FLIP software or the open source dfu-programmer to program the + * Chameleon-Mini.hex/.eep into the FLASH and EEPROM using the bootloader. For this you should + * follow the instructions of the particular DFU tool. + * For windows machines, there is an example batch file in the Firmware/Chameleon-Mini directory. + * + * Once you have got the Chameleon up and running, it should enumerate as the LUFA CDC device. + * On windows, you should use the supplied LUFA VirtualSerial.inf in the Drivers folder. + * When the installation is successful, a new COM port or /dev/ttyS shows up on your system. + * + * This serial port is your means of controlling the Chameleon-Mini from any computer either + * using a simple terminal emulator, like TeraTerm or your self-crafted scripts and applications. + * + * More info on how to use the serial interface can be found here: @ref Page_CommandLine + * + */ \ No newline at end of file diff --git a/Doc/DoxygenPages/MainPage.txt b/Doc/DoxygenPages/MainPage.txt new file mode 100644 index 00000000..bbe161f4 --- /dev/null +++ b/Doc/DoxygenPages/MainPage.txt @@ -0,0 +1,22 @@ +/** @file */ + +/** @mainpage + * Chameleon is a versatile emulator for ISO 14443 contactless smartcards. + * It is meant to be a programmable platform to assess security aspects in + * RFID environments and can be used in different attack scenarios like replay + * or relay attacks and even for emulating an existing smartcard, + * thus behaving as a perfect clone of a given card. + * + * The Chameleon Project has been started by the Chair for Embedded Security + * at the German University in Bochum and has been licensed as open source to + * let everyone benefit from the work that has been done so far. + * + * We are always looking forward to any means of contributing or contacting us. + * + * *Pages:* + * + * - @subpage Page_GettingStarted + * - @subpage Page_CommandLine + * - @subpage Page_FirmwareUpgrade + * - @subpage Page_UploadingDownloading + */ \ No newline at end of file diff --git a/Doc/DoxygenPages/UploadingDownloading.txt b/Doc/DoxygenPages/UploadingDownloading.txt new file mode 100644 index 00000000..284800f5 --- /dev/null +++ b/Doc/DoxygenPages/UploadingDownloading.txt @@ -0,0 +1,28 @@ +/** @file */ + +/** @page Page_UploadingDownloading Uploading and Downloading Memory dumps + * In order to be able to emulate different card contents, one can upload or download + * the memory used for emulation. + * + * The layout of the memory dump depends on the chosen configuration and is usually + * the same as the memory layout of the currently chosen card-emulation. + * The size of the memory dump also depends on the currently chosen configuration + * and can be requested with a specific command on the command-line. + * + * In order to upload or download a memory dump, the user has to send the + * corresponding command on the command-line first and the Chameleon responds + * with a status message indicating that it is waiting for an X-MODEM connection. + * Depending on whether upload or download is chosen, the Chameleon then waits + * for 10 seconds to initiate an X-MODEM receive or send connection. + * + * When waiting for a receiving X-MODEM connection, the X-MODEM NAK byte is sent + * upto 20 times with a delay of 500ms in order to establish + * a standard 128 byte frame-size X-MODEM connection with the simple checksum scheme. + * Within this time, the user has to get his X-MODEM client ready and choose the + * binary file to be uploaded into the memory. + * + * In case of waiting for an X-MODEM send connection to establish, a wait time + * of 10 seconds is performed to receive the X-MODEM NAK byte. Within this time, + * the user has to start the X-MODEM receiver and set it to the standard 128 byte + * frame using the simple checksum scheme in order to receive the binary memory dump. + */ \ No newline at end of file diff --git a/Doc/Fuses.txt b/Doc/Fuses.txt new file mode 100644 index 00000000..51fb2279 --- /dev/null +++ b/Doc/Fuses.txt @@ -0,0 +1,4 @@ +FUSE1: 0x00 +FUSE2: 0xBE +FUSE4: 0xFF +FUSE5: 0xE8 \ No newline at end of file diff --git a/Doc/StartDoxygen.bat b/Doc/StartDoxygen.bat new file mode 100644 index 00000000..a7610321 --- /dev/null +++ b/Doc/StartDoxygen.bat @@ -0,0 +1 @@ +doxygen \ No newline at end of file diff --git a/Drivers/LUFA VirtualSerial.inf b/Drivers/LUFA VirtualSerial.inf new file mode 100644 index 00000000..bfbd6865 --- /dev/null +++ b/Drivers/LUFA VirtualSerial.inf @@ -0,0 +1,63 @@ +;************************************************************ +; Windows USB CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation +;************************************************************ + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +DriverVer=7/1/2012,10.0.0.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 + +[SourceDisksNames] + +[SourceDisksFiles] + +[DestinationDirs] +DefaultDestDir=12 + +[DriverInstall] +Include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=DriverInstall.AddReg + +[DriverInstall.Services] +Include=mdmcpq.inf +AddService=usbser, 0x00000002, LowerFilter_Service_Inst + +[DriverInstall.AddReg] +HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider" + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTx86] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTia64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGNAME="http://www.lufa-lib.org" +DESCRIPTION="LUFA CDC-ACM Virtual Serial Port" \ No newline at end of file diff --git a/Dumps/MifareClassic1K.mfd b/Dumps/MifareClassic1K.mfd new file mode 100644 index 00000000..4e8cd3fe Binary files /dev/null and b/Dumps/MifareClassic1K.mfd differ diff --git a/EAGLE/Chameleon-Mini-RevE-2.brd b/EAGLE/Chameleon-Mini-RevE-2.brd new file mode 100644 index 00000000..c817eb4b Binary files /dev/null and b/EAGLE/Chameleon-Mini-RevE-2.brd differ diff --git a/EAGLE/Chameleon-Mini-RevE-2.sch b/EAGLE/Chameleon-Mini-RevE-2.sch new file mode 100644 index 00000000..ac44ee52 Binary files /dev/null and b/EAGLE/Chameleon-Mini-RevE-2.sch differ diff --git a/EAGLE/Chameleon-Mini-RevE.brd b/EAGLE/Chameleon-Mini-RevE.brd new file mode 100644 index 00000000..846a8cbb Binary files /dev/null and b/EAGLE/Chameleon-Mini-RevE.brd differ diff --git a/EAGLE/Chameleon-Mini-RevE.sch b/EAGLE/Chameleon-Mini-RevE.sch new file mode 100644 index 00000000..f9459c4c Binary files /dev/null and b/EAGLE/Chameleon-Mini-RevE.sch differ diff --git a/Firmware/Atmel DFU Bootloader/ASF-License.txt b/Firmware/Atmel DFU Bootloader/ASF-License.txt new file mode 100644 index 00000000..7e8f30cb --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/ASF-License.txt @@ -0,0 +1,27 @@ + * 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. \ No newline at end of file diff --git a/Firmware/Atmel DFU Bootloader/RevE-atxmega32a4u_104_modified.hex b/Firmware/Atmel DFU Bootloader/RevE-atxmega32a4u_104_modified.hex new file mode 100644 index 00000000..8fd91c3d --- /dev/null +++ b/Firmware/Atmel DFU Bootloader/RevE-atxmega32a4u_104_modified.hex @@ -0,0 +1,251 @@ +:020000020000FC +:1080000000C00091780005FD6AC0F092000608E10A +:10801000009316060FEF0A950023E9F70091080672 +:1080200006FFECC0E0E0F0E0079116910F3F19F475 +:108030001F3F09F4E3C053C03091CF0137FDFCCF9F +:108040003BB72BBFF8012091CA0113E21093CA017C +:108050000A01E8952093CA013BBF08953BB72BBFA7 +:10806000F8012091CA014093CA013DE930933400E0 +:10807000E8952093CA013BBF089520E006D0E9F7B8 +:108080000895259102D0E9F708952D9301501040ED +:10809000202F212B089584E39FE8FC010591149182 +:1080A000FC013296A591B491FC013496259134914E +:1080B000422F432B19F0F901E4DF01C0DEDF069601 +:1080C0001FE88034910748F3089501E70DBF00E2EF +:1080D0000EBFC4E2DAE20E944B400E942E41F092B1 +:1080E000530600910020109101200A3A154511F025 +:1080F0000C940000F0920020F092012000E2009326 +:108100007800F6CFAA84998488847F806E805D8011 +:108110004C80BB81AA8199818881F0E0EC0FFD1F22 +:10812000EF010895BD01D801F90104C021912D93FB +:1081300041505040242F252BC9F7DB010895AA9206 +:108140009A928A927A926A925A924A92BA93AA938D +:108150009A938A930895AF93BF93D80101900D929B +:1081600041505040D9F7BF91AF9108954091CA0155 +:10817000E22FF32F0093CA0104914093CA0108959E +:1081800040E04BBFF80158ED54BF208308954A9555 +:108190001AF0000F111FFBCF08954A951AF016959B +:0681A0000795FBCF0895D6 +:1081F4000C945C450C94944566CF0FBF08954FB71B +:10820400F8941095F0E0E02FE059FF4F008101232E +:108214000083042FF2CFB90198018B0163C361E09D +:1082240078C3B90198018B019FC2CFC262E770E2A3 +:10823400260F371F0C94924068EE70E2F9CFF89441 +:108244000AEA15E5E0E0F0E2008311832091790069 +:10825400216009E739D0FFCF27E402EA35D005D001 +:108264007894C9D303D4FFCFC8CF24E001E42CD041 +:108274002DE126D0009362002CE122D0009363000C +:108284000FB7F894E0E5F0E0108112601083ECDFA2 +:108294000091510001FBE6F721E000E415D0E6E58A +:1082A400F0E00081097F008300E807870BEB008B77 +:1082B400008104600083E0E600810160008308958A +:1082C40030E002E00C94B64010E00C94C04000E0B2 +:1082D4000093EC2053D0009190000093E82000918B +:1082E40091000093E920009192000093EA2000910C +:1082F40093000093EB200091D00101FB16F001E004 +:1083040001C000E0DEC00ED2A6E0B1E20091062179 +:108314000076003289F5109107210C91569707FFDA +:108324000FC0125041F01A9529F526E030E09E96D0 +:108334008D0180D01DC0D49675D5E1F009951DC07E +:108344001A9521F01350B1F419D012C00091EC2009 +:10835400002321F001E211E4929608C020E430E009 +:108364000FE211E267D00CEC11E494960D931C9388 +:1083740001E003C00FE05FD000E061C100C097D10D +:1083840000E006A702E002AB00E004A305A302A3F9 +:1083940003A30895F3DF10E08AD114AB15ABEFE229 +:1083A400F1E230812181203001E0300709F422C05C +:1083B400203003E0300709F444C02130300709F4C9 +:1083C40060C0203004E0300749F4A0D207FDFDCF9F +:1083D40040E200E0FDD277D200E073C023303007E2 +:1083E40021F401E00093EC2008952330364009F491 +:1083F40057C05BC197D135D011F082D018C0ACE121 +:10840400B1E22D913C919D972030304019F403E066 +:1084140012D002C02CD011F400E009C020E038E0F2 +:1084240007D00BE013E494960D931C9301E007C16D +:1084340000E711E239C300931E210AE000932221D0 +:10844400089515D019F025D011F416D02EC109D0F5 +:1084540019F002E812E402C00DEA12E404AB15AB11 +:1084640032C00091ED201091EE200123089501E324 +:1084740011E24DD00023089503E006A70AE002AB01 +:108484000895F5DF19F005D011F4F6DF0EC170D0B0 +:108494001AC0E0EFF0E222A533A520303040089561 +:1084A400EFE2F1E20281002359F40381013118F073 +:1084B40008E0C1DFFAC009D000E0F9D006AB07AB91 +:1084C40002C00093ED2001E00895033041F0023032 +:1084D40031F0043021F0053011F011E001C010E05A +:1084E4001093EE2012E0019FF001E356FF4D6081EE +:1084F400F18106E111E2E62F48E050E00C94AB4034 +:1085040003E000931E2102E000932221CEC0BD01AE +:10851400D8015C91F8010181402FC9D006AB57AB5B +:1085240012961D9130E00C9120E006A017A020A423 +:1085340031A4001511052205330520F008E09DDF64 +:1085440000E007C0041B150B0F5F1F4F00AF11AFF6 +:1085540001E0DB01089576D040AD51AD4AD09A9642 +:1085640051D49B970995FD0120AD31AD61DF66C003 +:1085740023D1A0EFB0E2FD0100AD11AD012B39F420 +:1085840000E018EF00AF11AF80E098E010C0FD01EB +:1085940000AD11AD202F212B59F1183010F4C80172 +:1085A40002C080E098E0081B190B00AF11AFAC01CA +:1085B40020D062A5F3A5E62F099500E711E207C0D4 +:1085C400FD0126A937A92F5F3F4F26AB37AB9C018E +:1085D4000197232BE1F2F80121918F012F3F81F3C1 +:1085E40005E000931E2100E013E4FD0104AB15AB8C +:1085F400B0C326A937A900E711E2089558D026A9E7 +:1086040007A9009370212093712122E030E010DF4C +:108614005ACF18D006A917A940AD51AD202F2F73FA +:10862400622F70E020E731E2260F371F9C96EAD3D1 +:108634009D97099500E0FD0104A305A301E0A9911C +:10864400B9910895BA93AA93A0EFB0E2FD010895F9 +:10865400009108210F770093C304089528D0208D3A +:10866400018D0A9529F00A95A1F00A95B9F01DC06B +:10867400E0ECF0E2228930E072968F01DBDE17D065 +:1086840013D320A131A10217130710F400A311A3DF +:108694001ACFE0ECF0E222813381EFCF222329F4D8 +:1086A40024E030E004EE10E2E9CF00E00895E0EFCA +:1086B400F0E2089537D0FBDF06890F7189F5178939 +:1086C400068907FF14C0112329F0165041F01250F7 +:1086D40041F026C022E030E000E719E206C0BEDF28 +:1086E40020C021E030E002E719E2A4DE17C01550F3 +:1086F40019F0145031F014C00AE213E402A313A3D6 +:108704000DC001E010E0A0E7B9E20D931C93008DC9 +:1087140000937229002311F0DADD03C001E001C0E7 +:1087240000E08DCFBA93AA930895C1DF00E000A3BF +:1087340001A302A303A304A305A3068907FF03C09F +:10874400B3D2012B81F000910621007619F4B2DF37 +:10875400002341F4009106210F71013021F4D3DD8F +:10876400002309F0B0CEA1CFB90161D0208127FD4B +:10877400FDCFECEC208128602083105F98018B01F1 +:1087840059DDECECF1E00081077F98CD15D0C801EC +:10879400A22FB091CA0141D04AD0008107FDFDCF7C +:1087A4000DD09093C1018093C001A093C40105E34F +:1087B40041D0B093CA01CDC20C94A64003E3009308 +:1087C400CA0100E00093C20108950E94A440C801B8 +:1087D400D9012A010DC08D0133D045E08C010E94DE +:1087E400CD4049D08096909600EE400E0FEF501E7B +:1087F400042D052979F0082F0F7129F400E24016A1 +:1088040000E0500640F72D918C01C0DF01960FEF78 +:10881400400EEDCFE6E00C94874009D0008107FDBF +:10882400FDCF008101FF02C006E304D00895EFEC00 +:10883400F1E008950093CA0121E00BEC11E045CD6D +:108844003091CA012091CF0127FDFCCF23E320936F +:10885400CA0120E02093C2012093C1012093C001EA +:10886400F80141918F014093C40123952032B0F364 +:108874003093CA0108958A93DADF108117FDFDCF82 +:1088840010E2019F9EDF1092C1010092C00180910D +:10889400CA0105E322C09A938A93802F9091CA015A +:1088A400BCDF34D007FDFDCF89DF0093C101009305 +:1088B400C0018093C40103950032C8F39093CA01A8 +:1088C4008991999108958A930FEFE5DFB0DF0081D4 +:1088D40007FDFDCF8091CA0100E3ACDF8093CA019C +:1088E40089910895BC01C80111D007FDFDCF042F63 +:1088F400052B51F0FC010491F90100832F5F3F4FD8 +:10890400019641505040F3CFCB0108950091CF011F +:1089140008950E949F402297D9013A01A62E28016A +:10892400912F80E006C02091CF0127FDFCCF45E2C6 +:108934004FD0062D0729F9F19924E8DF07FDFDCF73 +:1089440000E8802EAA2061F0FC01059114910883AF +:10895400198308810F3F1F4F31F09924939403C06A +:108964000FEF08830983062D072979F04816590665 +:1089740029F425D00883062D072939F0FC01319606 +:108984004E165F0611F41BD00983488159818C016E +:1089940020E030E00E941C4002968A9499F69C01E3 +:1089A4003A959920890109F0BECF2091CF0127FD86 +:1089B400FCCF44E2BDCF2296EBE00C9482400FEF53 +:1089C400600E701E01E0400E00E0501E0D910895EF +:1089D40020E030E00C942E4010CC2AE107D0009324 +:1089E400FA042BE103D00093FB04089569DC0F3FE4 +:1089F40009F40FE108950E94A74000E0009360008D +:108A040010E4FDDB23E004E45FDC7BD2006400833C +:108A140001E000936000AFB7F89400E010E028E0B4 +:108A2400029FF001E051FF4D158303950230C0F31E +:108A3400D4DF0091C0040093C00463D200680083B3 +:108A440000810061008380EF90E20496E6EC80836D +:108A54009183E0EC33D10FEF0583E8EC00810160F2 +:108A640000830A2FB9DFE3E00C948A400FB7F8942F +:108A740010E41093CA0410E21093CA04E1ECF4E089 +:108A8400108111601083E9EC108112601083E8EC0E +:108A9400108110641083E9EC108111601083E8ECFC +:108AA40010811068108398CF02DE068F178F20A3E1 +:108AB40031A3089564D00091CB0407FF02C000E8FD +:108AC4002EC005D2002361F5EBEC1CD204FF1EC0BE +:108AD40000E114D200E00093722901E010E0009359 +:108AE40070291093712900E00093C30420E430E05E +:108AF40059D020E430E010E000E854D003E719E254 +:108B04000093F8201093F92028D10AC0008106FFB1 +:108B140002C000E404C0008105FF02C000E2EED1FF +:108B24001ED018952CD0A1D101FD02C08ED1B1F474 +:108B340002E00093CC040091C50432D0F801008116 +:108B440005FF06C02DD020E2F80126930DD106C002 +:108B540000E827D020E2F8012693B3D0E1CF8FBFFD +:108B64000991199129913991499159916991799171 +:108B74000990199029903990E991F991B1CE8A938D +:108B8400FA93EA933A922A921A920A927A936A93FD +:108B94005A934A933A932A931A930A938FB7089550 +:108BA40000E01AC08A932051304041F020513040F7 +:108BB40039F02052304031F080E005C081E003C03C +:108BC40082E001C083E0EDDF20E0F801218326E0AC +:108BD40020838064818384CE64EF70E2202F2F7021 +:108BE400220F402F440F00E010E0001F020F43E06B +:108BF4000E94C740060F171F08959D01E8EC82D11B +:108C04000F7D008300810F7D00834DD102E0059329 +:108C1400AEEFB0E200E010E00D930C93539600E247 +:108C2400069300E4069349D1069300E406931D934A +:108C34001D931D931C9315971D931C9312AFD9017B +:108C4400089570DD8CD0002331F0033011F004302E +:108C540009F436D182D0FD0106811781083050E035 +:108C6400104009F548E023E739E206E011E2E2DAD0 +:108C7400E8ECF4E023D022D058DD002311F4F8D03E +:108C840012C0FD01068907FF05C011D002E006AF3E +:108C940018D009C009D0012B11F4F6D004C007D0B4 +:108CA40001E006AF06D1CBCC048D158D089500E00C +:108CB40002AF03AFDC960D930C930895008100621C +:108CC400FDCA4CD0033011F447D043C0A7D080A1D3 +:108CD40091A1801B910B282F292BE9F496D0E4DF76 +:108CE4000217130721F00091B329002311F0DED0FD +:108CF40030C004A115A120E00030120799F0F8015A +:108D04000995002379F000E0FD0104AFFC9601838E +:108D1400FD0180A191A1803400E0900718F080E467 +:108D240090E001C001E00093B329FD018687978795 +:108D3400068D178D24AD35AD020F131F008B118BDB +:108D4400DC960D91132F080F191F1C930E93ABD0B3 +:108D5400B1D0E4E00C948940B3D04FCF2DDDA0EF27 +:108D6400B0E200912E210895F9DF043011F4F4DF0C +:108D740048C0FD018681978164AD75AD20A131A104 +:108D84008B01080F191F2017310718F4C901861B1E +:108D9400970BAC0123E739E2068D178D060F171FD9 +:108DA40049DA3CD0080F191F04AF15AF8034904046 +:108DB40031F42FD0448D558D2417350750F000A37E +:108DC40011A394962FD019F00995002389F05CD053 +:108DD40018C020A131A12017310791F4949612D024 +:108DE400959700E0E030F00719F00995002311F49D +:108DF4003FD007C013D009D000E0DC960D930C934C +:108E040058D0A7CFED91FC91089503D022AF33AF92 +:108E1400089522AD33AD200F311F0895FD0104AD37 +:108E240015AD0895EFDF00E0E030F00708951DD0A0 +:108E340001FD0AC00AD041F400912E21013009F449 +:108E440023C0043009F417D008955FD013CB0DD09C +:108E540001FD0AC0FADF41F400912E21023009F429 +:108E640025C0033009F407D008950091CC04089577 +:108E740005E000932E21EDEFF0E204E00593E5EF29 +:108E8400F0E204E0059308951B2F2A2F10DC03E081 +:108E9400DF01DE960C9300E00687078704D00AD032 +:108EA400A22FB12F0895ECEFF0E2089504E00093AF +:108EB4002E2103D002E006930895E4EFF0E2089532 +:108EC40031DCA2E1B1E2AEDF09F00995B8CBEBECFD +:108ED40019D002FF08C0F093CA040091FC2006FFD9 +:108EE4000BC0A5DF09C0008101FF07C002E006D066 +:108EF4000091F42006FDABDFE6CAD7CB0093CA0489 +:108F04000895E0ECF4E000810895AFDF00FFCDCBDD +:108F140001E00093CC04D1DF00E80693C4DF00E84D +:108F2400069301E0EBDFC9DF00E106938ADECBCADA +:108F3400CC08E820000076007220408F0400000076 +:108F44008000000D4111410004000013411741034A +:108F540000000018410000040000001E4100000051 +:108F64000000000000000075207D209520952085DC +:108F7400208D20952095209520952095209520954D +:108F840020952095209520952000090212000101CA +:108F940000C0320904000000FF00000012010002BA +:108FA40000000040EB03E42F040000000001040370 +:028FB4000904AE +:040000030000800079 +:00000001FF diff --git a/Firmware/Chameleon-Mini/.cproject b/Firmware/Chameleon-Mini/.cproject new file mode 100644 index 00000000..ecd4de33 --- /dev/null +++ b/Firmware/Chameleon-Mini/.cproject @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + program + true + true + true + + + + + + + + + + + + + diff --git a/Firmware/Chameleon-Mini/.project b/Firmware/Chameleon-Mini/.project new file mode 100644 index 00000000..7b77bcf9 --- /dev/null +++ b/Firmware/Chameleon-Mini/.project @@ -0,0 +1,34 @@ + + + Chameleon-Mini + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doxyfile + 1 + PARENT-2-PROJECT_LOC/Doc/Doxyfile + + + diff --git a/Firmware/Chameleon-Mini/AntennaLevel.h b/Firmware/Chameleon-Mini/AntennaLevel.h new file mode 100644 index 00000000..1b390f07 --- /dev/null +++ b/Firmware/Chameleon-Mini/AntennaLevel.h @@ -0,0 +1,99 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef ANTENNALEVEL_H_ +#define ANTENNALEVEL_H_ + +#include "Common.h" + +#define ANTENNA_LEVEL_R1 10E3 +#define ANTENNA_LEVEL_R2 220E0 +#define ANTENNA_LEVEL_VREF 1.0 +#define ANTENNA_LEVEL_RES 4096 +#define ANTENNA_LEVEL_OFFSET 190 /* LSB */ + +#define ANTENNA_LEVEL_MILLIVOLT 1E3 +#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) ) +#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16) +#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5)) +#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) + +static inline +void AntennaLevelInit(void) +{ + ADCA.CTRLA = ADC_ENABLE_bm; + ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; + ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; + ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; + ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; + +} + +static inline +uint16_t AntennaLevelGet(void) +{ + ADCA.CH0.CTRL |= ADC_CH_START_bm; + while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); + + ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; + + int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; + if (Result < 0) Result = 0; + + return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); +} + +#endif /* ANTENNALEVEL_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h new file mode 100644 index 00000000..7b7df2f1 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -0,0 +1,90 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef APPLICATION_H_ +#define APPLICATION_H_ + +#include "../Common.h" +#include "../Configuration.h" + +/* Applications */ +#include "MifareClassic.h" + +/* Function wrappers */ +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); +} + +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); +} + +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); +} + +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); +} + +#endif /* APPLICATION_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/Crypto1.c b/Firmware/Chameleon-Mini/Application/Crypto1.c new file mode 100644 index 00000000..cd41a1e3 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Crypto1.c @@ -0,0 +1,378 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Crypto1.h" + +#define PRNG_MASK 0x002D0000UL +/* x^16 + x^14 + x^13 + x^11 + 1 */ + +#define PRNG_SIZE 4 /* Bytes */ + +#define LFSR_MASK_EVEN 0x2010E1UL +#define LFSR_MASK_ODD 0x3A7394UL +/* x^48 + x^43 + x^39 + x^38 + x^36 + x^34 + x^33 + x^31 + x^29 + + * x^24 + x^23 + x^21 + x^19 + x^13 + x^9 + x^7 + x^6 + x^5 + 1 */ + +#define LFSR_SIZE 6 /* Bytes */ + +/* Functions fa, fb and fc in filter output network. Definitions taken + * from Timo Kasper's thesis */ +#define FA(x3, x2, x1, x0) ( \ + ( (x0 | x1) ^ (x0 & x3) ) ^ ( x2 & ( (x0 ^ x1) | x3 ) ) \ +) + +#define FB(x3, x2, x1, x0) ( \ + ( (x0 & x1) | x2 ) ^ ( (x0 ^ x1) & (x2 | x3) ) \ +) + +#define FC(x4, x3, x2, x1, x0) ( \ + ( x0 | ( (x1 | x4) & (x3 ^ x4) ) ) ^ ( ( x0 ^ (x1 & x3) ) & ( (x2 ^ x3) | (x1 & x4) ) ) \ +) + +/* Create tables from function fa, fb and fc for faster access */ +static const uint8_t TableAB[5][16] = { + { /* fa with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 0 */ + FA(0,0,0,0) << 0, FA(0,0,0,1) << 0, FA(0,0,1,0) << 0, FA(0,0,1,1) << 0, + FA(0,1,0,0) << 0, FA(0,1,0,1) << 0, FA(0,1,1,0) << 0, FA(0,1,1,1) << 0, + FA(1,0,0,0) << 0, FA(1,0,0,1) << 0, FA(1,0,1,0) << 0, FA(1,0,1,1) << 0, + FA(1,1,0,0) << 0, FA(1,1,0,1) << 0, FA(1,1,1,0) << 0, FA(1,1,1,1) << 0, + }, + { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 1 */ + FB(0,0,0,0) << 1, FB(0,0,0,1) << 1, FB(0,0,1,0) << 1, FB(0,0,1,1) << 1, + FB(0,1,0,0) << 1, FB(0,1,0,1) << 1, FB(0,1,1,0) << 1, FB(0,1,1,1) << 1, + FB(1,0,0,0) << 1, FB(1,0,0,1) << 1, FB(1,0,1,0) << 1, FB(1,0,1,1) << 1, + FB(1,1,0,0) << 1, FB(1,1,0,1) << 1, FB(1,1,1,0) << 1, FB(1,1,1,1) << 1, + }, + { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 2 */ + FB(0,0,0,0) << 2, FB(0,0,0,1) << 2, FB(0,0,1,0) << 2, FB(0,0,1,1) << 2, + FB(0,1,0,0) << 2, FB(0,1,0,1) << 2, FB(0,1,1,0) << 2, FB(0,1,1,1) << 2, + FB(1,0,0,0) << 2, FB(1,0,0,1) << 2, FB(1,0,1,0) << 2, FB(1,0,1,1) << 2, + FB(1,1,0,0) << 2, FB(1,1,0,1) << 2, FB(1,1,1,0) << 2, FB(1,1,1,1) << 2, + }, + { /* fa with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 3 */ + FA(0,0,0,0) << 3, FA(0,0,0,1) << 3, FA(0,0,1,0) << 3, FA(0,0,1,1) << 3, + FA(0,1,0,0) << 3, FA(0,1,0,1) << 3, FA(0,1,1,0) << 3, FA(0,1,1,1) << 3, + FA(1,0,0,0) << 3, FA(1,0,0,1) << 3, FA(1,0,1,0) << 3, FA(1,0,1,1) << 3, + FA(1,1,0,0) << 3, FA(1,1,0,1) << 3, FA(1,1,1,0) << 3, FA(1,1,1,1) << 3, + }, + { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 4 */ + FB(0,0,0,0) << 4, FB(0,0,0,1) << 4, FB(0,0,1,0) << 4, FB(0,0,1,1) << 4, + FB(0,1,0,0) << 4, FB(0,1,0,1) << 4, FB(0,1,1,0) << 4, FB(0,1,1,1) << 4, + FB(1,0,0,0) << 4, FB(1,0,0,1) << 4, FB(1,0,1,0) << 4, FB(1,0,1,1) << 4, + FB(1,1,0,0) << 4, FB(1,1,0,1) << 4, FB(1,1,1,0) << 4, FB(1,1,1,1) << 4, + } +}; + +static const uint8_t TableC[32] = { + /* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */ + FC(0,0,0,0,0), FC(0,0,0,0,1), FC(0,0,0,1,0), FC(0,0,0,1,1), + FC(0,0,1,0,0), FC(0,0,1,0,1), FC(0,0,1,1,0), FC(0,0,1,1,1), + FC(0,1,0,0,0), FC(0,1,0,0,1), FC(0,1,0,1,0), FC(0,1,0,1,1), + FC(0,1,1,0,0), FC(0,1,1,0,1), FC(0,1,1,1,0), FC(0,1,1,1,1), + FC(1,0,0,0,0), FC(1,0,0,0,1), FC(1,0,0,1,0), FC(1,0,0,1,1), + FC(1,0,1,0,0), FC(1,0,1,0,1), FC(1,0,1,1,0), FC(1,0,1,1,1), + FC(1,1,0,0,0), FC(1,1,0,0,1), FC(1,1,0,1,0), FC(1,1,0,1,1), + FC(1,1,1,0,0), FC(1,1,1,0,1), FC(1,1,1,1,0), FC(1,1,1,1,1), +}; + +/* Split Crypto1 state into even and odd bits to speed up the output filter network */ +static uint8_t StateEven[LFSR_SIZE/2] = {0}; +static uint8_t StateOdd[LFSR_SIZE/2] = {0}; + +/* Proceed LFSR by one clock cycle */ +static void Crypto1LFSR(uint8_t In) { + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); + + Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + + /* Now the shifting of the Crypto1 state gets more complicated when + * split up into even/odd parts. After some hard thinking, one can + * see that after one LFSR clock cycle + * - the new even state becomes the old odd state + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + Temp |= ((uint32_t) StateEven[1] << 8); + Temp |= ((uint32_t) StateEven[2] << 16); + + /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ + Temp = (Temp >> 1) & 0x00FFFFFF; + + /* Calculate MSBit of even state as input bit to LFSR */ + if ( (Feedback & 0x01) ^ In ) { + Temp |= (uint32_t) 1 << (8 * LFSR_SIZE/2 - 1); + } + + /* Convert even state back into byte array and swap odd/even state + * as explained above. */ + StateEven[0] = StateOdd[0]; + StateEven[1] = StateOdd[1]; + StateEven[2] = StateOdd[2]; + + StateOdd[0] = (uint8_t) (Temp >> 0); + StateOdd[1] = (uint8_t) (Temp >> 8); + StateOdd[2] = (uint8_t) (Temp >> 16); +} + +uint8_t Crypto1FilterOutput(void) { + /* Calculate the functions fa, fb. + * Note that only bits {4...23} of the odd state + * get fed into these function. + * The tables are designed to hold mask values, which + * can simply be ORed together to produce the resulting + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; + Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; + Sum |= TableAB[4][(StateOdd[2] >> 4) & 0x0F]; + + return TableC[Sum]; +} + +void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]) +{ + uint8_t i; + + /* Again, one trade off when splitting up the state into even/odd parts + * is that loading the key into the state becomes a little more difficult. + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + StateOdd[i] = OddByte; + } + + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; + + for (i=0; i<32; i++) { + uint8_t Out = Crypto1FilterOutput(); + + Crypto1LFSR(Temp & 0x01); + Temp >>= 1; + + /* Store the keystream for later use */ + if (Out) { + Temp |= (uint32_t) 1 << 31; + } + } + + /* Crypto1 state register is now set up to be used for authentication. + * In case of nested authentication, we need to use the produced keystream + * to encrypt the CardNonce. For this case we do the encryption in-place. */ + CardNonce[0] ^= (uint8_t) (Temp >> 0); + CardNonce[1] ^= (uint8_t) (Temp >> 8); + CardNonce[2] ^= (uint8_t) (Temp >> 16); + CardNonce[3] ^= (uint8_t) (Temp >> 24); +} + +void Crypto1Auth(uint8_t EncryptedReaderNonce[4]) +{ + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; + + uint8_t i; + + for (i=0; i<32; i++) { + /* Decrypt one output bit of the given encrypted nonce using the + * filter output as keystream. */ + uint8_t Out = Crypto1FilterOutput(); + uint8_t Bit = Out ^ (Temp & 0x01); + + /* Feed back the bit to load the LFSR with the (decrypted) nonce */ + Crypto1LFSR(Bit); + Temp >>= 1; + } +} + +uint8_t Crypto1Byte(void) +{ + uint8_t KeyStream = 0; + uint8_t i; + + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + + if (Out) { + KeyStream |= (1<<7); + } + } + + return KeyStream; +} + +uint8_t Crypto1Nibble(void) +{ + uint8_t KeyStream = 0; + uint8_t i; + + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + + if (Out) { + KeyStream |= (1<<3); + } + } + + return KeyStream; +} + +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) +{ + while(ClockCount--) { + /* Actually, the PRNG is a 32 bit register with the upper 16 bit + * used as a LFSR. Furthermore only mask-byte 2 contains feedback at all. + * We rely on the compiler to optimize this for us here. + * XOR all tapped bits to a single feedback bit. */ + uint8_t Feedback = 0; + + Feedback ^= State[0] & (uint8_t) (PRNG_MASK >> 0); + Feedback ^= State[1] & (uint8_t) (PRNG_MASK >> 8); + Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); + Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + + /* For ease of processing convert the state into a 32 bit integer first */ + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + Temp |= (uint32_t) State[1] << 8; + Temp |= (uint32_t) State[2] << 16; + Temp |= (uint32_t) State[3] << 24; + + /* Cycle LFSR and feed back. */ + Temp >>= 1; + + if (Feedback & 0x01) { + Temp |= (uint32_t) 1 << (8 * PRNG_SIZE - 1); + } + + /* Store back state */ + State[0] = (uint8_t) (Temp >> 0); + State[1] = (uint8_t) (Temp >> 8); + State[2] = (uint8_t) (Temp >> 16); + State[3] = (uint8_t) (Temp >> 24); + } + + +} diff --git a/Firmware/Chameleon-Mini/Application/Crypto1.h b/Firmware/Chameleon-Mini/Application/Crypto1.h new file mode 100644 index 00000000..5d8d9647 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Crypto1.h @@ -0,0 +1,80 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef CRYPTO1_H +#define CRYPTO1_H + +#include + +/* Gets the current keystream-bit, without shifting the internal LFSR */ +uint8_t Crypto1FilterOutput(void); + +/* Set up Crypto1 cipher using the given Key, Uid and CardNonce. Also encrypts + * the CardNonce in-place while in non-linear mode. */ +void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]); + +/* Load the decrypted ReaderNonce into the Crypto1 state LFSR */ +void Crypto1Auth(uint8_t EncryptedReaderNonce[4]); + +/* Generate 8 Bits of key stream */ +uint8_t Crypto1Byte(void); + +/* Generate 4 Bits of key stream */ +uint8_t Crypto1Nibble(void); + +/* Execute 'ClockCount' cycles on the PRNG state 'State' */ +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount); + +#endif //CRYPTO1_H diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.c b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c new file mode 100644 index 00000000..090a0bd9 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c @@ -0,0 +1,156 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + *DataPtr++ = (Checksum >> 0) & 0x00FF; + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); +} + +#if 0 +bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + DataPtr[1] = UidCL[1]; + DataPtr[2] = UidCL[2]; + DataPtr[3] = UidCL[3]; + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + + *BitCount = ISO14443A_CL_FRAME_SIZE; + + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + (DataPtr[3] == UidCL[1]) && + (DataPtr[4] == UidCL[2]) && + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + ISO14443AAppendCRCA(Buffer, 1); + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + return true; + } else { + /* We have not been selected. Don't send anything. */ + *BitCount = 0; + return false; + } + default: + /* TODO: No anticollision supported */ + *BitCount = 0; + return false; + } +} + +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + + return true; + } else { + return false; + } +} +#endif diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.h b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h new file mode 100644 index 00000000..e38860c8 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h @@ -0,0 +1,165 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef ISO14443_3A_H_ +#define ISO14443_3A_H_ + +#include "../Common.h" + +#define ISO14443A_UID_SIZE_SINGLE 4 /* bytes */ +#define ISO14443A_UID_SIZE_DOUBLE 7 +#define ISO14443A_UID_SIZE_TRIPLE 10 + +#define ISO14443A_CMD_REQA 0x26 +#define ISO14443A_CMD_WUPA 0x52 +#define ISO14443A_CMD_SELECT_CL1 0x93 +#define ISO14443A_CMD_SELECT_CL2 0x95 +#define ISO14443A_CMD_SELECT_CL3 0x97 +#define ISO14443A_CMD_HLTA 0x50 + +#define ISO14443A_NVB_AC_START 0x20 +#define ISO14443A_NVB_AC_END 0x70 + +#define ISO14443A_CL_UID_OFFSET 0 +#define ISO14443A_CL_UID_SIZE 4 +#define ISO14443A_CL_BCC_OFFSET 4 +#define ISO14443A_CL_BCC_SIZE 1 /* Byte */ +#define ISO14443A_CL_FRAME_SIZE ((ISO14443A_CL_UID_SIZE + ISO14443A_CL_BCC_SIZE) * 8) /* UID[N...N+3] || BCCN */ +#define ISO14443A_SAK_INCOMPLETE 0x04 +#define ISO14443A_SAK_COMPLETE_COMPLIANT 0x20 +#define ISO14443A_SAK_COMPLETE_NOT_COMPLIANT 0x00 + +#define ISO14443A_ATQA_FRAME_SIZE (2 * 8) /* Bit */ +#define ISO14443A_SAK_FRAME_SIZE (3 * 8) /* Bit */ + +#define ISO14443A_UID0_RANDOM 0x08 +#define ISO14443A_UID0_CT 0x88 + +#define ISO14443A_CRCA_SIZE 2 + +#define ISO14443A_CALC_BCC(ByteBuffer) \ + ( ByteBuffer[0] ^ ByteBuffer[1] ^ ByteBuffer[2] ^ ByteBuffer[3] ) + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount); +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount); + +INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue); +INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue); + +INLINE +bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + DataPtr[1] = UidCL[1]; + DataPtr[2] = UidCL[2]; + DataPtr[3] = UidCL[3]; + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + + *BitCount = ISO14443A_CL_FRAME_SIZE; + + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + (DataPtr[3] == UidCL[1]) && + (DataPtr[4] == UidCL[2]) && + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + ISO14443AAppendCRCA(Buffer, 1); + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + return true; + } else { + /* We have not been selected. Don't send anything. */ + *BitCount = 0; + return false; + } + default: + /* TODO: No anticollision supported */ + *BitCount = 0; + return false; + } +} + +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + + return true; + } else { + return false; + } +} + +#endif diff --git a/Firmware/Chameleon-Mini/Application/MifareClassic.c b/Firmware/Chameleon-Mini/Application/MifareClassic.c new file mode 100644 index 00000000..1d532cba --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/MifareClassic.c @@ -0,0 +1,553 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "MifareClassic.h" + +#include "ISO14443-3A.h" +#include "../Codec/ISO14443-2A.h" +#include "../Memory.h" +#include "Crypto1.h" +#include "../Random.h" + +#define MFCLASSIC_1K_ATQA_VALUE 0x0004 +#define MFCLASSIC_4K_ATQA_VALUE 0x0002 +#define MFCLASSIC_1K_SAK_CL1_VALUE 0x08 +#define MFCLASSIC_4K_SAK_CL1_VALUE 0x18 + +#define MEM_UID_CL1_ADDRESS 0x00 +#define MEM_UID_CL1_SIZE 4 +#define MEM_UID_BCC1_ADDRESS 0x04 +#define MEM_KEY_A_OFFSET 48 /* Bytes */ +#define MEM_KEY_B_OFFSET 58 /* Bytes */ +#define MEM_KEY_SIZE 6 /* Bytes */ +#define MEM_SECTOR_ADDR_MASK 0x3C +#define MEM_BYTES_PER_BLOCK 16 /* Bytes */ +#define MEM_VALUE_SIZE 4 /* Bytes */ + +#define ACK_NAK_FRAME_SIZE 4 /* Bits */ +#define ACK_VALUE 0x0A +#define NAK_INVALID_ARG 0x00 +#define NAK_CRC_ERROR 0x01 +#define NAK_NOT_AUTHED 0x04 +#define NAK_EEPROM_ERROR 0x05 +#define NAK_OTHER_ERROR 0x06 + +#define CMD_AUTH_A 0x60 +#define CMD_AUTH_B 0x61 +#define CMD_AUTH_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_AUTH_RB_FRAME_SIZE 4 /* Bytes */ +#define CMD_AUTH_AB_FRAME_SIZE 8 /* Bytes */ +#define CMD_AUTH_BA_FRAME_SIZE 4 /* Bytes */ +#define CMD_HALT 0x50 +#define CMD_HALT_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_READ 0x30 +#define CMD_READ_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_READ_RESPONSE_FRAME_SIZE 16 /* Bytes without CRCA */ +#define CMD_WRITE 0xA0 +#define CMD_WRITE_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_DECREMENT 0xC0 +#define CMD_DECREMENT_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_INCREMENT 0xC1 +#define CMD_INCREMENT_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_RESTORE 0xC2 +#define CMD_RESTORE_FRAME_SIZE 2 /* Bytes without CRCA */ +#define CMD_TRANSFER 0xB0 +#define CMD_TRANSFER_FRAME_SIZE 2 /* Bytes without CRCA */ + +static enum { + STATE_HALT, + STATE_IDLE, + STATE_READY, + STATE_ACTIVE, + STATE_AUTHING, + STATE_AUTHED_IDLE, + STATE_WRITE, + STATE_INCREMENT, + STATE_DECREMENT, + STATE_RESTORE +} State; + +static uint8_t CardResponse[4]; +static uint8_t ReaderResponse[4]; +static uint8_t CurrentAddress; +static uint8_t BlockBuffer[MEM_BYTES_PER_BLOCK]; +static uint16_t CardATQAValue; +static uint8_t CardSAKValue; + +INLINE bool CheckValueIntegrity(uint8_t* Block) +{ + /* Value Blocks contain a value stored three times, with + * the middle portion inverted. */ + if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) + && (Block[1] == (uint8_t) ~Block[5]) && (Block[1] == Block[9]) + && (Block[2] == (uint8_t) ~Block[6]) && (Block[2] == Block[10]) + && (Block[3] == (uint8_t) ~Block[7]) && (Block[3] == Block[11]) + && (Block[12] == (uint8_t) ~Block[13]) + && (Block[12] == Block[14]) + && (Block[14] == (uint8_t) ~Block[15])) { + return true; + } else { + return false; + } +} + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + *Value |= ((uint32_t) Block[2] << 16); + *Value |= ((uint32_t) Block[3] << 24); +} + +INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) +{ + Block[0] = (uint8_t) (Value >> 0); + Block[1] = (uint8_t) (Value >> 8); + Block[2] = (uint8_t) (Value >> 16); + Block[3] = (uint8_t) (Value >> 24); + Block[4] = ~Block[0]; + Block[5] = ~Block[1]; + Block[6] = ~Block[2]; + Block[7] = ~Block[3]; + Block[8] = Block[0]; + Block[9] = Block[1]; + Block[10] = Block[2]; + Block[11] = Block[3]; +} + +void MifareClassicAppInit1K(void) +{ + State = STATE_IDLE; + CardATQAValue = MFCLASSIC_1K_ATQA_VALUE; + CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; +} + +void MifareClassicAppInit4K(void) +{ + State = STATE_IDLE; + CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; + CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE; +} + +void MifareClassicAppReset(void) +{ + State = STATE_IDLE; +} + +void MifareClassicAppTask(void) +{ + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + case STATE_IDLE: + case STATE_HALT: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY; + return BitCount; + } + break; + + case STATE_READY: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { + /* Load UID CL1 and perform anticollision */ + uint8_t UidCL1[4]; + MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) { + State = STATE_ACTIVE; + } + + return BitCount; + } else { + /* Unknown command. Enter HALT state. */ + State = STATE_HALT; + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { + State = STATE_READY; + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + return ISO14443A_APP_NO_RESPONSE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); + + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; iButtonAction; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i 0) { + if (Carry) { + if (UidBuffer[i] == 0xFF) { + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i 0) { + if (Carry) { + if (UidBuffer[i] == 0x00) { + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + SettingsCycle(); + } + } +} + +void ButtonGetActionList(char* ListOut, uint16_t BufferSize) +{ + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i sizeof(ButtonActionTable[i]) ) { + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ListOut++ = c; + ActionName++; + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + BufferSize--; + } + } + + *ListOut = '\0'; +} + +void ButtonSetActionById(ButtonActionEnum Action) +{ + GlobalSettings.ActiveSettingPtr->ButtonAction = Action; +} + +void ButtonGetActionByName(char* ActionOut, uint16_t BufferSize) +{ + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); +} + +bool ButtonSetActionByName(const char* Action) +{ + uint8_t i; + + for (i=0; i +#include "Application/Application.h" + +#define BUTTON_PORT PORTA +#define BUTTON_MASK PIN6_bm +#define BUTTON_PINCTRL PIN6CTRL + +typedef enum { + BUTTON_ACTION_NONE, + BUTTON_ACTION_UID_RANDOM, + BUTTON_ACTION_UID_LEFT_INCREMENT, + BUTTON_ACTION_UID_RIGHT_INCREMENT, + BUTTON_ACTION_UID_LEFT_DECREMENT, + BUTTON_ACTION_UID_RIGHT_DECREMENT, + BUTTON_ACTION_CYCLE_SETTINGS, + + /* This has to be last element */ + BUTTON_ACTION_COUNT +} ButtonActionEnum; + +void ButtonInit(void); +void ButtonTick(void); + +void ButtonGetActionList(char* ListOut, uint16_t BufferSize); +void ButtonSetActionById(ButtonActionEnum Action); +void ButtonGetActionByName(char* ActionOut, uint16_t BufferSize); +bool ButtonSetActionByName(const char* Action); + +#endif /* BUTTON_H_ */ diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.bin b/Firmware/Chameleon-Mini/Chameleon-Mini.bin new file mode 100644 index 00000000..2dfc95c7 Binary files /dev/null and b/Firmware/Chameleon-Mini/Chameleon-Mini.bin differ diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.c b/Firmware/Chameleon-Mini/Chameleon-Mini.c new file mode 100644 index 00000000..fabdb324 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.c @@ -0,0 +1,87 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Chameleon-Mini.h" + +int main(void) +{ + SystemInit(); + SettingsLoad(); + LEDInit(); + MemoryInit(); + ConfigurationInit(); + TerminalInit(); + RandomInit(); + ButtonInit(); + AntennaLevelInit(); + + SystemInterruptInit(); + + while(1) { + TerminalTask(); + CodecTask(); + ApplicationTask(); + + if (SystemTick100ms()) { + RandomTick(); + TerminalTick(); + ButtonTick(); + LEDTick(); + } + } +} + + + diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.eep b/Firmware/Chameleon-Mini/Chameleon-Mini.eep new file mode 100644 index 00000000..8515437c --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.eep @@ -0,0 +1,3 @@ +:100000000010210600060006000600060006000695 +:03001000000600E7 +:00000001FF diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.elf b/Firmware/Chameleon-Mini/Chameleon-Mini.elf new file mode 100644 index 00000000..297e98f2 Binary files /dev/null and b/Firmware/Chameleon-Mini/Chameleon-Mini.elf differ diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.h b/Firmware/Chameleon-Mini/Chameleon-Mini.h new file mode 100644 index 00000000..a9b39fa2 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.h @@ -0,0 +1,79 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef CHAMELEON_MINI_H +#define CHAMELEON_MINI_H + +#include +#include +#include +#include + +#include "System.h" +#include "Memory.h" +#include "LED.h" +#include "Terminal/Terminal.h" +#include "Codec/Codec.h" +#include "Application/Application.h" +#include "Configuration.h" +#include "Random.h" +#include "Button.h" +#include "AntennaLevel.h" +#include "Settings.h" + +#define CHAMELEON_MINI_VERSION_STRING BUILD_DATE + +#endif //CHAMELEON_MINI_H + diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.hex b/Firmware/Chameleon-Mini/Chameleon-Mini.hex new file mode 100644 index 00000000..72ce1553 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.hex @@ -0,0 +1,1334 @@ +:1000000023C300003DC300003BC3000039C3000010 +:1000100037C3000035C3000033C3000031C3000004 +:100020002FC300002DC300002BC3000029C3000014 +:1000300027C3000025C3000023C3000021C3000024 +:100040001FC300001DC300001BC3000019C3000034 +:1000500017C3000015C300000C945A1111C300000F +:100060000FC300000DC300000BC3000009C3000054 +:1000700007C3000005C3000003C3000001C3000064 +:10008000FFC20000FDC200000C941611F9C200006E +:10009000F7C20000F5C20000F3C20000F1C2000088 +:1000A000EFC20000EDC20000EBC20000E9C2000098 +:1000B000E7C20000E5C20000E3C20000E1C20000A8 +:1000C000DFC20000DDC20000DBC20000D9C20000B8 +:1000D000D7C20000D5C20000D3C20000D1C20000C8 +:1000E000CFC20000CDC20000CBC20000C9C20000D8 +:1000F000C7C20000C5C20000C3C20000C1C20000E8 +:10010000BFC20000BDC20000BBC20000B9C20000F7 +:10011000B7C20000B5C20000B3C20000B1C2000007 +:10012000AFC20000ADC20000ABC20000A9C2000017 +:10013000A7C20000A5C20000A3C20000A1C2000027 +:100140009FC200009DC200009BC200000C94FE11E3 +:1001500097C2000095C2000093C2000091C2000047 +:100160008FC200008DC200008BC2000089C2000057 +:1001700087C2000085C2000083C2000081C2000067 +:100180007FC200007DC200007BC2000079C2000077 +:1001900077C2000075C2000073C2000071C2000087 +:1001A0006FC200006DC200006BC2000069C2000097 +:1001B00067C2000065C2000063C2000061C20000A7 +:1001C0005FC200005DC200005BC2000059C20000B7 +:1001D00057C2000055C2000053C2000051C20000C7 +:1001E0004FC200004DC200004BC2000049C20000D7 +:1001F00047C200000C94EA2243C200001C034C00DA +:100200005500460041002000430044004300200008 +:10021000440065006D006F00000018034400650095 +:1002200061006E002000430061006D0065007200F7 +:10023000610000000403090409023E00020100C03D +:10024000320904000001020201000524001001042B +:100250002402060524060001070582030800FF09A1 +:10026000040100020A00000007050402100005074F +:100270000583021000051201100102000008EB03C3 +:10028000442001000102DC01004E4F4E45000000F9 +:100290000000000000000000002C042D042E042F9C +:1002A00004300431043404350400000001014D46DB +:1002B0005F434C41535349435F314B0000000713E8 +:1002C0003F13B813D213D613D713B518BB180004B5 +:1002D0000400024D465F434C41535349435F344B46 +:1002E00000000007133F13C513D213D613D713B55D +:1002F00018BB18001004004E4F4E450000000000CF +:1003000000000000000000000000000000000000ED +:10031000000000000000005549445F52414E444F28 +:100320004D00000000000000000000000000000080 +:10033000000000000000005549445F4C4546545FF2 +:10034000494E4352454D454E540000000000000008 +:10035000000000000000005549445F5249474854DE +:100360005F494E4352454D454E5400000000000089 +:10037000000000000000005549445F4C4546545FB2 +:1003800044454352454D454E5400000000000000D6 +:10039000000000000000005549445F52494748549E +:1003A0005F44454352454D454E5400000000000057 +:1003B000000000000000004368616D656C656F6EB1 +:1003C0002D4D696E69202553207573696E67204C29 +:1003D00055464120255320636F6D70696C6564201C +:1003E00077697468204156522D47434320255300B6 +:1003F0003133313232320031333039303100342E42 +:10040000362E320025730052414E444F4D00257563 +:1004100000257500253575206D5600564552534907 +:100420004F4E0000000000000000000000000074BB +:100430000B434F4E464947000000000000000000FB +:1004400000CE0BC60BA10B55494400000000000074 +:10045000000000000000000000F90BD30B524541E2 +:10046000444F4E4C59000000000000000000005CAA +:100470000C4D0C55504C4F41440000000000000052 +:10048000000000720C00000000444F574E4C4F41DA +:10049000440000000000000000770C000000005243 +:1004A0004553455400000000000000000000007C9F +:1004B0000C00000000555047524144450000000028 +:1004C0000000000000870C000000004D454D53491E +:1004D0005A450000000000000000000000000092EB +:1004E0000C55494453495A450000000000000000E3 +:1004F0000000000000B90C425554544F4E0000005B +:1005000000000000000000DE0CE80CE30C53455432 +:1005100054494E470000000000000000000000F5B4 +:100520000CF00C434C45415200000000000000005C +:10053000000000FD0C0000000048454C5000000089 +:10054000000000000000000000000D00000000524C +:1005500053534900000000000000000000000000AC +:100560000000004D0D000000000000000000000031 +:1005700000000000000000000000000D0A000D0A4D +:1005800000643130303A4F4B0000000000000000A2 +:10059000000000000000000000000000000000005B +:1005A0000000653130313A4F4B20574954482054B0 +:1005B000455854000000000000000000000000004A +:1005C0000000006E3131303A57414954494E4720BE +:1005D000464F5220584D4F44454D0000000000004A +:1005E00000000000C83230303A554E4B4E4F574E47 +:1005F00020434F4D4D414E440000000000000000DC +:100600000000000000C93230313A494E56414C4991 +:100610004420434F4D4D414E4420555341474500E2 +:10062000000000000000CA3230323A494E56414CB8 +:10063000494420504152414D45544552000000006C +:10064000000000000000000011241FBECFEFDFE219 +:10065000DEBFCDBF10E2A0E0B0E2EEE9F2E502C0FD +:1006600005900D92A23AB107D9F716E2A2EAB0E2DC +:1006700001C01D92AD3AB107E1F703D00C944D29AA +:100680006FC074D0F2D680E3E0E0F6E081834ED212 +:1006900016D1B3D79CD173D5E0E0F2E081E080932E +:1006A0000002118292E0928393E0948380A388E316 +:1006B00081A3CCD0C0E0DAE0FF24F39400E016E0A0 +:1006C000A1D7E091FB20F091FC200995E091012158 +:1006D000F0910221099580910C0A80FFF1CFFC86F0 +:1006E00091D1B1D753D58091A320F8018683109280 +:1006F000A320E6CF9230F9F09330A1F0913049F089 +:1007000080E090E0E0E0F0E0DA01ED93FC931197F7 +:10071000089582E190E0E6E7F2E0DA01ED93FC93E0 +:1007200011970895813081F0813098F4E4E3F2E08C +:10073000849190E0E9CF8EE390E0E8E3F2E0DA0123 +:10074000ED93FC9311970895EAE1F2E0849190E033 +:10075000DBCF8230A9F6ECEFF1E0849190E0D4CFCA +:100760001F920F920FB60F921124FFCF8091780045 +:1007700083FF0AC088E08093780088ED84BF81E021 +:1007800080938000FD95FEC080915000866080932C +:1007900050008091510081FFFCCF8091510082FF79 +:1007A000FCCFE0E5F0E0168221E02093600088EDC8 +:1007B00084BF2093400083ED90E3E0E0FAE086A35D +:1007C00097A386E08093000AE0E4F0E0238320937F +:1007D00000048091CC018860E0ECF1E0848708950A +:1007E00088ED84BF81E0E8E7F0E08183089588ED3B +:1007F00084BF8BE18093800008958BECE0E5F0E00E +:1008000082838091500088608093500080915100D5 +:1008100083FFFCCF84ECE0E5F0E08583809150001D +:100820008061809350008091510084FFFCCF089537 +:10083000E0E4F0E084818E7F8483E0E5F0E0808175 +:100840008F7E80838081877F8083089587E0E0EAC0 +:10085000F0E08283789408950895089508950895A6 +:10086000089580E090E0089508950895E0910E21A4 +:10087000F0910F21818390E09C01220F331F220F02 +:10088000331FB901660F771F660F771F660F771F3B +:10089000620F731F680F791F68577D4F88EE90E2D3 +:1008A00045E250E00E94E225E091FD20F091FE201B +:1008B0000995E091F920F091FA2009950895E091C9 +:1008C0000E21F0910F218181D1CF0F931F93CF93F0 +:1008D000DF93AC0120E030E08C010F5F1F4F622FEF +:1008E000C901880F991F880F991FFC01EE0FFF1F88 +:1008F000EE0FFF1FEE0FFF1FE80FF91FE20FF31FB0 +:10090000E757FD4F8491DA01882359F09C91992390 +:1009100059F0981749F4E80131961196849188238B +:1009200071F48C91882389F02F5F3F4F233031057C +:10093000B1F680E0DF91CF911F910F9108959991C9 +:10094000992391F3981741F3EFCF862F8FDF81E042 +:10095000DF91CF911F910F910895CF93DF93EC0119 +:100960006150704020E030E04CE2C901880F991FCF +:10097000880F991FFC01EE0FFF1FEE0FFF1FEE0FF8 +:10098000FF1FE80FF91FE20FF31FE757FD4F849198 +:10099000882381F06131710568F0DE0103C06031A8 +:1009A000710541F08D93ED01319661507040849155 +:1009B0008823A9F72230310521F41882DF91CF91E5 +:1009C00008954993615070402F5F3F4FCECF0895F7 +:1009D0000C94D42508950F931F93CF93DF93662330 +:1009E00061F08C010F5F1F4F6150060F111DEC016C +:1009F000EFDF8993C017D107D9F7DF91CF911F910E +:100A00000F9108950E94D4250E94D4250E94D425D8 +:100A10000C94D425CF93DF93FC012115310581F18E +:100A2000615070406230710558F1DA0140E050E0E9 +:100A300018C0D05DD0838C2F90E08F7090708A307A +:100A40009105D4F48C2F8F70805D818332964E5F38 +:100A50005F4F21503040B1F06250704062307105FC +:100A600088F0CD91DC2FD295DF708D2F90E08A3009 +:100A70009105FCF2D95CDECF8C2F8F70895CE5CFBD +:100A800040E050E01082CA01DF91CF910895CF93EA +:100A9000DF93DA012C91222309F443C011963C9193 +:100AA00011973323F1F161157105D9F11396EC011A +:100AB00080E090E014C02295207F313430F5342F4F +:100AC000232B29930196FD0131972081222331F1B7 +:100AD0003C91332331F1129668177907F9F0422FD0 +:100AE00040534A3018F041514630D8F4432F405318 +:100AF0004A3020F0532F5154563098F42134D8F214 +:100B00002295207F20573134D0F23753232B29935D +:100B10000196FD01319720812223D1F6DF91CF91FB +:100B2000089580E090E0DF91CF910895CF93DF9317 +:100B300000D000D0CDB7DEB7A0E6B6E080E11596D4 +:100B40008C9315979AE111969C931197E0EAF9E03E +:100B50001682178293EC958398E1948316968C9372 +:100B6000169787ED8093A0098091A10986FFFCCF9D +:100B700080E4E0EAF9E081838091A0091092A00965 +:100B80008091A10986FFFCCF80E4E0EAF9E081834F +:100B90008091A00990E1E0E6F6E0958380FD47C0F2 +:100BA0008DE389838AE28A8380E88B8386EA8C835B +:100BB000A0E6B6E020E137EDE0EAF9E090E4169631 +:100BC0002C9316973093A0098091A10986FFFCCF42 +:100BD00091838091A0091092A0098091A10986FFBC +:100BE000FCCF91838091A00915962C93159787FFD0 +:100BF000E6CF80E1E0E6F6E08683CE010596FE01D1 +:100C00003196A0EAB9E030E421912093A009209127 +:100C1000A10926FFFCCF11963C9311972091A009C2 +:100C2000E817F90789F780E1E0E6F6E08583249686 +:100C3000CDBFDEBFDF91CF9108950F931F93CF9368 +:100C4000DF93EC018B0120E030E080910D2190E0FA +:100C5000A0E0B0E0DC0199278827080F191F2A1FA0 +:100C60003B1FA0E6B6E060E177EDE0EAF9E090E452 +:100C700016966C9316977093A0098091A10986FF30 +:100C8000FCCF91838091A0091092A0098091A109C5 +:100C900086FFFCCF91838091A00915966C931597E0 +:100CA00087FFE6CF80E1E0E6F6E0868383E080938D +:100CB000A0098091A10986FFFCCF80E4E0EAF9E079 +:100CC00081838091A009C901AA27BB278093A0092D +:100CD0008091A10986FFFCCF80E4E0EAF9E08183FE +:100CE0008091A009BB27A32F922F812F8093A00969 +:100CF0008091A10986FFFCCF80E4E0EAF9E08183DE +:100D00008091A0090093A0098091A10986FFFCCFE2 +:100D100080E4E0EAF9E081838091A0094115510562 +:100D200071F090E41092A0098091A10986FFFCCF98 +:100D300091838091A00989934150504099F780E1B7 +:100D4000E0E6F6E08583DF91CF911F910F91089542 +:100D50002F923F924F925F926F927F928F929F92CB +:100D6000AF92BF92CF92DF92EF92FF920F931F93B9 +:100D7000CF93DF93CDB7DEB72697CDBFDEBF8B8392 +:100D80009C834A0180910D214115510509F41EC132 +:100D90006B01EE24FF2490E0A0E0B0E0DC01992795 +:100DA0008827C80ED91EEA1EFB1E212C01E0302E1A +:100DB00000E130E147EDE0EAF9E050E420E410E63C +:100DC000612E16E0712E60E117ED240146015701F6 +:100DD000BB27AB2D9A2D892D7C01982D6101C81858 +:100DE000D1084C145D0408F4620160936606109308 +:100DF000A0098091A10986FFFCCF21838091A009E1 +:100E00001092A0098091A10986FFFCCF21838091D7 +:100E1000A0093093650687FFE8CFD30116963C936F +:100E2000B3E5B093A0098091A10986FFFCCF51835F +:100E30008091A009F092A0098091A10986FFFCCFC2 +:100E400051838091A009E092A0098091A10986FFB9 +:100E5000FCCF51838091A0091092A0098091A10933 +:100E600086FFFCCF51838091A009009365063093E3 +:100E700066064093A0098091A10986FFFCCF2183DB +:100E80008091A0091092A0098091A10986FFFCCF52 +:100E900021838091A0093093650687FFE8CFD301B5 +:100EA00016963C93B4E8B093A0098091A10986FFFF +:100EB000FCCF51838091A0091092A0098091A109D3 +:100EC00086FFFCCF51838091A0091092A0098091E8 +:100ED000A10986FFFCCF51838091A0099093A009BE +:100EE0008091A10986FFFCCF51838091A009C11494 +:100EF000D104D9F0C601AB81AD83BC81BE83C98268 +:100F0000DA82AD81BE817D917093A0096D01DC0113 +:100F10008091A10986FFFCCFCD01D601218370917C +:100F2000A009019781F7C980DA80009365063093A4 +:100F300066064093A0098091A10986FFFCCF21831A +:100F40008091A0091092A0098091A10986FFFCCF91 +:100F500021838091A0093093650687FFE8CFD301F4 +:100F600016963C93B3E8B093A0098091A10986FF3F +:100F7000FCCF51838091A009F092A0098091A10932 +:100F800086FFFCCF51838091A009E092A009809157 +:100F9000A10986FFFCCF51838091A0091092A0097E +:100FA0008091A10986FFFCCF51838091A009009315 +:100FB00065064C185D08C601A0E0B0E0880E991ED9 +:100FC000AA1EBB1E4114510409F002CF2696CDBFC4 +:100FD000DEBFDF91CF911F910F91FF90EF90DF90D7 +:100FE000CF90BF90AF909F908F907F906F905F90C9 +:100FF0004F903F902F9008951F93CF93DF93809150 +:101000000D2190E0A0E0B0E0BA2FA92F982F8827FB +:101010009C0120503F4FA0E6B6E0D0E160E177EDC3 +:10102000E0EAF9E0C0E450E411E816966C931697F4 +:101030007093A0094091A10946FFFCCF51834091D4 +:10104000A0091092A0094091A10946FFFCCF51834D +:101050004091A00915966C93159747FFE6CF169619 +:10106000DC9316971093A0094091A10946FFFCCF8D +:10107000C1834091A0099093A0094091A10946FF26 +:10108000FCCFC1834091A0098093A0094091A109A0 +:1010900046FFFCCFC1834091A0091092A009409166 +:1010A000A10946FFFCCFC1834091A0091596DC93AE +:1010B000159701968217930709F0B7CFDF91CF916B +:1010C0001F9108950F931F93FC01403080E0580753 +:1010D00081E0680780E0780720F081E01F910F91A0 +:1010E000089580E090E0A1E0B0E0841B950BA60B92 +:1010F000B70B890120E030E080179107A207B30702 +:1011000040F0CF01BA01A80123DE81E01F910F91C9 +:1011100008958C019D01CF01BA01A80119DEF5CF18 +:101120000F931F93FC01403080E0580781E068076F +:1011300080E0780720F080E01F910F91089580E013 +:1011400090E0A1E0B0E0841B950BA60BB70B8901E2 +:1011500020E030E080179107A207B30740F0CF01ED +:10116000BA01A8016ADD81E01F910F9108958C01F9 +:101170009D01CF01BA01A80160DD81E0F5CFE0E07B +:10118000F6E080E4828388E1868B0895FF920F93D6 +:101190001F93CF93DF93CDB7DEB7A097CDBFDEBF50 +:1011A0009091080690958091A22089278923909399 +:1011B000A22086FF15C0E0910E21F0910F218081C1 +:1011C0008130B9F0823079F1833009F44EC0843037 +:1011D00009F470C0853009F48FC0863009F468C006 +:1011E000A096CDBFDEBFDF91CF911F910F91FF90F1 +:1011F000089580910B21882309F4A1C0FF248E015A +:101200000F5F1F4FE5DBF801EF0DF11D8083F394B5 +:1012100080910B21F816B0F3E0910721F09108219D +:10122000C8010995DDCFE0910521F09106218E01DD +:101230000F5F1F4FC801099520910B21222361F3F5 +:10124000F801CE0102962150820F911D21E0222348 +:1012500039F0308121E03F3F09F020E03F5F3083EB +:101260003196E817F90799F7D7CFE0910521F0916A +:1012700006218E010F5F1F4FC801099520910B2198 +:1012800031E0222349F221503323D9F3822F90E019 +:10129000F801E80FF91F408131E04F3F09F030E0DD +:1012A000800F911F4F5FFC014083222361F7B4CF71 +:1012B000FBD096CFE0910521F09106218E010F5FC2 +:1012C0001F4FC801099520910B21222309F4A4CFB7 +:1012D000F801CE0102962150820F911D21E02223B8 +:1012E00031F0308121E0311120E0315030833196EE +:1012F000E817F907A1F790CFE0910521F0910621B9 +:101300008E010F5F1F4FC801099520910B2131E01D +:10131000222309F481CF21503323D1F3822F90E08F +:10132000F801E80FF91F408131E0411130E0800FF2 +:10133000911F4150FC014083222369F76DCF8E013C +:101340000F5F1F4F69CFCF93DF93EC016150704067 +:1013500027EF32E04CE2C901F9015491552389F09D +:101360006132710570F0DE0103C06032710549F031 +:101370005D93ED01019661507040FC01549155233D +:10138000A1F7F3E0273B3F0721F41882DF91CF91CB +:101390000895499361507040205E3F4F83E0273DA0 +:1013A0003807C9F6F2CFE0910E21F0910F2180832A +:1013B0000895AB01E0910E21F0910F21608170E062 +:1013C000660F771F62957295707F7627607F76270C +:1013D00069507D4F0C94F425CF93DF93EC0167EFB8 +:1013E00072E00E94EB25009771F1CE0167E173E096 +:1013F0000E94EB25009769F1CE0167E373E00E943C +:10140000EB25009741F1CE0167E573E00E94EB25E3 +:10141000009719F1CE0167E773E00E94EB25009772 +:10142000F1F0CE0167E973E00E94EB250097C9F067 +:10143000CE0167EB73E00E94EB250097A1F080E0FE +:10144000DF91CF91089580E0AEDF81E0DF91CF9111 +:10145000089581E0F9CF82E0F7CF83E0F5CF84E013 +:10146000F3CF85E0F1CF86E0EFCF8DE091E260E051 +:1014700070E043E150E00C9408288DE091E260E0D8 +:1014800070E043E150E00C941328883008F0089590 +:1014900080930D2190E0880F991F805F9E4D80936F +:1014A0000E2190930F210BCA80910D218F5F8770C1 +:1014B000282F30E0F901EE0FFF1FEF5EFE4D908107 +:1014C000992309F05DC0C90101968770282F30E08B +:1014D000F901EE0FFF1FEF5EFE4D9081992309F099 +:1014E0004FC0C90101968770282F30E0F901EE0F37 +:1014F000FF1FEF5EFE4D9081992309F041C0C901A5 +:1015000001968770282F30E0F901EE0FFF1FEF5E84 +:10151000FE4D90819923A1F5C90101968770282F6E +:1015200030E0F901EE0FFF1FEF5EFE4D9081992331 +:1015300039F5C90101968770282F30E0F901EE0FC7 +:10154000FF1FEF5EFE4D90819923D1F4C9010196F2 +:101550008770282F30E0F901EE0FFF1FEF5EFE4D80 +:101560009081992369F4C90101968770E82FF0E012 +:10157000EE0FFF1FEF5EFE4D9081992309F4089551 +:1015800084CF80910D210895CF93DF93EC01F9DF93 +:10159000805D88831982DF91CF910895FC0180815D +:1015A0009181992341F48053883010F080E00895B0 +:1015B0006CDF81E0089580E00895BC0180E090E256 +:1015C0000C942B24CF93DF93FC016491662359F094 +:1015D000EC01219680E090E20E947124FE012196A8 +:1015E00064916623B9F7DF91CF9108959C01AB0117 +:1015F00080E090E2B9010C944F2480E2E0E6F6E04E +:1016000082830895CF93DF9380E090E20E94E524E7 +:101610000E94441E80E090E20E94FF24EC0197FDAE +:101620000AC080E18093A320E0E0F6E085838C2F60 +:10163000B3D2882319F0DF91CF9108958C2F33D442 +:10164000DF91CF9108958091A420813009F18130FC +:1016500030F0823059F1833071F0F7D3C7C58091F3 +:10166000680685FFFACF84E180931B2081E0809398 +:10167000A420EBD3BBC580911B20815080931B20FD +:10168000882359F70E947822D3D81092A420E5CF5E +:1016900080911B20815080931B208823F1F6ADD8C8 +:1016A0000E94B32282E08093A420D7CF8091680665 +:1016B00085FDD3CF84E180931B2083E08093A42019 +:1016C000C4D394C580E2E0E0F6E08583089580E22B +:1016D000E0E0F6E08683089580E090E20C94052433 +:1016E00080E090E20C945A232DB73EB72C50304046 +:1016F0002DBF3EBFEDB7FEB73196ADB7BEB7119661 +:101700008D939C93129780E091E08283938387EB83 +:1017100093E08483958380EF93E08683978387EFBC +:1017200093E0808791878EEF93E0828793870E9472 +:101730000C262DB73EB7245F3F4F2DBF3EBF85E639 +:1017400008952DB73EB7285030402DBF3EBFEDB7AE +:10175000FEB73196ADB7BEB711968D939C93129795 +:1017600080E091E08283938384E094E08483958396 +:1017700089EE90E2868397830E940C262DB73EB7B0 +:10178000285F3F4F2DBF3EBF85E608959ED8882332 +:1017900011F48AEC089571DE84E6089560E071E04A +:1017A000DCD885E608950F931F93CF93DF93CDB7D1 +:1017B000DEB7A197CDBFDEBF8C0120910B21E09158 +:1017C0000521F0910621CE01019629A30995C801B2 +:1017D00060E071E0AE014F5F5F4F29A130E01AD9A0 +:1017E00085E6A196CDBFDEBFDF91CF911F910F910E +:1017F0000895BF92CF92DF92EF92FF920F931F93C3 +:10180000CF93DF93CDB7DEB7A097CDBFDEBF8C01FE +:10181000E0900B21FF2467E074E00E94EB25009725 +:1018200049F5E114F104A1F1BB2400E010E06E01E0 +:101830000894C11CD11CCCD8F601E00FF11F8083A5 +:10184000B3940B2D10E00E151F05A8F3E0910721AE +:10185000F0910821C601099584E6A096CDBFDEBFB0 +:10186000DF91CF911F910F91FF90EF90DF90CF907C +:10187000BF9008956E010894C11CD11CC60160E29E +:1018800070E0A80104D98E159F0501F38AECE5CF1D +:101890006E010894C11CD11CD9CFFC0180910C2190 +:1018A000882329F480E38083118285E6089581E30B +:1018B0008083118285E60895FC018181882339F4B3 +:1018C0008081813331F0803349F08AEC08958AECCD +:1018D000089581E080930C2184E6089510920C21F4 +:1018E00084E6089582E698E02CD18EE6089580E99A +:1018F00098E03FD18EE60895E0ECF4E081818E7FA0 +:1019000081830E9478220E94F00384E60895E0EC2F +:10191000F4E081818E7F81830E9478220E94F70308 +:1019200084E608952DB73EB7285030402DBF3EBF06 +:10193000EDB7FEB73196ADB7BEB711968D939C93B8 +:10194000129780E091E0828393838EE094E0848319 +:1019500095838091092190910A21868397830E9423 +:101960000C262DB73EB7285F3F4F2DBF3EBF85E603 +:1019700008952DB73EB7285030402DBF3EBFEDB77C +:10198000FEB73196ADB7BEB711968D939C93129763 +:1019900080E091E08283938381E194E08483958366 +:1019A00080910B21868317820E940C262DB73EB7AB +:1019B000285F3F4F2DBF3EBF85E6089560E071E090 +:1019C000C2DC85E6089560E071E0F3DC85E6089509 +:1019D00003DD882311F48AEC08954FDD84E6089531 +:1019E00060E071E0D1DD85E60895D8DD882311F44B +:1019F0008AEC089542DD84E60895FEDA84E60895CF +:101A0000BF92CF92DF92EF92FF920F931F93CF93EB +:101A1000DF937C01CFEFD0E02BE1C22E24E0D22E69 +:101A20003CE2B32E86018CE190E2B6010E94EB25E8 +:101A3000009729F1F6018491882389F0C132D105FC +:101A400070F0D70103C0C032D10549F08D937D01FC +:101A50000F5F1F4F2197F80184918823A1F7F701A9 +:101A6000B1927F01219786E190E0C80ED91E8601D0 +:101A70008CE190E2B6010E94EB250097D9F6F701C0 +:101A80003197108285E6DF91CF911F910F91FF90E2 +:101A9000EF90DF90CF90BF900895CF93DF93209188 +:101AA00020022068E0E0F2E020A32091230220FF42 +:101AB000FCCF21E0E0E0F2E023A3609110027091FE +:101AC00011022DB73EB7285030402DBF3EBFCDB7D5 +:101AD000DEB72196EDB7FEB78183928380E091E077 +:101AE0008A839B8384E194E08C839D836E5B70404A +:101AF00077FD1AC0882777FD8095982F29E637E56E +:101B00004BE050E00E946525DC01CB01AE83BF8332 +:101B10000E940C262DB73EB7285F3F4F2DBF3EBF1A +:101B200085E6DF91CF91089560E070E0E3CF80E03B +:101B3000E0E2F1E29191890F91E2E03AF907D1F701 +:101B4000089521E02093A5202093A62024E120934E +:101B5000A72025E02093A8201092A9201092AA2067 +:101B60001092AB201092AC208093AD209093AE20C9 +:101B7000089527E02093A52024E62093A820109222 +:101B8000A9201092AA201092AB201092AC20809332 +:101B9000AD209093AE200895CF93C82F8091A520BB +:101BA000853009F484C08630E8F0873009F44EC0EF +:101BB000873070F52091B2208091A620281709F473 +:101BC000E1C030E090E001972817390709F40BC114 +:101BD00080E090E268E10E9471241092A52081E0EB +:101BE000CF910895833009F45AC08430C0F08C2F0F +:101BF00090E04091B2202FEF30E0241B3109821792 +:101C0000930709F06BC085E08093A52081E0E8CFC1 +:101C10008830F9F08930A9F080E0CF9108958130C3 +:101C2000D8F3C13009F4E9C0C43009F4FBC0C831AD +:101C300041F081E0CF91089580E090E266E00E945B +:101C400071241092A52081E0CF910895C53109F447 +:101C50004FC0C83189F3C63009F4F3C0C53149F724 +:101C600080E090E261E00E94712480E090E2609167 +:101C7000A6200E9471246091A620609580E090E2E9 +:101C80000E94712480E291E260E870E0AFDC4FDFF7 +:101C9000682F80E090E20E94712481E0A1CFC09380 +:101CA000B22084E08093A52081E0CF910895209117 +:101CB000AF203091B020F901E05EFE4DC083C90134 +:101CC00001968093AF209093B0208038910509F061 +:101CD000B0CF86E08093A52081E082CF80E090E2C3 +:101CE00065E10E94712482E08093A52081E078CF95 +:101CF00081E08093A6204091A9205091AA20609174 +:101D0000AB207091AC20E091AD20F091AE2080E24C +:101D100091E220E830E00995882309F479C080E059 +:101D200090E261E00E94712480E090E26091A62040 +:101D30000E9471246091A620609580E090E20E944C +:101D4000712480E291E260E870E050DCF0DE682F00 +:101D500080E090E20E9471248091A9209091AA20B5 +:101D6000A091AB20B091AC2080589F4FAF4FBF4F98 +:101D70008093A9209093AA20A093AB20B093AC208D +:101D800081E02ECFD4DE8C1709F0A8CF4091A92096 +:101D90005091AA206091AB207091AC20E091AD20D1 +:101DA000F091AE2080E291E220E830E009958823AE +:101DB00009F441C08091A6208F5F8093A620809176 +:101DC000A9209091AA20A091AB20B091AC2080587E +:101DD0009F4FAF4FBF4F8093A9209093AA20A0930D +:101DE000AB20B093AC2080E090E266E00E947124CA +:101DF00082E08093A52081E0F3CE1092AF20109274 +:101E0000B0201092B12083E08093A52081E0E8CE3D +:101E100080E090E264E00E94712489E08093A52034 +:101E200081E0DECE80E090E266E00E9471241092B4 +:101E3000A52081E0D5CE80E090E268E10E94712487 +:101E4000C7CE8091A6208F5F54CF8091A52081308E +:101E500071F0873009F008958091A820982F915053 +:101E60009093A8208823B9F71092A5200895809117 +:101E7000A820982F91509093A820882361F78091F3 +:101E8000A720982F91509093A720882331F4109287 +:101E9000A52085E08093A820089580E090E265E188 +:101EA0000E947124F6CF1F93CF93DF93982F915404 +:101EB0009A3120F090529A31B8F480522091B32098 +:101EC0003091B4202F3F310550F4F901E05EFE4D12 +:101ED00080832F5F3F4F2093B3203093B42081E065 +:101EE000DF91CF911F9108959F5C9A3038F38F3521 +:101EF00029F38F3319F38D3309F38D30A9F088302E +:101F000039F08B3161F71092B3201092B420E7CFF3 +:101F10008091B3209091B420009709F301978093AA +:101F2000B3209093B420DBCFE091B320F091B420A4 +:101F3000E05EFE4D10821092B3201092B42080918A +:101F40002021882309F4A7C08F3309F4A4C08D335E +:101F500009F4A1C0E1E2F1E2EF01219706C08F335D +:101F600009F4D3C08D3309F4CEC021968191882322 +:101F7000B1F710E0188280E291E26BE174E00E9418 +:101F8000EB25009709F420C180E291E261E374E05F +:101F90000E94EB25009709F415C180E291E267E405 +:101FA00074E00E94EB25009709F406C180E291E2FB +:101FB0006DE574E00E94EB25009709F4FBC080E218 +:101FC00091E263E774E00E94EB25009709F4F0C00A +:101FD00080E291E269E874E00E94EB25009709F441 +:101FE000B5C080E291E26FE974E00E94EB250097B2 +:101FF00009F4FAC080E291E265EB74E00E94EB25FF +:10200000009709F4EFC080E291E26BEC74E00E946B +:10201000EB25009709F4E4C080E291E261EE74E000 +:102020000E94EB25009709F4D9C080E291E267EFA6 +:1020300074E00E94EB25009709F4CEC080E291E2A3 +:102040006DE075E00E94EB25009709F4C3C080E2C3 +:1020500091E263E275E00E94EB25009709F4B8C0B5 +:1020600080E291E269E375E00E94EB25009709F4B4 +:10207000ADC080E291E26FE475E00E94EB2500972D +:1020800009F49EC080E291E265E675E00E94EB25CE +:10209000009709F493C088ECC0E0E1E8F5E0949182 +:1020A000891709F450C0B196E4918E1709F448C01D +:1020B000E3ECF5E0E4918E1709F43FC0E4EEF5E0BF +:1020C000E4918E1709F436C0E5E0F6E0E4918E174E +:1020D00071F1E6E2F6E0E4918E17C9F080E090E05D +:1020E00071DA8BE795E06EDACC2309F4F8CE8091B3 +:1020F0002021882309F4F3CE80E291E25EDA8EE7B4 +:1021000095E060DAECCE1DE335CF1FE333CF25E059 +:1021100030E0C901880F991F82959295907F98278A +:10212000807F9827820F931F8E579A4FD9CF24E034 +:1021300030E0EFCF23E030E0ECCF22E030E0E9CF39 +:1021400021E030E0E6CF20E030E0E3CF25E0109260 +:10215000202130E046E150E0249FC001259F900DF2 +:10216000349F900D1124855E9B4F1F33F9F01D3372 +:1021700089F0112319F089ECC1E08FCF4096FC0162 +:1021800085919491FC010097B1F380E291E2099569 +:10219000C1E083CF4296FC0185919491FC010097A8 +:1021A00051F3CE0101960995C1E077CF4496E7CF70 +:1021B00024E0CDCF23E0CBCF22E0C9CF2FE0C7CFA3 +:1021C0002EE0C5CF21E0C3CF20E0C1CF2DE0BFCFAF +:1021D0002CE0BDCF2BE0BBCF2AE0B9CF29E0B7CFB1 +:1021E00028E0B5CF27E0B3CF26E0B1CF0895A0E235 +:1021F000B6E082E011968C93119715968C93159703 +:10220000E0E4F8E010A211A28DE291E086A397A38A +:102210008FEF9FEF80A791A781E0808398E8938359 +:1022200093E097831A968C931A9708951F920F92B2 +:102230000FB60F9211248F939F93EF93FF9380E239 +:1022400092E28093C1209093C22080EA92E2809330 +:10225000C3209093C4201092BA201092B9201092FB +:10226000B5201092BD201092BE201092B820E0E45C +:10227000F8E0138286E990E086AB97AB8AE190E0C4 +:1022800080AF91AFE0E4F9E010A211A28FEF9FEFD1 +:1022900086A397A389E883838EE08083E0E2F6E05B +:1022A0001286FF91EF919F918F910F900FBE0F902B +:1022B0001F9018951F920F920FB60F9211242F9313 +:1022C0008F939F93EF93FF93909128068091B9206D +:1022D000880F957021E009F020E0822B8093B920CF +:1022E0009091B5209923A1F1982F9770973009F418 +:1022F00044C08C7069F191E082FD6EC09093B7206C +:102300008091B820882309F06FC08091BA2086950B +:10231000992309F471C020E8282B2093BA208091DA +:10232000BD209091BE2001968093BD209093BE2049 +:1023300087709070009761F4E091C120F091C22005 +:102340002193E093C120F093C22081E08093B820D4 +:102350009091B52081E0911180E08093B52088E8CC +:10236000E0E4F8E08383FF91EF919F918F912F91AB +:102370000F900FBE0F901F9018951092400880E1AB +:10238000E0E4F8E08487E0E4F9E013828091B7208C +:10239000882369F18CEB94E086A397A31092B62072 +:1023A000E0E4F9E081E0848783E086838091BD20CA +:1023B0009091BE20877061F09091BA208F5F9695C2 +:1023C0008F5F8930E1F7E091C120F091C2209083C6 +:1023D00081E08093BF20BCCF90E09093B7208091A4 +:1023E000B820882309F491CF1092B820B1CF8CE7A0 +:1023F00094E086A397A3D2CF20E08ECF1F920F92B6 +:102400000FB60F9211242F933F938F939F93AF9307 +:10241000BF93EF93FF938091B620853009F455C0A8 +:102420008630C0F0883009F486C0893040F58630A7 +:1024300009F4C7C0873009F495C0FF91EF91BF91AF +:10244000AF919F918F913F912F910F900FBE0F9061 +:102450001F901895823089F1833008F1833009F498 +:102460005BC0843051F78091BA2080FDC7C080E402 +:10247000E0E4F6E0868385E08093B620DECF893005 +:1024800009F461C08A30C9F610924009E0E4F9E02D +:1024900016821092000881E08093C020CECF88235E +:1024A00009F459C0813049F68FE390E0E0E4F9E0A7 +:1024B00086A397A38EE08093000880E4E0E4F6E032 +:1024C000858383E08093B620B8CF8091BA2090E4D2 +:1024D000E0E4F6E080FD90C0958386958093BA2075 +:1024E0008091BB209091BC2001968093BB2090935B +:1024F000BC209C01277030702115310509F483C080 +:102500002091BD203091BE208217930709F055C05D +:1025100088E08093B62091CF80E4E0E4F6E0868303 +:1025200084E08093B620E091C120F091C2208081A8 +:102530008093BA2082CF80E4E0E4F6E0868389E0ED +:102540008093B6207ACF80E4E0E4F6E086838AE0E8 +:102550008093B62072CF8FE790E0E0E4F9E086A3A5 +:1025600097A36BCFE091C320F091C4208081882392 +:10257000E1F580E4A0E4B6E015968C9315972091E0 +:10258000BB203091BC208091BD209091BE202817A7 +:10259000390709F4BDCF3196E093C320F093C420EE +:1025A000E091C120F091C220CF0101968093C1201B +:1025B0009093C22081818093BA2084E08093B620DA +:1025C0003CCFE091C320F091C4208081882341F466 +:1025D00080E4E0E4F6E0868387E08093B6202DCFA8 +:1025E00080E4E0E4F6E08583F7CF80E4A0E4B6E0A1 +:1025F00016968C931697C3CF96836FCF80E4E0E452 +:10260000F6E0858338CF86E08093B62016CFCF934F +:10261000DF93E0E4F6E084E08283128AC0E8D1E050 +:1026200082E68E83A0E2B6E085E012968C93129744 +:1026300081E050968C93509782E052968C935297FB +:102640001A961C921A9783E019968C9398E59883B2 +:102650009AE5998390E49183968381838683E0E071 +:10266000F8E08FE090E086A397A388E090E082A74F +:1026700093A783E28183BBDDDF91CF9108958091A1 +:10268000BF208823C9F01092BF20E0E2F6E082E08C +:10269000818386836091BD207091BE206115710594 +:1026A00099F4E091FF20F0910021099510924009E2 +:1026B000E0E4F9E016829BDD8091C020882309F4D4 +:1026C00008951092C02093CDE0910321F091042150 +:1026D00080E292E209959C0194FD28C0AC015695D8 +:1026E0004795569547955695479541155105F9F0EB +:1026F00060E0E0E0F0E0E05EFD4D8081082E829534 +:102700008025082E869586958025E058FF4F90E01D +:1027100001969595879591E080FD90E090836F5F9D +:10272000E62FF0E0E417F50730F301C03F7E2115F6 +:10273000310509F4BBCF2093BD203093BE20109209 +:10274000BB201092BC2080E292E28093C120909343 +:10275000C22080EA92E28093C3209093C42081E05B +:102760008093B6208091C020882309F4A9CFA9CFF7 +:1027700081E08093C52084E090E08093C620909310 +:10278000C72088E08093C820089581E08093C52009 +:1027900082E090E08093C6209093C72088E18093E8 +:1027A000C820089581E08093C520089508958F92F0 +:1027B0009F92AF92BF92CF92DF92EF92FF920F93D0 +:1027C0001F93CF93DF93CDB7DEB72E97CDBFDEBF7C +:1027D0007C018091C520843009F4F9C0853008F46B +:1027E0003FC0863009F4C0C0863008F064C0F701ED +:1027F00000810E94081C8027D7018C9311960C91B0 +:102800000E94081C8027F701818302810E94081C16 +:102810008027D70112968C93129713960C91F8D7B4 +:102820008027F70183838081803309F4BDC2803A19 +:1028300009F439C3803C09F453C3813C09F435C41D +:10284000823C09F43FC4803B09F44BC4805682307B +:1028500008F496C181E08093C52080E090E065C0D7 +:10286000823009F4A0C0833008F46FC0F701808182 +:10287000863209F46FC1823509F46CC1803509F4E0 +:1028800075C1982F9056923008F4E7C1803351F00B +:10289000803A41F0803C31F0813C21F0823C11F0E3 +:1028A000803BC1F681E08093C52084E0F7018083FE +:1028B00084E090E03AC08A3008F053C0F70100810C +:1028C000A7D78027D7018C9311960C91A1D7802789 +:1028D000F701818302819CD78027D70112968C93C0 +:1028E000129713960C9194D78027F7018383048164 +:1028F0008FD78027D70114968C93149715960C9137 +:1029000087D78027F7018583C70164E070E092D400 +:10291000882309F00FC2BDD791E09827F701908373 +:1029200085E08093C52084E090E02E96CDBFDEBF89 +:10293000DF91CF911F910F91FF90EF90DF90CF909B +:10294000BF90AF909F908F9008952091C620909156 +:10295000C720D7018C91863209F4F3C0823509F47F +:10296000F0C080E090E0E1CF8701CC24F8018080C6 +:102970004FD78825D8018D938D01C394B2E1CB1632 +:10298000A9F7C70160E170E055D4882309F4EFC1CD +:1029900080910C21882309F4F0C17BD79AE0982715 +:1029A000F7019083BDCF2091C6209091C720D70119 +:1029B0008C91863209F4C5C0823509F4C2C08339CE +:1029C00009F435C21092C52080E090E0AECFC70177 +:1029D000E0D6D70114960C911BD78027F70184838A +:1029E000058116D78027D70115968C9315971696D3 +:1029F0000C910ED78027F7018683078109D780279E +:102A0000D70117968C93179714962C911497909141 +:102A1000C920291709F01ECF15962C911597909172 +:102A2000CA20291709F016CF16962C911697909167 +:102A3000CB20291709F00ECF9091CC20891709F0EF +:102A400009CF0091CD20E4D68027F7018083009143 +:102A5000CD20002E02950025002E06950695002516 +:102A60009ED4F701E058FF4F202F30E02F5F3F4FFB +:102A70003595279591E020FD90E09827908300916F +:102A8000CE20C6D68027D70111968C930091CE20F8 +:102A9000002E02950025002E0695069500257FD470 +:102AA000F701EF57FF4F202F30E02F5F3F4F359555 +:102AB000279591E020FD90E0982790830091CF200A +:102AC000A7D68027F70182830091CF20002E0295A0 +:102AD0000025002E06950695002561D4F701EE57D6 +:102AE000FF4F202F30E02F5F3F4F3595279591E026 +:102AF00020FD90E0982790830091D02089D68027F0 +:102B0000D70113968C930091D020002E02950025BA +:102B1000002E06950695002542D4F701ED57FF4F8C +:102B2000202F30E02F5F3F4F3595279591E020FD16 +:102B300090E09827908385E08093C52080E290E123 +:102B4000F4CEF7012083918382E08093C52080E159 +:102B500090E0EBCE84E0D7018C9311961C921197F4 +:102B600082E08093C52080E190E0DFCEF701818193 +:102B7000882309F4D7C2F701108284E090E0D5CE13 +:102B8000C70162E070E056D3882309F405C1D7017C +:102B900011960C9111970C738C91803609F4DFC259 +:102BA0008AE390E010E002951295107F1027007FD5 +:102BB0001027080F191FCE01059664E00E94EB0450 +:102BC000CE01019660E070E044E050E00E941D06F6 +:102BD000CE010996B80146E050E00E941D068D81A5 +:102BE0008093C9208E818093CA208F818093CB20CF +:102BF00088858093CC2089EC90E260E470E06DD60B +:102C00008091C9208093CD208091CA208093CE20CE +:102C10008091CB208093CF208091CC208093D020B6 +:102C20008DEC90E260E270E058D6CE010996BE01CC +:102C30006F5F7F4FAE014B5F5F4FE5D38D81F70133 +:102C400080838E8181838F8182838885838384E0E2 +:102C50008093C52080E290E068CEC70162E070E01A +:102C6000E9D2882309F465C2D70111960C91119716 +:102C70000C738C91803609F475C28AE390E010E001 +:102C800002951295107F1027007F1027080F191F3B +:102C9000CE01019664E00E94EB04CE01059660E04F +:102CA00070E044E050E00E941D06CE010996B80194 +:102CB00046E050E00E941D0689818093C9208A81E8 +:102CC0008093CA208B818093CB208C818093CC20F1 +:102CD00089EC90E260E470E000D68091C920809396 +:102CE000CD208091CA208093CE208091CB208093EC +:102CF000CF208091CC208093D0208DEC90E260E2B8 +:102D000070E0EBD584E08093C5208981F701808352 +:102D10008A8181838B8182838C818383CE01099612 +:102D2000BE016B5F7F4FAE014F5F5F4F6CD380E2A0 +:102D300090E0FBCD6091D12070E062957295707F3C +:102D40007627607F762782ED90E240E150E00E9496 +:102D50001D062091D2208091D6208095281709F455 +:102D6000D6C097D596E09827D7019C93D9CD91D519 +:102D700091E09827D7019C93D3CD6091D12070E04A +:102D800062957295707F7627607F7627C70140E154 +:102D900050E00E94A80601CE7CD591E09827D7018B +:102DA0009C9384E090E0C1CDC70162E070E042D224 +:102DB000882391F3D70111966C9170E0629572951A +:102DC000707F7627607F7627C70140E150E00E9440 +:102DD0001D06C70160E170E0EFD1870130E8E32E06 +:102DE000F12CE00EF11E8824F801C08011D58C254D +:102DF000D8018D938D010C2CC294C0240C2CC69448 +:102E0000C694C024CCD22C2D30E02F5F3F4F359597 +:102E1000279591E020FD90E09827F70191937F019D +:102E20008394F2E18F1601F780E990E17ECDCE0127 +:102E3000059660E070E044E050E00E941D0690912D +:102E4000C820D70111968C911197803209F477C16F +:102E5000803709F086CDD70112962C9112978D817B +:102E6000281709F07ECD13962C9113978E81281781 +:102E700009F077CD14962C9114978F81281709F0BB +:102E800070CD15962C9115978885281709F069CD76 +:102E90009C93C70161E070E08FD183E08093C520EF +:102EA00088E190E042CDC70162E070E0C3D18823A1 +:102EB00079F0F70181818093D12086E08093C5204D +:102EC000E8D49AE09827D7019C9384E090E02DCD38 +:102ED000E0D491E09827F701908384E090E025CD3D +:102EE000C70162E070E0A6D1882309F455CFD7016D +:102EF00011968C918093D12088E08093C520C9D40D +:102F00009AE09827F701908384E090E00ECD8091BD +:102F1000DA20281709F025CF3091D3208091D720CF +:102F20008095381709F01DCF8091DB20381709F004 +:102F300018CF4091D4208091D8208095481709F06F +:102F400010CF8091DC20481709F00BCFE091D520FD +:102F50008091D9208095E81709F003CF8091DD207A +:102F6000E81709F0FECE9091DE208091DF20809559 +:102F7000981709F0F6CE8091E020981709F0F1CE6D +:102F80008091E1208095981709F0EBCED70111963A +:102F90008C9011979924AA24BB24BA2CA92C982C84 +:102FA000882412968C9190E0A0E0B0E0DC01992793 +:102FB0008827882A992AAA2ABB2AD7018C9190E0CF +:102FC000A0E0B0E0882A992AAA2ABB2AD701139642 +:102FD000CC90DD24EE24FF24FC2CEE24DD24CC2434 +:102FE0008C289D28AE28BF28832F90E0A0E0B0E079 +:102FF000BA2FA92F982F882750E060E070E0BA011F +:1030000055274427842B952BA62BB72B30E040E087 +:1030100050E0822B932BA42BB52B4E2F50E060E079 +:1030200070E0742F662755274427842B952BA62BF9 +:10303000B72B2091C520283009F46FC0273021F428 +:10304000880D991DAA1DBB1D8093D220092F1A2F10 +:103050002B2F33270093D320AD016627772740938A +:10306000D420CB2EDD24EE24FF24C092D520E82FDF +:10307000E095E093D620E02FE095E093D720E42F71 +:10308000E095E093D820EC2DE095E093D920809353 +:10309000DA200093DB204093DC20C092DD2085E025 +:1030A0008093C52080E090E040CCC70162E070E0F2 +:1030B000C1D0882309F40CCFF70181818093D120FE +:1030C00087E0FCCEC70162E070E0B4D0882309F449 +:1030D00063CED70111968C9111978093D12089E00E +:1030E0000CCFC70162E070E0A5D0882309F4F0CED0 +:1030F00080910C21882309F0E3CEF701618170E013 +:1031000062957295707F7627607F762782ED90E2D8 +:1031100040E150E00E94A806D3CE88199909AA0977 +:10312000BB0992CFC70162E070E084D0882309F028 +:1031300049CC81E0D7018C9384E090E0F6CB8D817F +:10314000F70180833E8131832F8122839885938389 +:10315000832782278927848388E290E0E6CB80E377 +:1031600090E020CD80E390E08ACD60E070E044E024 +:1031700050E00C941D06CF93DF930F92CDB7DEB7CE +:10318000FC018181908189279281892793818927F8 +:103190008983CF0160E070E044E050E00E94A8061F +:1031A000CE01019664E070E041E050E00E94A80684 +:1031B0000F90DF91CF910895EF92FF920F931F939D +:1031C000CF937C018B016115710581F1FB01DC015D +:1031D00043E653E68D918427C82FC295C07FC82748 +:1031E0008C2F90E0782F66279C01220F331F220F2F +:1031F000331F220F331F62277327452F552746277A +:103200005727C295CF708C2F90E0482759273197C8 +:1032100009F7F701E00FF11F942F852F9083818329 +:10322000CF911F910F91FF90EF900895FC0183E6DD +:1032300093E6F4CFEF92FF920F931F93CF937C010D +:103240008B016115710509F43DC0FB01DC0143E60A +:1032500053E68D918427C82FC295C07FC8278C2F35 +:1032600090E0782F66279C01220F331F220F331F17 +:10327000220F331F62277327452F552746275727CD +:10328000C295CF708C2F90E048275927319709F7C6 +:10329000F701E00FF11F9A013070808190E08217F2 +:1032A000930739F080E0CF911F910F91FF90EF903D +:1032B0000895218130E0452F552781E024173507F7 +:1032C00089F7F1CFFC0123E630E043E653E6E5CF92 +:1032D000CF92DF92EF92FF920F931F930091E52020 +:1032E0004091E6203091E720A091E220F091E32088 +:1032F000E091E420942F9071202F217E9227232F9C +:10330000207292272A2F247992272F2F2377922712 +:103310002E2F2A739227292F22952F702927922F3B +:10332000969596959227B92FB69550E060E070E09B +:10333000762F652F542F4427C32EDD24EE24FF243F +:103340007601DD24CC244C295D296E297F2910E0EB +:1033500020E030E0402B512B622B732B7695679544 +:1033600057954795B9272B2F30E02170307090E0AA +:103370002817390709F06068A093E520F093E6204C +:10338000E093E7204093E2205093E3206093E42011 +:103390001F910F91FF90EF90DF90CF900895509183 +:1033A000E3204091E420242F2F708DE190E2DC0196 +:1033B000A20FB11D252F2F70FC01E20FF11DD09639 +:1033C0002C91D0973089232B3091E22032953F7099 +:1033D000FC01E30FF11D3081232B52955F70FC013E +:1033E000E50FF11D30A1232B42954F70840F911DE5 +:1033F000805C9F4FFC018081282BEDE6F0E2E20F1C +:10340000F11D80810895CF92DF92EF92FF920F938A +:103410001F93CF93DF93FC01EA01318120E080818B +:1034200090E0822B932B80FDB2C130E081FDADC1D5 +:1034300020E09695879596958795432F406880FD67 +:10344000342F422F406881FD242F969587959695BD +:10345000879536952695432F406880FD342F422F5F +:10346000406881FD242F969587959695879536958A +:103470002695432F406880FD342F422F406881FD00 +:10348000242F969587959695879536952695432F63 +:10349000406880FD342F422F406881FD242F96958F +:1034A00087959695879536952695432F406880FD9C +:1034B000342F422F406881FD242F9695879596954D +:1034C000879536952695432F406880FD342F422FEF +:1034D000406881FD242F969587959695879536951A +:1034E0002695532F5068422F406880FD352F30932A +:1034F000E52081FD242F2093E220338120E082818A +:1035000090E0822B932B80FD3EC130E081FD39C1DC +:1035100020E09695879596958795432F406880FD86 +:10352000342F422F406881FD242F969587959695DC +:10353000879536952695432F406880FD342F422F7E +:10354000406881FD242F96958795969587953695A9 +:103550002695432F406880FD342F422F406881FD1F +:10356000242F969587959695879536952695432F82 +:10357000406880FD342F422F406881FD242F9695AE +:1035800087959695879536952695432F406880FDBB +:10359000342F422F406881FD242F9695879596956C +:1035A000879536952695432F406880FD342F422F0E +:1035B000406881FD242F9695879596958795369539 +:1035C0002695532F5068422F406880FD352F309349 +:1035D000E62081FD242F2093E320958180E0248143 +:1035E00030E0282B392B20FDCAC050E021FDC5C09A +:1035F00040E0C9019695879596958795352F306857 +:1036000080FF352F242F206881FF242F96958795E2 +:103610009695879536952695432F406880FD342FE3 +:10362000422F406881FD242F969587959695879522 +:1036300036952695432F406880FD342F422F4068F1 +:1036400081FD242F96958795969587953695269595 +:10365000432F406880FD342F422F406881FD242F86 +:10366000969587959695879536952695432F40682C +:1036700080FD342F422F406881FD242F9695879539 +:103680009695879536952695432F406880FD342F73 +:10369000422F406881FD242F9695879596958795B2 +:1036A00036952695532F5068422F406880FD352F60 +:1036B0003093E72081FD242F2093E420C980DB0193 +:1036C00011968C911197C826DD24EE24FF24FE2C40 +:1036D000ED2CDC2CCC248A8112969C91892790E0D9 +:1036E000A0E0B0E0DC0199278827C82AD92AEA2A75 +:1036F000FB2A8881FB019081892790E0A0E0B0E05F +:10370000C82AD92AEA2AFB2A8B819381892790E04B +:10371000A0E0B0E0B82FAA2799278827C82AD92A7D +:10372000EA2AFB2A10E23BDE082F8C2D8170D0DDC7 +:10373000F694E794D794C794002341F080E090E09A +:10374000A0E0B0E8C82AD92AEA2AFB2A115059F782 +:1037500088818C25888389818D2589838A818E251E +:103760008A838B818F258B83DF91CF911F910F915E +:10377000FF90EF90DF90CF90089540E43ACF50E46F +:1037800035CF20E4C6CE30E4C1CE20E452CE30E4C2 +:103790004DCECF92DF92EF92FF92CF93FC01C1808A +:1037A000DD24EE24FF24FE2CED2CDC2CCC248281A5 +:1037B00090E0A0E0B0E0DC0199278827C82AD92A48 +:1037C000EA2AFB2A808190E0A0E0B0E0C82AD92A4A +:1037D000EA2AFB2A838190E0A0E0B0E0B82FAA2774 +:1037E00099278827C82AD92AEA2AFB2AC0E2D7DDE6 +:1037F0009C2D917089276CDDF694E794D794C7943B +:10380000C150A9F7CF91FF90EF90DF90CF9008952E +:10381000CF93DF93C4DDC82F80E05ADDCC2309F4B9 +:1038200036C0C0E8BCDDD82F80E052DDC695D1118E +:10383000C068B5DDD82F80E04BDDC695D111C068DA +:10384000AEDDD82F80E044DDC695D111C068A7DD7C +:10385000D82F80E03DDDC695D111C068A0DDD82FFE +:1038600080E036DDC695D111C06899DDD82F80E0A3 +:103870002FDDC695D111C06892DDD82F80E028DDFC +:103880008C2F8695D1118068DF91CF910895C0E08B +:10389000C9CFCF93DF9383DDC82F80E019DDCC2320 +:1038A000D1F0C8E07CDDD82F80E012DDC695D111C3 +:1038B000C86075DDD82F80E00BDDC695D111C860DA +:1038C0006EDDD82F80E004DD8C2F8695D1118860C5 +:1038D000DF91CF910895C0E0E5CF8F929F92AF9294 +:1038E000BF92CF92DF92EF92FF920F931F93CF93ED +:1038F000DF934C015B016115710509F45FC0DC01C8 +:103900001296CC911297EC911196DC911197139627 +:10391000FC919C2F9D72892F82958F708927282F6B +:10392000269526952827322F36958D2F90E0A0E0FA +:10393000B0E0BA2FA92F982F88274C2F50E060E0D5 +:1039400070E0BA0155274427842B952BA62BB72B63 +:103950004E2F50E060E070E0842B952BA62BB72B08 +:103960004F2F50E060E070E0742F66275527442702 +:10397000842B952BA62BB72BB695A7959795879556 +:10398000322730FDB068E82F492F5A2F6B2F772749 +:10399000D42F8D0122273327C02FCB2EDD24EE24F8 +:1039A000FF24FC2D0894A108B108A114B10409F06A +:1039B000B0CFF401808341830283C382DF91CF9132 +:1039C0001F910F91FF90EF90DF90CF90BF90AF903D +:1039D0009F908F9008951F93CF93DF93CDB7DEB75D +:1039E000EE97CDBFDEBF4DD3809325234AD380937E +:1039F000262347D38093272344D38093282341D37E +:103A0000809329233ED380932A233BD380932B2377 +:103A100038D380932C230E94700BD5D3882391F048 +:103A20009091252380912623853009F453C0863058 +:103A3000A8F0883009F4BAC0893009F49EC08630F5 +:103A400009F45DC0C0D3882311F091D374D3EE96EE +:103A5000CDBFDEBFDF91CF911F910895813029F056 +:103A6000813008F46EC0833069F7992309F4A8C047 +:103A7000923041F780912723882339F5109129232B +:103A80001F7001F3812F1BD380912623833009F40B +:103A9000F8C0E0912F23F091302381818B7F8183C7 +:103AA000212F30E084E890E0289FF001299FF00D5D +:103AB000389FF00D1124ED58FC4D1082E0912F231A +:103AC000F091302380818E7F808380E0F8D24FD3C5 +:103AD000A8D4B8CF992309F0B5CF109127231F7729 +:103AE00046D39FD4A0D38823E9F3E0ECF4E013831A +:103AF000112309F07AC082E080932423A3CF905849 +:103B0000923008F09FCF809127239091282323E0C3 +:103B10008C3D920709F46BC060912923AE014F5F81 +:103B20005F4F0E947A03BC01009709F48BCF8DAFE1 +:103B30007EAF1DD389819A816DAD7EADCAD192D2FF +:103B400081CF903809F448C0923809F07BCF80913A +:103B500029238F70B4D2E0912F23F09130238181FB +:103B600011E082FF10E080E0AAD201D3812F98D229 +:103B700080E096D25ED255D465CF992309F062CF0A +:103B800080912723823008F05DCFF1D280912723E6 +:103B90008093202346D480912023882309F467C092 +:103BA00084E0809324230E946C0B4CCF903809F062 +:103BB00049CFDDD28091202373D23BD232D442CF81 +:103BC00090912723913009F03DCF91E0833009F0A7 +:103BD00090E09093222379CF10912123809122238A +:103BE000882309F4C2CF1260C0CF83E085CF83E081 +:103BF0008C838AE38B836FB7F894A0ECB1E082E00A +:103C00001A968C931A97E8E0F0E024911A961C9289 +:103C1000DE01159681E090E078E040EC51E012E0A2 +:103C2000E22FEF702E2F30E0EA30A8F0295C3F4FF2 +:103C30002D933D938C31910589F0FA011287E72F7E +:103C4000F0E02491FA01128680FF03C022952F70C4 +:103C50007F5F0196E5CF205D3F4FEACF6FBF87D2F0 +:103C6000CE0103966AE370E08FD0FCD1EBCE809159 +:103C7000C304882321F084E08093242394CF81E03F +:103C8000FBCF59D222CF0895CF938091242388234C +:103C900011F4CF910895C091312380E010D293D2D6 +:103CA000882321F48C2F0BD2CF91089594DEFACF84 +:103CB000AF92BF92CF92DF92FF920F931F93CF9359 +:103CC000DF93EC018B016A01C2D3F82E882361F5E2 +:103CD000C114D10439F0F60180819181081B190BC0 +:103CE000C80FD91F01151105F9F0C114D10441F015 +:103CF00026C08991D5D10150104001151105A1F0C0 +:103D000080912D2390912E23FC01EF5BFF4F2081AA +:103D1000805C9F4FFC018081281758F38AD1B4DF63 +:103D200096D3882351F3F82E8F2DDF91CF911F91D9 +:103D30000F91FF90DF90CF90BF90AF900895AA248D +:103D4000BB2480912D2390912E23FC01EF5BFF4F2C +:103D50002081FC01E05CFF4F8081281760F069D171 +:103D600093DFF601808191818A0D9B1D8083918371 +:103D700025E0F22ED9CF899193D10894A11CB11CD2 +:103D80000A151B05F1F6D0CFCF92DF92EF92FF928A +:103D90000F931F93CF93DF93D82EC92EEB01809101 +:103DA000312380688CD1E0902B23F0902C23EC16EB +:103DB000FD0620F0209709F486C07E0100E0E114A2 +:103DC000F10409F04CC0002309F45FC08091242362 +:103DD000882309F458C0853009F460C0F4D18823E1 +:103DE00009F06FC008D2882309F04FC01CD2882385 +:103DF00069F38091312387FD5BC080912D239091E1 +:103E00002E23FC01E05CFF4FC0818F5B9F4FFC01C4 +:103E10008081D0E0C81BD109E114F104B1F0C830B1 +:103E2000D10598F40D2D1C2D03C0C830D10569F0C3 +:103E3000F80181918F0134D1D02EC12E0894E10870 +:103E4000F1082196E114F10481F701E0C830D105B1 +:103E500009F000E0EED0E114F10409F4B4CF809150 +:103E60002423882381F08530C9F0ADD1882349F51A +:103E7000C2D1882351F4D7D1882309F0BACF8091D9 +:103E80002423882381F782E00AC0B5D18823F9F47E +:103E9000809124238823B9F38530B9F783E0DF913B +:103EA000CF911F910F91FF90EF90DF90CF900895E9 +:103EB000E0912D23F0912E23EF5BFF4FC081D0E0E6 +:103EC000ABCF81E0ECCFB5D0EE24FF2477CF80E0FC +:103ED000E6CFCF92DF92EF92FF920F931F93CF9393 +:103EE000DF930F92CDB7DEB7D82EC92E7B0180911C +:103EF00031238068E4D000912B2310912C230E15E0 +:103F00001F0528F0E114F10409F48DC08701ED2CA0 +:103F1000FC2C80E00115110509F050C0882309F43C +:103F200063C080912423882309F45CC0853009F4A0 +:103F300064C049D1882309F074C05DD1882309F099 +:103F400053C071D1882369F38091312387FD60C00C +:103F500080912D2390912E23FC01E05CFF4FC080C7 +:103F60008F5B9F4FFC018081DD24C81AD1080115A9 +:103F70001105B9F088E0C816D10428F012C0F8E0A5 +:103F8000CF16D10471F0F70184918AD00894E11C16 +:103F9000F11C015010400894C11CD11C01151105E1 +:103FA00071F781E098E0C916D10409F080E08983B7 +:103FB00040D089810115110509F4B0CF80912423E7 +:103FC000882381F08530C9F0FED0882351F513D1C4 +:103FD000882351F428D1882309F0B6CF8091242377 +:103FE000882381F782E00AC006D1882301F58091F9 +:103FF00024238823B9F38530B9F783E00F90DF914C +:10400000CF911F910F91FF90EF90DF90CF90089587 +:10401000E0912D23F0912E23EF5BFF4FC080DD2434 +:10402000A6CF81E0EBCF05D000E010E070CF80E0BC +:10403000E5CFE0912F23F0913023A0912D23B09173 +:104040002E23AF5BBF4F8C9190E08283938380815E +:104050008D798083E0912D23F0912E23EF5BFF4F2C +:1040600010820895E0912F23F091302380818D7983 +:104070008083E0912D23F0912E23EF5BFF4F108280 +:10408000089580912D2390912E23FC01EF5BFF4F2B +:104090002081820F911DDC018C912F5F2083089578 +:1040A00020912D2330912E23F901EF5BFF4F90815A +:1040B000290F311DD9018C939F5F90830895282F7C +:1040C0002F708093312330E064E870E0269FA001D8 +:1040D000279F500D369F500D11244E5C5C4D609112 +:1040E000C6047091C70487FD11C040932D235093DF +:1040F0002E2322953295307F3227207F3227260FBC +:10410000371F20932F233093302308954E5B5F4F4A +:1041100040932D2350932E2322953295307F3227C2 +:10412000207F3227285F3F4F260F371F20932F23F2 +:10413000309330230895E0912F23F0913023818133 +:1041400084608183E0912F23F09130238181807CF2 +:10415000803409F00895809131238058B0DFE091D8 +:104160002F23F09130238181846081830895809191 +:1041700031238F77A4DFE0912F23F09130238081CA +:104180008D788083E0912F23F091302380818160AE +:104190008083E0912D23F0912E23EF5BFF4F10825F +:1041A0008091312380688BDFE0912F23F0913023C1 +:1041B000808181608083E0912D23F0912E23EF5B3D +:1041C000FF4F10820895809131238F7778DFE0913F +:1041D0002F23F0913023808184FF0BC0A0912D23E9 +:1041E000B0912E2382819381A05CBF4F8C9381E09C +:1041F000089580E00895809131238F7760DFE0910A +:104200002F23F0913023808185FF0BC0A0912D23B7 +:10421000B0912E2382819381A05CBF4F8C9381E06B +:10422000089580E0089580913123806848DFE0910F +:104230002F23F0913023908181E091FF80E0089559 +:104240001F93CF93DF9300D0CDB7DEB7182F4A83EB +:10425000698335DFE0912F23F09130231182E091C3 +:104260002F23F09130234A81698117FD22C01082EB +:10427000E0912F23F09130236183E0912F23F0917F +:1042800030231282138280912D2390912E238483D8 +:10429000958340E0FC01E05CFF4F40838F5B9F4FC4 +:1042A000DC011C9281E00F900F90DF91CF911F9164 +:1042B000089582E08083E0912F23F0913023618381 +:1042C000E0912F23F09130231282138280912D23CD +:1042D00090912E2384839583DDCFCF92DF92EF924E +:1042E000FF920F931F93CF93DF930F92CDB7DEB75B +:1042F000F62E662309F441C06C0110E0F60100813E +:10430000002399F16381218132818481823008F414 +:1043100041C048E158E12930310550F088E090E093 +:1043200040E04F5F880F991F82179307D0F3452B0A +:10433000802F90E08F709070863091054CF521347D +:10434000310530F54F7E662341F5942F9064E22EBF +:10435000802F8058692F422F998372DF9981802F97 +:10436000692F4E2D6DDF882399F01F5F85E090E067 +:10437000C80ED91E1F1509F0C1CF81E00F90DF9143 +:10438000CF911F910F91FF90EF90DF90CF90089504 +:1043900080E0F4CF48E058E0BECF613031F0942F98 +:1043A00090686623A1F2E22EDACF942F906CE22E71 +:1043B000D6CFE0ECF4E0A681B78119961C92A681D5 +:1043C000B78111961C92A681B78159961C92A6813D +:1043D000B78151961C92A681B78199961C92A681AD +:1043E000B78191961C92A681B781D9961C92A6811D +:1043F000B781D1961C92A681B781A75BBF4F1C9253 +:10440000A681B781AF5BBF4F1C92A681B781A75A27 +:10441000BF4F1C920680F781E02DEF5AFF4F1082AC +:1044200008958091252387FD08C0FDDE882369F467 +:10443000809124238823C9F70895DDDE882331F491 +:10444000809124238823C9F70895F3CD0BCE1F93C1 +:10445000CF93DF93E091C604F091C704E05AFF4F79 +:10446000C081D18114E6809131238078803821F198 +:10447000C2DE882321F580912423882329F1853009 +:1044800041F1E0912F23F0913023818182FD26C0FC +:10449000E091C604F091C704E05AFF4F80819181FA +:1044A000C817D90701F31123F1F01150EC018091E5 +:1044B000312380788038E1F6B6DE8823E1F280E0AF +:1044C000DF91CF911F91089582E0DF91CF911F91ED +:1044D000089583E0DF91CF911F91089581E0DF91EE +:1044E000CF911F91089584E0DF91CF911F9108959E +:1044F00064D06AD0E0ECF4E081818E7F818380819A +:104500008F778083109223230895CF93DF93E0E485 +:10451000F0E014828481816084834FD055D0C0EC58 +:10452000D4E088818F77888388818068888310921F +:104530002423109220231092222310922123888179 +:104540008064888380E868E448E07ADE80E068E49C +:1045500048E076DE888580648887898181608983E8 +:10456000DF91CF910895CF93DF933FB7F894C0ECDC +:10457000D1E022E02A87EAE1F0E0E491A0ECB4E0A7 +:10458000DA96EC93DA97EBE1F0E0E491DB96EC93CA +:10459000DB971A868BE496E28E7F16968D939C931A +:1045A000179785E18C9318962C933FBF81E08093F9 +:1045B0002323ABDFDF91CF910895E0ECF4E0808519 +:1045C0008370808711860895E0ECF4E08FEF828796 +:1045D000848708951F920F920FB60F9211242F9384 +:1045E0003F934F935F936F937F938F939F93AF937B +:1045F000BF93EF93FF938091CA0487FD4FC08091D2 +:10460000CA0486FD42C08091CA0485FF0DC080E2C5 +:10461000E0ECF4E0828780912023882371F184E02C +:10462000809324230E94620BE0ECF4E08091CA04A2 +:1046300084FF12C080E1828782E08093242310925D +:1046400020231382B6DE80E868E448E0F9DD80E0EC +:1046500068E448E0F5DD17DBFF91EF91BF91AF9182 +:104660009F918F917F916F915F914F913F912F918A +:104670000F900FBE0F901F9018958091C304882350 +:10468000B9F481E080932423CDCF80E4E0ECF4E022 +:104690008287109224230E94670BB5CF8091C804B3 +:1046A00087FFADCF80E8E0ECF4E08287ECDAA7CFBB +:1046B00083E0E8CFEF92FF920F931F93CF93DF93A6 +:1046C000EC0181DD882349F0888190E02091292345 +:1046D00030912A232817390739F0DF91CF911F91A4 +:1046E0000F91FF90EF90089580912623813209F475 +:1046F0005FC0823208F04BC0803279F78091252369 +:10470000813259F734DD04C080912423882329F3B2 +:1047100072DD8823C9F3B5DCE82EB3DCF82EB1DCFA +:10472000082FAFDC482F50E060E070E0742F662760 +:104730005527442710E020E030E09801112700279A +:10474000402B512B622B732B8E2D90E0A0E0B0E01C +:10475000482B592B6A2B7B2B8F2D90E0A0E0B0E0EB +:10476000BA2FA92F982F8827482B592B6A2B7B2BE0 +:104770004C8B5D8B6E8B7F8B84DC888F82DC898F8A +:1047800080DC8A8F6FDC4DDECE019ED1A6CF8232D7 +:1047900061F1833209F0A1CF80912523813209F0A4 +:1047A0009CCFE5DC3EDECE01609127238DD195CFF5 +:1047B00080912523813A09F090CFD9DC34DD88231C +:1047C000E9F38C89ED88FE880F896ADC8E2D68DC20 +:1047D0008F2D66DC802F64DC888D62DC898D60DC47 +:1047E0008A8D5EDC26DC1DDE78CF80912523813228 +:1047F00009F073CFBCDC15DE80912723909128232C +:10480000888B998BCE0160D168CFCF93DF93EC0179 +:104810004096FC018BE0DF011D928A95E9F782E06A +:104820008C83898783E08E87CE01019661E055DD18 +:10483000882321F480E0DF91CF910895CE01069680 +:1048400061E04BDD8823B1F3CE010B9661E045DDDD +:10485000DF91CF910895CF93DF93EB012091242333 +:10486000243021F082E0DF91CF910895FC0144894A +:10487000558966897789411551056105710591F35F +:1048800081811DDCFE0101900020E9F73197EC1BCE +:10489000FD0BCE01BF0140E050E00ADAE4CF0F93F8 +:1048A0001F93CF93DF938B01EA01209124232430BF +:1048B00031F082E0DF91CF911F910F910895FC01BB +:1048C00044895589668977894115510561057105C6 +:1048D00081F38181F4DBC801BE0140E050E0E8D9FA +:1048E000E9CFCF93C62F20912423243019F082E002 +:1048F000CF910895FC0144895589668977894115CE +:1049000051056105710599F38181D9DB20912D2332 +:1049100030912E23F901EF5BFF4F9081205C3F4FD8 +:10492000F9018081981720F084DB91DD882301F75D +:104930008C2FB6DB80E0DCCF0F931F93CF93DF93F8 +:104940000F92CDB7DEB720912423243039F082E0D6 +:104950000F90DF91CF911F910F910895FC01448931 +:10496000558966897789411551056105710579F386 +:104970008181A5DB8091312320912D2330912E233D +:10498000F90187FD1DC0E05CFF4F8081F901EF5BFD +:10499000FF4F408190E0841B9109009711F480E063 +:1049A000D7CF0081205C3F4FF901108142DB011716 +:1049B000B0F34DDD882361F689833BDB8981C8CF65 +:1049C000EF5BFF4F808190E0E8CFCF93DF93EC0166 +:1049D00080912423843019F0DF91CF9108958C8940 +:1049E0009D89AE89BF890097A105B105A9F3898189 +:1049F00066DB19DC882381F3CE019EDFEDCFCF93F8 +:104A0000DF9300D0CDB7DEB7FC0180912423843042 +:104A100009F03EC044895589668977894115510559 +:104A200061057105A9F186814ADBE5DB882381F107 +:104A30008091312320912D2330912E23F90187FD80 +:104A40003EC0E05CFF4F8081F901EF5BFF4F40818A +:104A500090E0841B9109009711F58FEF9FEF409133 +:104A6000312347FD29C0205C3F4FD9012C91408163 +:104A700030E0241B31092115310561F489839A83C3 +:104A8000F1DA89819A810F900F90DF91CF9108958B +:104A90008FEF9FEF0F900F90DF91CF910895F1DA94 +:104AA00090E020912D2330912E23F901EF5BFF4FF1 +:104AB0004091312347FFD7CF208130E0DCCFEF5B3F +:104AC000FF4F808190E0C7CF0895629FD001739F10 +:104AD000F001829FE00DF11D649FE00DF11D929F9A +:104AE000F00D839FF00D749FF00D659FF00D9927D9 +:104AF000729FB00DE11DF91F639FB00DE11DF91FFD +:104B0000BD01CF01112408958F929F92AF92BF9261 +:104B1000CF92DF92EF92FF92CF93DF93EC018881E7 +:104B20009981AA81BB810097A105B10521F484E296 +:104B300099EDABE5B7E0BC01CD012DE133EF41E0EC +:104B400050E03DD349015A0127EA31E440E050E00A +:104B5000BCDF6B017C01C501B4012CEE34EF4FEFDB +:104B60005FEFB3DFDC01CB01C80ED91EEA1EFB1ECE +:104B7000F7FE08C08FEF9FEFAFEFBFE7C80ED91E5B +:104B8000EA1EFB1EC882D982EA82FB82C6019F7799 +:104B9000DF91CF91FF90EF90DF90CF90BF90AF90DB +:104BA0009F908F900895B0CF8DE990E2ADCFA0E0B7 +:104BB000B0E080939D2090939E20A0939F20B0937F +:104BC000A0200895FB01DC0102C005900D92415028 +:104BD0005040D8F70895FB01DC018D9105908019B4 +:104BE0000110D9F3990B0895FB01DC0141505040AD +:104BF00048F005900D920020C9F701C01D92415068 +:104C00005040E0F70895FB01DC0102C001900D92D5 +:104C100041505040D8F70895AEE0B0E0E1E1F6E24F +:104C2000F7C20D891E898F89988D2EE02C83098308 +:104C30001A8397FF02C080E090E801978D839E83DE +:104C4000AE01455E5F4FCE010196698D7A8D11D020 +:104C50004D815E8157FD0AC02F8138854217530769 +:104C60000CF49A01020F131FF80110822E96E4E053 +:104C7000E8C2ADE0B0E0EEE3F6E2BCC23C016C8716 +:104C80007D875A01FC0116821782838181FFBBC197 +:104C90002E010894411C511CF3019381EC85FD8584 +:104CA00093FD859193FF8191EC87FD87882309F41B +:104CB000A6C1853241F493FD859193FF8191EC87E4 +:104CC000FD87853221F490E0B301EFD1E5CFFF24D9 +:104CD000EE2410E01032B0F48B3269F08C3228F4FC +:104CE000803251F0833271F40BC08D3239F0803351 +:104CF00049F411602CC01260146029C0186027C0EC +:104D0000106125C017FD2EC0282F20532A3098F49B +:104D100016FF08C08F2D880FF82EFF0CFF0CF80E21 +:104D2000F20E15C08E2D880FE82EEE0CEE0CE80E5C +:104D3000E20E10620CC08E3221F416FD60C11064C8 +:104D400006C08C3611F4106802C0883659F4EC8520 +:104D5000FD8593FD859193FF8191EC87FD878823E5 +:104D600009F0B8CF982F9554933018F090529330A3 +:104D700038F424E030E0A20EB31E3FE339830FC0C5 +:104D8000833631F0833781F0833509F056C021C076 +:104D9000F5018081898322E030E0A20EB31E21E07C +:104DA000C22ED12C420113C092E0292E312C2A0CA4 +:104DB0003B1CF5018080918016FF03C06F2D70E0D1 +:104DC00002C06FEF7FEFC40165D16C0151011F7705 +:104DD00014C082E0282E312C2A0C3B1CF501808067 +:104DE000918016FF03C06F2D70E002C06FEF7FEF60 +:104DF000C40145D16C011068510113FD1AC005C0F2 +:104E000080E290E0B30151D1EA948E2D90E0C81673 +:104E1000D906B0F30EC0F40117FD859117FF8191FB +:104E20004F0190E0B30141D1E110EA940894C10828 +:104E3000D108C114D10479F7DFC0843611F0893666 +:104E400049F5F50117FF07C080819181A281B381E7 +:104E500024E030E008C080819181AA2797FDA095C9 +:104E6000BA2F22E030E0A20EB31E012F0F76B7FF5B +:104E700008C0B095A095909581959F4FAF4FBF4FBB +:104E80000068BC01CD01A2012AE030E03AD1D82E61 +:104E9000D4183EC0853721F41F7E2AE030E020C0C0 +:104EA000197F8F36A9F0803720F4883509F0A7C024 +:104EB0000BC0803721F0883709F0A1C001C0106114 +:104EC00014FF09C0146007C014FF08C0166006C0B4 +:104ED00028E030E005C020E130E002C020E132E00F +:104EE000F50117FF07C0608171818281938144E0E1 +:104EF00050E006C06081718180E090E042E050E0C7 +:104F0000A40EB51EA201FDD0D82ED418012F0F7704 +:104F100006FF09C00E7FDF1430F404FF06C002FD57 +:104F200004C00F7E02C01D2D01C01F2D802F90E0F8 +:104F300004FF0CC0FE01ED0DF11D2081203311F4A2 +:104F4000097E09C002FF06C01E5F05C0867890700A +:104F5000009709F01F5F802E992403FD11C000FF08 +:104F60000CC0FD2C1E1548F4FE0CF11A1E2D05C0B8 +:104F700080E290E0B30199D01F5F1E15C8F304C012 +:104F80001E1510F4E11A01C0EE2484FE0EC080E369 +:104F900090E0B3018AD082FE1DC081FE03C088E587 +:104FA00090E010C088E790E00DC0C4018678907052 +:104FB000009781F081FC02C080E201C08BE207FD16 +:104FC0008DE290E0B30171D005C080E390E0B301C1 +:104FD0006CD0FA94DF14C8F3DA94F201ED0DF11DF0 +:104FE000808190E0B30161D0DD20B1F705C080E29F +:104FF00090E0B3015AD0EA94EE20C9F74DCEF30108 +:105000008681978102C08FEF9FEF2D96E2E10BC161 +:10501000E0ECF1E0A785A7FDFDCFA485A860A487FB +:105020006050704FF0CDDC01CB0102C02D9105D056 +:1050300041505040D8F70895262FE0ECF1E0378535 +:1050400037FDFDCF3485377F3487378531FF09C081 +:1050500036E3328738ED34BF31E03387378537FDAB +:10506000FDCF33E33287808391831282248325E34B +:10507000228728ED31E024BF338701960895FC0193 +:105080000590615070400110D8F7809590958E0F73 +:105090009F1F0895FC016150704001900110D8F7E6 +:1050A000809590958E0F9F1F08950F931F93CF9318 +:1050B000DF938C01EB018B8181FF1BC082FF0DC050 +:1050C0002E813F818C819D812817390764F4E88106 +:1050D000F9810193E883F98306C0E885F985802F7B +:1050E0000995009731F48E819F8101968E839F836D +:1050F00002C00FEF1FEFC801DF91CF911F910F91F9 +:105100000895FA01AA27283051F1203181F1E8945D +:105110006F936E7F6E5F7F4F8F4F9F4FAF4FB1E0AA +:105120003ED0B4E03CD0670F781F891F9A1FA11DA5 +:10513000680F791F8A1F911DA11D6A0F711D811DA6 +:10514000911DA11D20D009F468943F912AE0269F6B +:1051500011243019305D3193DEF6CF010895462FCA +:105160004770405D4193B3E00FD0C9F7F6CF462FAB +:105170004F70405D4A3318F0495D31FD4052419314 +:1051800002D0A9F7EACFB4E0A695979587957795D1 +:105190006795BA95C9F700976105710508959B0158 +:1051A000AC010A2E06945795479537952795BA95E1 +:1051B000C9F7620F731F841F951FA01D089597FBE9 +:1051C000092E05260ED057FD04D045D00AD0001C6C +:1051D00038F450954095309521953F4F4F4F5F4F94 +:1051E0000895F6F790958095709561957F4F8F4F54 +:1051F0009F4F08952F923F924F925F926F927F92AE +:105200008F929F92AF92BF92CF92DF92EF92FF92D6 +:105210000F931F93CF93DF93CDB7DEB7CA1BDB0B82 +:10522000CDBFDEBF09942A88398848885F846E84A0 +:105230007D848C849B84AA84B984C884DF80EE80BA +:10524000FD800C811B81AA81B981CE0FD11DCDBFFC +:10525000DEBFED010895A1E21A2EAA1BBB1BFD01C2 +:105260000DC0AA1FBB1FEE1FFF1FA217B307E40745 +:10527000F50720F0A21BB30BE40BF50B661F771F9D +:10528000881F991F1A9469F760957095809590957D +:0E5290009B01AC01BD01CF010895F894FFCF42 +:10529E0000831000000104100000018208000001CC +:1052AE0000000000000000000000001400000101DA +:1052BE0001000000010000010001010001000000DA +:1052CE0002020000020002020202000002000000C0 +:1052DE000404000004000404040400000400080890 +:1052EE000800000008000008000808000800000080 +:1052FE00101000001000101010100000100001001F +:10530E000100000000000000010001010101010187 +:10531E0000010001000000010100010101A12000B7 +:10532E000000000200A101000000000000010000CA +:02533E0000006D +:00000001FF diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.lss b/Firmware/Chameleon-Mini/Chameleon-Mini.lss new file mode 100644 index 00000000..d1eab406 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.lss @@ -0,0 +1,17012 @@ + +Chameleon-Mini.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0000529e 00000000 00000000 000000b4 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .data 000000a2 00802000 0000529e 00005352 2**0 + CONTENTS, ALLOC, LOAD, DATA + 2 .bss 0000060b 008020a2 008020a2 000053f4 2**0 + ALLOC + 3 .eeprom 00000013 00810000 00810000 000053f4 2**0 + CONTENTS, ALLOC, LOAD, DATA + 4 .stab 000014d0 00000000 00000000 00005408 2**2 + CONTENTS, READONLY, DEBUGGING + 5 .stabstr 00000601 00000000 00000000 000068d8 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_aranges 00000b78 00000000 00000000 00006ee0 2**3 + CONTENTS, READONLY, DEBUGGING + 7 .debug_info 000159d0 00000000 00000000 00007a58 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_abbrev 00004a41 00000000 00000000 0001d428 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_line 000075a6 00000000 00000000 00021e69 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_frame 00001e1c 00000000 00000000 00029410 2**2 + CONTENTS, READONLY, DEBUGGING + 11 .debug_str 0000769c 00000000 00000000 0002b22c 2**0 + CONTENTS, READONLY, DEBUGGING + 12 .debug_loc 0000b6e8 00000000 00000000 000328c8 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .debug_ranges 00001ae0 00000000 00000000 0003dfb0 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 23 c3 rjmp .+1606 ; 0x648 <__ctors_end> + 2: 00 00 nop + 4: 3d c3 rjmp .+1658 ; 0x680 <__bad_interrupt> + 6: 00 00 nop + 8: 3b c3 rjmp .+1654 ; 0x680 <__bad_interrupt> + a: 00 00 nop + c: 39 c3 rjmp .+1650 ; 0x680 <__bad_interrupt> + e: 00 00 nop + 10: 37 c3 rjmp .+1646 ; 0x680 <__bad_interrupt> + 12: 00 00 nop + 14: 35 c3 rjmp .+1642 ; 0x680 <__bad_interrupt> + 16: 00 00 nop + 18: 33 c3 rjmp .+1638 ; 0x680 <__bad_interrupt> + 1a: 00 00 nop + 1c: 31 c3 rjmp .+1634 ; 0x680 <__bad_interrupt> + 1e: 00 00 nop + 20: 2f c3 rjmp .+1630 ; 0x680 <__bad_interrupt> + 22: 00 00 nop + 24: 2d c3 rjmp .+1626 ; 0x680 <__bad_interrupt> + 26: 00 00 nop + 28: 2b c3 rjmp .+1622 ; 0x680 <__bad_interrupt> + 2a: 00 00 nop + 2c: 29 c3 rjmp .+1618 ; 0x680 <__bad_interrupt> + 2e: 00 00 nop + 30: 27 c3 rjmp .+1614 ; 0x680 <__bad_interrupt> + 32: 00 00 nop + 34: 25 c3 rjmp .+1610 ; 0x680 <__bad_interrupt> + 36: 00 00 nop + 38: 23 c3 rjmp .+1606 ; 0x680 <__bad_interrupt> + 3a: 00 00 nop + 3c: 21 c3 rjmp .+1602 ; 0x680 <__bad_interrupt> + 3e: 00 00 nop + 40: 1f c3 rjmp .+1598 ; 0x680 <__bad_interrupt> + 42: 00 00 nop + 44: 1d c3 rjmp .+1594 ; 0x680 <__bad_interrupt> + 46: 00 00 nop + 48: 1b c3 rjmp .+1590 ; 0x680 <__bad_interrupt> + 4a: 00 00 nop + 4c: 19 c3 rjmp .+1586 ; 0x680 <__bad_interrupt> + 4e: 00 00 nop + 50: 17 c3 rjmp .+1582 ; 0x680 <__bad_interrupt> + 52: 00 00 nop + 54: 15 c3 rjmp .+1578 ; 0x680 <__bad_interrupt> + 56: 00 00 nop + 58: 0c 94 5a 11 jmp 0x22b4 ; 0x22b4 <__vector_22> + 5c: 11 c3 rjmp .+1570 ; 0x680 <__bad_interrupt> + 5e: 00 00 nop + 60: 0f c3 rjmp .+1566 ; 0x680 <__bad_interrupt> + 62: 00 00 nop + 64: 0d c3 rjmp .+1562 ; 0x680 <__bad_interrupt> + 66: 00 00 nop + 68: 0b c3 rjmp .+1558 ; 0x680 <__bad_interrupt> + 6a: 00 00 nop + 6c: 09 c3 rjmp .+1554 ; 0x680 <__bad_interrupt> + 6e: 00 00 nop + 70: 07 c3 rjmp .+1550 ; 0x680 <__bad_interrupt> + 72: 00 00 nop + 74: 05 c3 rjmp .+1546 ; 0x680 <__bad_interrupt> + 76: 00 00 nop + 78: 03 c3 rjmp .+1542 ; 0x680 <__bad_interrupt> + 7a: 00 00 nop + 7c: 01 c3 rjmp .+1538 ; 0x680 <__bad_interrupt> + 7e: 00 00 nop + 80: ff c2 rjmp .+1534 ; 0x680 <__bad_interrupt> + 82: 00 00 nop + 84: fd c2 rjmp .+1530 ; 0x680 <__bad_interrupt> + 86: 00 00 nop + 88: 0c 94 16 11 jmp 0x222c ; 0x222c <__vector_34> + 8c: f9 c2 rjmp .+1522 ; 0x680 <__bad_interrupt> + 8e: 00 00 nop + 90: f7 c2 rjmp .+1518 ; 0x680 <__bad_interrupt> + 92: 00 00 nop + 94: f5 c2 rjmp .+1514 ; 0x680 <__bad_interrupt> + 96: 00 00 nop + 98: f3 c2 rjmp .+1510 ; 0x680 <__bad_interrupt> + 9a: 00 00 nop + 9c: f1 c2 rjmp .+1506 ; 0x680 <__bad_interrupt> + 9e: 00 00 nop + a0: ef c2 rjmp .+1502 ; 0x680 <__bad_interrupt> + a2: 00 00 nop + a4: ed c2 rjmp .+1498 ; 0x680 <__bad_interrupt> + a6: 00 00 nop + a8: eb c2 rjmp .+1494 ; 0x680 <__bad_interrupt> + aa: 00 00 nop + ac: e9 c2 rjmp .+1490 ; 0x680 <__bad_interrupt> + ae: 00 00 nop + b0: e7 c2 rjmp .+1486 ; 0x680 <__bad_interrupt> + b2: 00 00 nop + b4: e5 c2 rjmp .+1482 ; 0x680 <__bad_interrupt> + b6: 00 00 nop + b8: e3 c2 rjmp .+1478 ; 0x680 <__bad_interrupt> + ba: 00 00 nop + bc: e1 c2 rjmp .+1474 ; 0x680 <__bad_interrupt> + be: 00 00 nop + c0: df c2 rjmp .+1470 ; 0x680 <__bad_interrupt> + c2: 00 00 nop + c4: dd c2 rjmp .+1466 ; 0x680 <__bad_interrupt> + c6: 00 00 nop + c8: db c2 rjmp .+1462 ; 0x680 <__bad_interrupt> + ca: 00 00 nop + cc: d9 c2 rjmp .+1458 ; 0x680 <__bad_interrupt> + ce: 00 00 nop + d0: d7 c2 rjmp .+1454 ; 0x680 <__bad_interrupt> + d2: 00 00 nop + d4: d5 c2 rjmp .+1450 ; 0x680 <__bad_interrupt> + d6: 00 00 nop + d8: d3 c2 rjmp .+1446 ; 0x680 <__bad_interrupt> + da: 00 00 nop + dc: d1 c2 rjmp .+1442 ; 0x680 <__bad_interrupt> + de: 00 00 nop + e0: cf c2 rjmp .+1438 ; 0x680 <__bad_interrupt> + e2: 00 00 nop + e4: cd c2 rjmp .+1434 ; 0x680 <__bad_interrupt> + e6: 00 00 nop + e8: cb c2 rjmp .+1430 ; 0x680 <__bad_interrupt> + ea: 00 00 nop + ec: c9 c2 rjmp .+1426 ; 0x680 <__bad_interrupt> + ee: 00 00 nop + f0: c7 c2 rjmp .+1422 ; 0x680 <__bad_interrupt> + f2: 00 00 nop + f4: c5 c2 rjmp .+1418 ; 0x680 <__bad_interrupt> + f6: 00 00 nop + f8: c3 c2 rjmp .+1414 ; 0x680 <__bad_interrupt> + fa: 00 00 nop + fc: c1 c2 rjmp .+1410 ; 0x680 <__bad_interrupt> + fe: 00 00 nop + 100: bf c2 rjmp .+1406 ; 0x680 <__bad_interrupt> + 102: 00 00 nop + 104: bd c2 rjmp .+1402 ; 0x680 <__bad_interrupt> + 106: 00 00 nop + 108: bb c2 rjmp .+1398 ; 0x680 <__bad_interrupt> + 10a: 00 00 nop + 10c: b9 c2 rjmp .+1394 ; 0x680 <__bad_interrupt> + 10e: 00 00 nop + 110: b7 c2 rjmp .+1390 ; 0x680 <__bad_interrupt> + 112: 00 00 nop + 114: b5 c2 rjmp .+1386 ; 0x680 <__bad_interrupt> + 116: 00 00 nop + 118: b3 c2 rjmp .+1382 ; 0x680 <__bad_interrupt> + 11a: 00 00 nop + 11c: b1 c2 rjmp .+1378 ; 0x680 <__bad_interrupt> + 11e: 00 00 nop + 120: af c2 rjmp .+1374 ; 0x680 <__bad_interrupt> + 122: 00 00 nop + 124: ad c2 rjmp .+1370 ; 0x680 <__bad_interrupt> + 126: 00 00 nop + 128: ab c2 rjmp .+1366 ; 0x680 <__bad_interrupt> + 12a: 00 00 nop + 12c: a9 c2 rjmp .+1362 ; 0x680 <__bad_interrupt> + 12e: 00 00 nop + 130: a7 c2 rjmp .+1358 ; 0x680 <__bad_interrupt> + 132: 00 00 nop + 134: a5 c2 rjmp .+1354 ; 0x680 <__bad_interrupt> + 136: 00 00 nop + 138: a3 c2 rjmp .+1350 ; 0x680 <__bad_interrupt> + 13a: 00 00 nop + 13c: a1 c2 rjmp .+1346 ; 0x680 <__bad_interrupt> + 13e: 00 00 nop + 140: 9f c2 rjmp .+1342 ; 0x680 <__bad_interrupt> + 142: 00 00 nop + 144: 9d c2 rjmp .+1338 ; 0x680 <__bad_interrupt> + 146: 00 00 nop + 148: 9b c2 rjmp .+1334 ; 0x680 <__bad_interrupt> + 14a: 00 00 nop + 14c: 0c 94 fe 11 jmp 0x23fc ; 0x23fc <__vector_83> + 150: 97 c2 rjmp .+1326 ; 0x680 <__bad_interrupt> + 152: 00 00 nop + 154: 95 c2 rjmp .+1322 ; 0x680 <__bad_interrupt> + 156: 00 00 nop + 158: 93 c2 rjmp .+1318 ; 0x680 <__bad_interrupt> + 15a: 00 00 nop + 15c: 91 c2 rjmp .+1314 ; 0x680 <__bad_interrupt> + 15e: 00 00 nop + 160: 8f c2 rjmp .+1310 ; 0x680 <__bad_interrupt> + 162: 00 00 nop + 164: 8d c2 rjmp .+1306 ; 0x680 <__bad_interrupt> + 166: 00 00 nop + 168: 8b c2 rjmp .+1302 ; 0x680 <__bad_interrupt> + 16a: 00 00 nop + 16c: 89 c2 rjmp .+1298 ; 0x680 <__bad_interrupt> + 16e: 00 00 nop + 170: 87 c2 rjmp .+1294 ; 0x680 <__bad_interrupt> + 172: 00 00 nop + 174: 85 c2 rjmp .+1290 ; 0x680 <__bad_interrupt> + 176: 00 00 nop + 178: 83 c2 rjmp .+1286 ; 0x680 <__bad_interrupt> + 17a: 00 00 nop + 17c: 81 c2 rjmp .+1282 ; 0x680 <__bad_interrupt> + 17e: 00 00 nop + 180: 7f c2 rjmp .+1278 ; 0x680 <__bad_interrupt> + 182: 00 00 nop + 184: 7d c2 rjmp .+1274 ; 0x680 <__bad_interrupt> + 186: 00 00 nop + 188: 7b c2 rjmp .+1270 ; 0x680 <__bad_interrupt> + 18a: 00 00 nop + 18c: 79 c2 rjmp .+1266 ; 0x680 <__bad_interrupt> + 18e: 00 00 nop + 190: 77 c2 rjmp .+1262 ; 0x680 <__bad_interrupt> + 192: 00 00 nop + 194: 75 c2 rjmp .+1258 ; 0x680 <__bad_interrupt> + 196: 00 00 nop + 198: 73 c2 rjmp .+1254 ; 0x680 <__bad_interrupt> + 19a: 00 00 nop + 19c: 71 c2 rjmp .+1250 ; 0x680 <__bad_interrupt> + 19e: 00 00 nop + 1a0: 6f c2 rjmp .+1246 ; 0x680 <__bad_interrupt> + 1a2: 00 00 nop + 1a4: 6d c2 rjmp .+1242 ; 0x680 <__bad_interrupt> + 1a6: 00 00 nop + 1a8: 6b c2 rjmp .+1238 ; 0x680 <__bad_interrupt> + 1aa: 00 00 nop + 1ac: 69 c2 rjmp .+1234 ; 0x680 <__bad_interrupt> + 1ae: 00 00 nop + 1b0: 67 c2 rjmp .+1230 ; 0x680 <__bad_interrupt> + 1b2: 00 00 nop + 1b4: 65 c2 rjmp .+1226 ; 0x680 <__bad_interrupt> + 1b6: 00 00 nop + 1b8: 63 c2 rjmp .+1222 ; 0x680 <__bad_interrupt> + 1ba: 00 00 nop + 1bc: 61 c2 rjmp .+1218 ; 0x680 <__bad_interrupt> + 1be: 00 00 nop + 1c0: 5f c2 rjmp .+1214 ; 0x680 <__bad_interrupt> + 1c2: 00 00 nop + 1c4: 5d c2 rjmp .+1210 ; 0x680 <__bad_interrupt> + 1c6: 00 00 nop + 1c8: 5b c2 rjmp .+1206 ; 0x680 <__bad_interrupt> + 1ca: 00 00 nop + 1cc: 59 c2 rjmp .+1202 ; 0x680 <__bad_interrupt> + 1ce: 00 00 nop + 1d0: 57 c2 rjmp .+1198 ; 0x680 <__bad_interrupt> + 1d2: 00 00 nop + 1d4: 55 c2 rjmp .+1194 ; 0x680 <__bad_interrupt> + 1d6: 00 00 nop + 1d8: 53 c2 rjmp .+1190 ; 0x680 <__bad_interrupt> + 1da: 00 00 nop + 1dc: 51 c2 rjmp .+1186 ; 0x680 <__bad_interrupt> + 1de: 00 00 nop + 1e0: 4f c2 rjmp .+1182 ; 0x680 <__bad_interrupt> + 1e2: 00 00 nop + 1e4: 4d c2 rjmp .+1178 ; 0x680 <__bad_interrupt> + 1e6: 00 00 nop + 1e8: 4b c2 rjmp .+1174 ; 0x680 <__bad_interrupt> + 1ea: 00 00 nop + 1ec: 49 c2 rjmp .+1170 ; 0x680 <__bad_interrupt> + 1ee: 00 00 nop + 1f0: 47 c2 rjmp .+1166 ; 0x680 <__bad_interrupt> + 1f2: 00 00 nop + 1f4: 0c 94 ea 22 jmp 0x45d4 ; 0x45d4 <__vector_125> + 1f8: 43 c2 rjmp .+1158 ; 0x680 <__bad_interrupt> + 1fa: 00 00 nop + +000001fc : + 1fc: 1c 03 4c 00 55 00 46 00 41 00 20 00 43 00 44 00 ..L.U.F.A. .C.D. + 20c: 43 00 20 00 44 00 65 00 6d 00 6f 00 00 00 C. .D.e.m.o... + +0000021a : + 21a: 18 03 44 00 65 00 61 00 6e 00 20 00 43 00 61 00 ..D.e.a.n. .C.a. + 22a: 6d 00 65 00 72 00 61 00 00 00 m.e.r.a... + +00000234 : + 234: 04 03 09 04 .... + +00000238 : + 238: 09 02 3e 00 02 01 00 c0 32 09 04 00 00 01 02 02 ..>.....2....... + 248: 01 00 05 24 00 10 01 04 24 02 06 05 24 06 00 01 ...$....$...$... + 258: 07 05 82 03 08 00 ff 09 04 01 00 02 0a 00 00 00 ................ + 268: 07 05 04 02 10 00 05 07 05 83 02 10 00 05 .............. + +00000276 : + 276: 12 01 10 01 02 00 00 08 eb 03 44 20 01 00 01 02 ..........D .... + 286: dc 01 .. + +00000288 : + 288: 00 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 .NONE........... + 298: 00 2c 04 2d 04 2e 04 2f 04 30 04 31 04 34 04 35 .,.-.../.0.1.4.5 + 2a8: 04 00 00 00 01 01 4d 46 5f 43 4c 41 53 53 49 43 ......MF_CLASSIC + 2b8: 5f 31 4b 00 00 00 07 13 3f 13 b8 13 d2 13 d6 13 _1K.....?....... + 2c8: d7 13 b5 18 bb 18 00 04 04 00 02 4d 46 5f 43 4c ...........MF_CL + 2d8: 41 53 53 49 43 5f 34 4b 00 00 00 07 13 3f 13 c5 ASSIC_4K.....?.. + 2e8: 13 d2 13 d6 13 d7 13 b5 18 bb 18 00 10 04 00 ............... + +000002f7 : + 2f7: 4e 4f 4e 45 00 00 00 00 00 00 00 00 00 00 00 00 NONE............ + 307: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 317: 55 49 44 5f 52 41 4e 44 4f 4d 00 00 00 00 00 00 UID_RANDOM...... + 327: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 337: 55 49 44 5f 4c 45 46 54 5f 49 4e 43 52 45 4d 45 UID_LEFT_INCREME + 347: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. + 357: 55 49 44 5f 52 49 47 48 54 5f 49 4e 43 52 45 4d UID_RIGHT_INCREM + 367: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. + 377: 55 49 44 5f 4c 45 46 54 5f 44 45 43 52 45 4d 45 UID_LEFT_DECREME + 387: 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NT.............. + 397: 55 49 44 5f 52 49 47 48 54 5f 44 45 43 52 45 4d UID_RIGHT_DECREM + 3a7: 45 4e 54 00 00 00 00 00 00 00 00 00 00 00 00 00 ENT............. + +000003b7 <__c.6198>: + 3b7: 43 68 61 6d 65 6c 65 6f 6e 2d 4d 69 6e 69 20 25 Chameleon-Mini % + 3c7: 53 20 75 73 69 6e 67 20 4c 55 46 41 20 25 53 20 S using LUFA %S + 3d7: 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 41 56 compiled with AV + 3e7: 52 2d 47 43 43 20 25 53 00 R-GCC %S. + +000003f0 <__c.6200>: + 3f0: 31 33 31 32 32 32 00 131222. + +000003f7 <__c.6202>: + 3f7: 31 33 30 39 30 31 00 130901. + +000003fe <__c.6204>: + 3fe: 34 2e 36 2e 32 00 4.6.2. + +00000404 <__c.6209>: + 404: 25 73 00 %s. + +00000407 <__c.6227>: + 407: 52 41 4e 44 4f 4d 00 RANDOM. + +0000040e <__c.6254>: + 40e: 25 75 00 %u. + +00000411 <__c.6259>: + 411: 25 75 00 %u. + +00000414 <__c.6298>: + 414: 25 35 75 20 6d 56 00 %5u mV. + +0000041b : + 41b: 56 45 52 53 49 4f 4e 00 00 00 00 00 00 00 00 00 VERSION......... + 42b: 00 00 00 00 74 0b 43 4f 4e 46 49 47 00 00 00 00 ....t.CONFIG.... + 43b: 00 00 00 00 00 00 ce 0b c6 0b a1 0b 55 49 44 00 ............UID. + 44b: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9 0b ................ + 45b: d3 0b 52 45 41 44 4f 4e 4c 59 00 00 00 00 00 00 ..READONLY...... + 46b: 00 00 00 00 5c 0c 4d 0c 55 50 4c 4f 41 44 00 00 ....\.M.UPLOAD.. + 47b: 00 00 00 00 00 00 00 00 72 0c 00 00 00 00 44 4f ........r.....DO + 48b: 57 4e 4c 4f 41 44 00 00 00 00 00 00 00 00 77 0c WNLOAD........w. + 49b: 00 00 00 00 52 45 53 45 54 00 00 00 00 00 00 00 ....RESET....... + 4ab: 00 00 00 00 7c 0c 00 00 00 00 55 50 47 52 41 44 ....|.....UPGRAD + 4bb: 45 00 00 00 00 00 00 00 00 00 87 0c 00 00 00 00 E............... + 4cb: 4d 45 4d 53 49 5a 45 00 00 00 00 00 00 00 00 00 MEMSIZE......... + 4db: 00 00 00 00 92 0c 55 49 44 53 49 5a 45 00 00 00 ......UIDSIZE... + 4eb: 00 00 00 00 00 00 00 00 00 00 b9 0c 42 55 54 54 ............BUTT + 4fb: 4f 4e 00 00 00 00 00 00 00 00 00 00 de 0c e8 0c ON.............. + 50b: e3 0c 53 45 54 54 49 4e 47 00 00 00 00 00 00 00 ..SETTING....... + 51b: 00 00 00 00 f5 0c f0 0c 43 4c 45 41 52 00 00 00 ........CLEAR... + 52b: 00 00 00 00 00 00 00 00 fd 0c 00 00 00 00 48 45 ..............HE + 53b: 4c 50 00 00 00 00 00 00 00 00 00 00 00 00 00 0d LP.............. + 54b: 00 00 00 00 52 53 53 49 00 00 00 00 00 00 00 00 ....RSSI........ + 55b: 00 00 00 00 00 00 00 00 4d 0d 00 00 00 00 00 00 ........M....... + 56b: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + +0000057b <__c.5994>: + 57b: 0d 0a 00 ... + +0000057e <__c.5996>: + 57e: 0d 0a 00 ... + +00000581 : + 581: 64 31 30 30 3a 4f 4b 00 00 00 00 00 00 00 00 00 d100:OK......... + 591: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 5a1: 00 65 31 30 31 3a 4f 4b 20 57 49 54 48 20 54 45 .e101:OK WITH TE + 5b1: 58 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 XT.............. + 5c1: 00 00 6e 31 31 30 3a 57 41 49 54 49 4e 47 20 46 ..n110:WAITING F + 5d1: 4f 52 20 58 4d 4f 44 45 4d 00 00 00 00 00 00 00 OR XMODEM....... + 5e1: 00 00 00 c8 32 30 30 3a 55 4e 4b 4e 4f 57 4e 20 ....200:UNKNOWN + 5f1: 43 4f 4d 4d 41 4e 44 00 00 00 00 00 00 00 00 00 COMMAND......... + 601: 00 00 00 00 c9 32 30 31 3a 49 4e 56 41 4c 49 44 .....201:INVALID + 611: 20 43 4f 4d 4d 41 4e 44 20 55 53 41 47 45 00 00 COMMAND USAGE.. + 621: 00 00 00 00 00 ca 32 30 32 3a 49 4e 56 41 4c 49 ......202:INVALI + 631: 44 20 50 41 52 41 4d 45 54 45 52 00 00 00 00 00 D PARAMETER..... + 641: 00 00 00 00 00 00 00 ....... + +00000648 <__ctors_end>: + 648: 11 24 eor r1, r1 + 64a: 1f be out 0x3f, r1 ; 63 + 64c: cf ef ldi r28, 0xFF ; 255 + 64e: df e2 ldi r29, 0x2F ; 47 + 650: de bf out 0x3e, r29 ; 62 + 652: cd bf out 0x3d, r28 ; 61 + +00000654 <__do_copy_data>: + 654: 10 e2 ldi r17, 0x20 ; 32 + 656: a0 e0 ldi r26, 0x00 ; 0 + 658: b0 e2 ldi r27, 0x20 ; 32 + 65a: ee e9 ldi r30, 0x9E ; 158 + 65c: f2 e5 ldi r31, 0x52 ; 82 + 65e: 02 c0 rjmp .+4 ; 0x664 <__do_copy_data+0x10> + 660: 05 90 lpm r0, Z+ + 662: 0d 92 st X+, r0 + 664: a2 3a cpi r26, 0xA2 ; 162 + 666: b1 07 cpc r27, r17 + 668: d9 f7 brne .-10 ; 0x660 <__do_copy_data+0xc> + +0000066a <__do_clear_bss>: + 66a: 16 e2 ldi r17, 0x26 ; 38 + 66c: a2 ea ldi r26, 0xA2 ; 162 + 66e: b0 e2 ldi r27, 0x20 ; 32 + 670: 01 c0 rjmp .+2 ; 0x674 <.do_clear_bss_start> + +00000672 <.do_clear_bss_loop>: + 672: 1d 92 st X+, r1 + +00000674 <.do_clear_bss_start>: + 674: ad 3a cpi r26, 0xAD ; 173 + 676: b1 07 cpc r27, r17 + 678: e1 f7 brne .-8 ; 0x672 <.do_clear_bss_loop> + 67a: 03 d0 rcall .+6 ; 0x682
+ 67c: 0c 94 4d 29 jmp 0x529a ; 0x529a <_exit> + +00000680 <__bad_interrupt>: + 680: 6f c0 rjmp .+222 ; 0x760 <__vector_default> + +00000682
: + +#include "Chameleon-Mini.h" + +int main(void) +{ + SystemInit(); + 682: 74 d0 rcall .+232 ; 0x76c + 684: f2 d6 rcall .+3556 ; 0x146a + SettingsLoad(); + 686: 80 e3 ldi r24, 0x30 ; 48 + 688: e0 e0 ldi r30, 0x00 ; 0 + +extern uint8_t LEDPulseMask; + +static inline +void LEDInit(void) { + LED_PORT.DIRSET = LED_MASK; + 68a: f6 e0 ldi r31, 0x06 ; 6 + 68c: 81 83 std Z+1, r24 ; 0x01 + 68e: 4e d2 rcall .+1180 ; 0xb2c + 690: 16 d1 rcall .+556 ; 0x8be + LEDInit(); + MemoryInit(); + 692: b3 d7 rcall .+3942 ; 0x15fa + 694: 9c d1 rcall .+824 ; 0x9ce + ConfigurationInit(); + 696: 73 d5 rcall .+2790 ; 0x117e + 698: e0 e0 ldi r30, 0x00 ; 0 + TerminalInit(); + 69a: f2 e0 ldi r31, 0x02 ; 2 + 69c: 81 e0 ldi r24, 0x01 ; 1 + RandomInit(); + 69e: 80 93 00 02 sts 0x0200, r24 + ButtonInit(); + 6a2: 11 82 std Z+1, r1 ; 0x01 + 6a4: 92 e0 ldi r25, 0x02 ; 2 +#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) + +static inline +void AntennaLevelInit(void) +{ + ADCA.CTRLA = ADC_ENABLE_bm; + 6a6: 92 83 std Z+2, r25 ; 0x02 + 6a8: 93 e0 ldi r25, 0x03 ; 3 + 6aa: 94 83 std Z+4, r25 ; 0x04 + 6ac: 80 a3 lds r24, 0x50 + 6ae: 88 e3 ldi r24, 0x38 ; 56 + ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; + 6b0: 81 a3 lds r24, 0x51 + ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; + 6b2: cc d0 rcall .+408 ; 0x84c + 6b4: c0 e0 ldi r28, 0x00 ; 0 + ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; + 6b6: da e0 ldi r29, 0x0A ; 10 + 6b8: ff 24 eor r15, r15 + ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; + 6ba: f3 94 inc r15 + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; + 6bc: 00 e0 ldi r16, 0x00 ; 0 + 6be: 16 e0 ldi r17, 0x06 ; 6 + AntennaLevelInit(); + + SystemInterruptInit(); + 6c0: a1 d7 rcall .+3906 ; 0x1604 + 6c2: e0 91 fb 20 lds r30, 0x20FB + return RTC.CNT; +} + +INLINE bool SystemTick100ms(void) +{ + if (TCE0.INTFLAGS & TC0_OVFIF_bm) { + 6c6: f0 91 fc 20 lds r31, 0x20FC + TCE0.INTFLAGS = TC0_OVFIF_bm; + 6ca: 09 95 icall + LED_PORT.OUTSET = Mask; +} + +static inline +void LEDTick(void) { + LED_PORT.OUTCLR = LEDPulseMask; + 6cc: e0 91 01 21 lds r30, 0x2101 + + while(1) { + TerminalTask(); + 6d0: f0 91 02 21 lds r31, 0x2102 +INLINE void CodecInit(void) { + ActiveConfiguration.CodecInitFunc(); +} + +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); + 6d4: 09 95 icall + 6d6: 80 91 0c 0a lds r24, 0x0A0C + 6da: 80 ff sbrs r24, 0 + 6dc: f1 cf rjmp .-30 ; 0x6c0 +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); +} + +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); + 6de: fc 86 std Y+12, r15 ; 0x0c + 6e0: 91 d1 rcall .+802 ; 0xa04 + 6e2: b1 d7 rcall .+3938 ; 0x1646 + 6e4: 53 d5 rcall .+2726 ; 0x118c + 6e6: 80 91 a3 20 lds r24, 0x20A3 + return RTC.CNT; +} + +INLINE bool SystemTick100ms(void) +{ + if (TCE0.INTFLAGS & TC0_OVFIF_bm) { + 6ea: f8 01 movw r30, r16 + 6ec: 86 83 std Z+6, r24 ; 0x06 + 6ee: 10 92 a3 20 sts 0x20A3, r1 + CodecTask(); + ApplicationTask(); + + if (SystemTick100ms()) { + RandomTick(); + 6f2: e6 cf rjmp .-52 ; 0x6c0 + +000006f4 : + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + 6f4: 92 30 cpi r25, 0x02 ; 2 + 6f6: f9 f0 breq .+62 ; 0x736 + 6f8: 93 30 cpi r25, 0x03 ; 3 + 6fa: a1 f0 breq .+40 ; 0x724 + 6fc: 91 30 cpi r25, 0x01 ; 1 + 6fe: 49 f0 breq .+18 ; 0x712 +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + 700: 80 e0 ldi r24, 0x00 ; 0 + 702: 90 e0 ldi r25, 0x00 ; 0 + const void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + 704: e0 e0 ldi r30, 0x00 ; 0 + 706: f0 e0 ldi r31, 0x00 ; 0 + } + + break; + } + + *DescriptorAddress = Address; + 708: da 01 movw r26, r20 + 70a: ed 93 st X+, r30 + 70c: fc 93 st X, r31 + 70e: 11 97 sbiw r26, 0x01 ; 1 + return Size; +} + 710: 08 95 ret + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + 712: 82 e1 ldi r24, 0x12 ; 18 + 714: 90 e0 ldi r25, 0x00 ; 0 + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + 716: e6 e7 ldi r30, 0x76 ; 118 + 718: f2 e0 ldi r31, 0x02 ; 2 + } + + break; + } + + *DescriptorAddress = Address; + 71a: da 01 movw r26, r20 + 71c: ed 93 st X+, r30 + 71e: fc 93 st X, r31 + 720: 11 97 sbiw r26, 0x01 ; 1 + return Size; +} + 722: 08 95 ret + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + 724: 81 30 cpi r24, 0x01 ; 1 + 726: 81 f0 breq .+32 ; 0x748 + 728: 81 30 cpi r24, 0x01 ; 1 + 72a: 98 f4 brcc .+38 ; 0x752 + { + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + 72c: e4 e3 ldi r30, 0x34 ; 52 + 72e: f2 e0 ldi r31, 0x02 ; 2 + 730: 84 91 lpm r24, Z + 732: 90 e0 ldi r25, 0x00 ; 0 + break; + 734: e9 cf rjmp .-46 ; 0x708 + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + 736: 8e e3 ldi r24, 0x3E ; 62 + 738: 90 e0 ldi r25, 0x00 ; 0 + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + 73a: e8 e3 ldi r30, 0x38 ; 56 + 73c: f2 e0 ldi r31, 0x02 ; 2 + } + + break; + } + + *DescriptorAddress = Address; + 73e: da 01 movw r26, r20 + 740: ed 93 st X+, r30 + 742: fc 93 st X, r31 + 744: 11 97 sbiw r26, 0x01 ; 1 + return Size; +} + 746: 08 95 ret + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + 748: ea e1 ldi r30, 0x1A ; 26 + 74a: f2 e0 ldi r31, 0x02 ; 2 + 74c: 84 91 lpm r24, Z + 74e: 90 e0 ldi r25, 0x00 ; 0 + break; + 750: db cf rjmp .-74 ; 0x708 + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + 752: 82 30 cpi r24, 0x02 ; 2 + 754: a9 f6 brne .-86 ; 0x700 + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + 756: ec ef ldi r30, 0xFC ; 252 + 758: f1 e0 ldi r31, 0x01 ; 1 + 75a: 84 91 lpm r24, Z + 75c: 90 e0 ldi r25, 0x00 ; 0 + break; + 75e: d4 cf rjmp .-88 ; 0x708 + +00000760 <__vector_default>: + +#include "System.h" +#include "LED.h" + +ISR(BADISR_vect) +{ + 760: 1f 92 push r1 + 762: 0f 92 push r0 + 764: 0f b6 in r0, 0x3f ; 63 + 766: 0f 92 push r0 + 768: 11 24 eor r1, r1 + 76a: ff cf rjmp .-2 ; 0x76a <__vector_default+0xa> + +0000076c : + while(1); +} + +void SystemInit(void) +{ + if (RST.STATUS & RST_WDRF_bm) { + 76c: 80 91 78 00 lds r24, 0x0078 + 770: 83 ff sbrs r24, 3 + 772: 0a c0 rjmp .+20 ; 0x788 + /* On Watchdog reset clear WDRF bit, disable watchdog + * and jump into bootloader */ + RST.STATUS = RST_WDRF_bm; + 774: 88 e0 ldi r24, 0x08 ; 8 + 776: 80 93 78 00 sts 0x0078, r24 + + CCP = CCP_IOREG_gc; + 77a: 88 ed ldi r24, 0xD8 ; 216 + 77c: 84 bf out 0x34, r24 ; 52 + WDT.CTRL = WDT_CEN_bm; + 77e: 81 e0 ldi r24, 0x01 ; 1 + 780: 80 93 80 00 sts 0x0080, r24 + + asm volatile ("jmp %0"::"i" (BOOT_SECTION_START + 0x1FC)); + 784: fd 95 fe c0 jmp 0x7f81fc ; 0x7f81fc <__data_load_end+0x7f2ebc> + } + + /* 32MHz system clock using internal RC and 32K DFLL*/ + OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm; + 788: 80 91 50 00 lds r24, 0x0050 + 78c: 86 60 ori r24, 0x06 ; 6 + 78e: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_RC32MRDY_bm)) + 792: 80 91 51 00 lds r24, 0x0051 + 796: 81 ff sbrs r24, 1 + 798: fc cf rjmp .-8 ; 0x792 + ; + while(!(OSC.STATUS & OSC_RC32KRDY_bm)) + 79a: 80 91 51 00 lds r24, 0x0051 + 79e: 82 ff sbrs r24, 2 + 7a0: fc cf rjmp .-8 ; 0x79a + ; + + OSC.DFLLCTRL = OSC_RC32MCREF_RC32K_gc; + 7a2: e0 e5 ldi r30, 0x50 ; 80 + 7a4: f0 e0 ldi r31, 0x00 ; 0 + 7a6: 16 82 std Z+6, r1 ; 0x06 + DFLLRC32M.CTRL = DFLL_ENABLE_bm; + 7a8: 21 e0 ldi r18, 0x01 ; 1 + 7aa: 20 93 60 00 sts 0x0060, r18 + + CCP = CCP_IOREG_gc; + 7ae: 88 ed ldi r24, 0xD8 ; 216 + 7b0: 84 bf out 0x34, r24 ; 52 + CLK.CTRL = CLK_SCLKSEL_RC32M_gc; + 7b2: 20 93 40 00 sts 0x0040, r18 + + /* Use TCE0 as system tick */ + TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1; + 7b6: 83 ed ldi r24, 0xD3 ; 211 + 7b8: 90 e3 ldi r25, 0x30 ; 48 + 7ba: e0 e0 ldi r30, 0x00 ; 0 + 7bc: fa e0 ldi r31, 0x0A ; 10 + 7be: 86 a3 lds r24, 0x56 + 7c0: 97 a3 lds r25, 0x57 + TCE0.CTRLA = TC_CLKSEL_DIV256_gc; + 7c2: 86 e0 ldi r24, 0x06 ; 6 + 7c4: 80 93 00 0a sts 0x0A00, r24 + + /* Enable RTC with roughly 1kHz clock */ + CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm; + 7c8: e0 e4 ldi r30, 0x40 ; 64 + 7ca: f0 e0 ldi r31, 0x00 ; 0 + 7cc: 23 83 std Z+3, r18 ; 0x03 + RTC.CTRL = RTC_PRESCALER_DIV1_gc; + 7ce: 20 93 00 04 sts 0x0400, r18 + + /* Enable EEPROM data memory mapping */ + NVM.CTRLB |= NVM_EEMAPEN_bm; + 7d2: 80 91 cc 01 lds r24, 0x01CC + 7d6: 88 60 ori r24, 0x08 ; 8 + 7d8: e0 ec ldi r30, 0xC0 ; 192 + 7da: f1 e0 ldi r31, 0x01 ; 1 + 7dc: 84 87 std Z+12, r24 ; 0x0c +} + 7de: 08 95 ret + +000007e0 : + +void SystemReset(void) +{ + CCP = CCP_IOREG_gc; + 7e0: 88 ed ldi r24, 0xD8 ; 216 + 7e2: 84 bf out 0x34, r24 ; 52 + RST.CTRL = RST_SWRST_bm; + 7e4: 81 e0 ldi r24, 0x01 ; 1 + 7e6: e8 e7 ldi r30, 0x78 ; 120 + 7e8: f0 e0 ldi r31, 0x00 ; 0 + 7ea: 81 83 std Z+1, r24 ; 0x01 + +} + 7ec: 08 95 ret + +000007ee : + +void SystemEnterBootloader(void) +{ + /* Use Watchdog timer to reset into bootloader. */ + CCP = CCP_IOREG_gc; + 7ee: 88 ed ldi r24, 0xD8 ; 216 + 7f0: 84 bf out 0x34, r24 ; 52 + WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; + 7f2: 8b e1 ldi r24, 0x1B ; 27 + 7f4: 80 93 80 00 sts 0x0080, r24 +} + 7f8: 08 95 ret + +000007fa : + + +void SystemStartUSBClock(void) +{ + /* 48MHz USB Clock using 12MHz XTAL */ + OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; + 7fa: 8b ec ldi r24, 0xCB ; 203 + 7fc: e0 e5 ldi r30, 0x50 ; 80 + 7fe: f0 e0 ldi r31, 0x00 ; 0 + 800: 82 83 std Z+2, r24 ; 0x02 + OSC.CTRL |= OSC_XOSCEN_bm; + 802: 80 91 50 00 lds r24, 0x0050 + 806: 88 60 ori r24, 0x08 ; 8 + 808: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_XOSCRDY_bm)) + 80c: 80 91 51 00 lds r24, 0x0051 + 810: 83 ff sbrs r24, 3 + 812: fc cf rjmp .-8 ; 0x80c + ; + + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp); + 814: 84 ec ldi r24, 0xC4 ; 196 + 816: e0 e5 ldi r30, 0x50 ; 80 + 818: f0 e0 ldi r31, 0x00 ; 0 + 81a: 85 83 std Z+5, r24 ; 0x05 + + OSC.CTRL |= OSC_PLLEN_bm; + 81c: 80 91 50 00 lds r24, 0x0050 + 820: 80 61 ori r24, 0x10 ; 16 + 822: 80 93 50 00 sts 0x0050, r24 + while(!(OSC.STATUS & OSC_PLLRDY_bm)) + 826: 80 91 51 00 lds r24, 0x0051 + 82a: 84 ff sbrs r24, 4 + 82c: fc cf rjmp .-8 ; 0x826 + ; +} + 82e: 08 95 ret + +00000830 : + +void SystemStopUSBClock(void) +{ + /* Disable USB Clock to minimize power consumption */ + CLK.USBCTRL &= ~CLK_USBSEN_bm; + 830: e0 e4 ldi r30, 0x40 ; 64 + 832: f0 e0 ldi r31, 0x00 ; 0 + 834: 84 81 ldd r24, Z+4 ; 0x04 + 836: 8e 7f andi r24, 0xFE ; 254 + 838: 84 83 std Z+4, r24 ; 0x04 + OSC.CTRL &= ~OSC_PLLEN_bm; + 83a: e0 e5 ldi r30, 0x50 ; 80 + 83c: f0 e0 ldi r31, 0x00 ; 0 + 83e: 80 81 ld r24, Z + 840: 8f 7e andi r24, 0xEF ; 239 + 842: 80 83 st Z, r24 + OSC.CTRL &= ~OSC_XOSCEN_bm; + 844: 80 81 ld r24, Z + 846: 87 7f andi r24, 0xF7 ; 247 + 848: 80 83 st Z, r24 +} + 84a: 08 95 ret + +0000084c : + +void SystemInterruptInit(void) +{ + /* Enable all interrupt levels */ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + 84c: 87 e0 ldi r24, 0x07 ; 7 + 84e: e0 ea ldi r30, 0xA0 ; 160 + 850: f0 e0 ldi r31, 0x00 ; 0 + 852: 82 83 std Z+2, r24 ; 0x02 + sei(); + 854: 78 94 sei +} + 856: 08 95 ret + +00000858 : + +/* Include all Codecs and Applications */ +#include "Codec/Codec.h" +#include "Application/Application.h" + +static void CodecInitDummy(void) { } + 858: 08 95 ret + +0000085a : +static void CodecTaskDummy(void) { } + 85a: 08 95 ret + +0000085c : +static void ApplicationInitDummy(void) {} + 85c: 08 95 ret + +0000085e : +static void ApplicationResetDummy(void) {} + 85e: 08 95 ret + +00000860 : +static void ApplicationTaskDummy(void) {} + 860: 08 95 ret + +00000862 : +static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return 0; } + 862: 80 e0 ldi r24, 0x00 ; 0 + 864: 90 e0 ldi r25, 0x00 ; 0 + 866: 08 95 ret + +00000868 : +static void ApplicationGetUidDummy(ConfigurationUidType Uid) { } + 868: 08 95 ret + +0000086a : +static void ApplicationSetUidDummy(ConfigurationUidType Uid) { } + 86a: 08 95 ret + +0000086c : + ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); +} + +void ConfigurationSetById( ConfigurationEnum Configuration ) +{ + GlobalSettings.ActiveSettingPtr->Configuration = Configuration; + 86c: e0 91 0e 21 lds r30, 0x210E + 870: f0 91 0f 21 lds r31, 0x210F + 874: 81 83 std Z+1, r24 ; 0x01 + + /* Copy struct from PROGMEM to RAM */ + memcpy_P(&ActiveConfiguration, + 876: 90 e0 ldi r25, 0x00 ; 0 + 878: 9c 01 movw r18, r24 + 87a: 22 0f add r18, r18 + 87c: 33 1f adc r19, r19 + 87e: 22 0f add r18, r18 + 880: 33 1f adc r19, r19 + 882: b9 01 movw r22, r18 + 884: 66 0f add r22, r22 + 886: 77 1f adc r23, r23 + 888: 66 0f add r22, r22 + 88a: 77 1f adc r23, r23 + 88c: 66 0f add r22, r22 + 88e: 77 1f adc r23, r23 + 890: 62 0f add r22, r18 + 892: 73 1f adc r23, r19 + 894: 68 0f add r22, r24 + 896: 79 1f adc r23, r25 + 898: 68 57 subi r22, 0x78 ; 120 + 89a: 7d 4f sbci r23, 0xFD ; 253 + 89c: 88 ee ldi r24, 0xE8 ; 232 + 89e: 90 e2 ldi r25, 0x20 ; 32 + 8a0: 45 e2 ldi r20, 0x25 ; 37 + 8a2: 50 e0 ldi r21, 0x00 ; 0 + 8a4: 0e 94 e2 25 call 0x4bc4 ; 0x4bc4 +/* Applications */ +#include "MifareClassic.h" + +/* Function wrappers */ +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); + 8a8: e0 91 fd 20 lds r30, 0x20FD + 8ac: f0 91 fe 20 lds r31, 0x20FE + 8b0: 09 95 icall +#define CODEC_CARRIER_FREQ 13560000 + +extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; + +INLINE void CodecInit(void) { + ActiveConfiguration.CodecInitFunc(); + 8b2: e0 91 f9 20 lds r30, 0x20F9 + 8b6: f0 91 fa 20 lds r31, 0x20FA + 8ba: 09 95 icall + &ConfigurationTable[Configuration], sizeof(ConfigurationType)); + + + ApplicationInit(); + CodecInit(); +} + 8bc: 08 95 ret + +000008be : + +ConfigurationType ActiveConfiguration; + +void ConfigurationInit(void) +{ + ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); + 8be: e0 91 0e 21 lds r30, 0x210E + 8c2: f0 91 0f 21 lds r31, 0x210F + 8c6: 81 81 ldd r24, Z+1 ; 0x01 + 8c8: d1 cf rjmp .-94 ; 0x86c + +000008ca : + 8ca: 0f 93 push r16 +} + 8cc: 1f 93 push r17 + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) +{ + 8ce: cf 93 push r28 + 8d0: df 93 push r29 + 8d2: ac 01 movw r20, r24 + 8d4: 20 e0 ldi r18, 0x00 ; 0 + 8d6: 30 e0 ldi r19, 0x00 ; 0 + + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) + 8d8: 8c 01 movw r16, r24 + 8da: 0f 5f subi r16, 0xFF ; 255 + 8dc: 1f 4f sbci r17, 0xFF ; 255 + ConfigurationSetById(i); + return true; + } + } + + return false; + 8de: 62 2f mov r22, r18 +{ + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; + 8e0: c9 01 movw r24, r18 + 8e2: 88 0f add r24, r24 + 8e4: 99 1f adc r25, r25 + 8e6: 88 0f add r24, r24 + 8e8: 99 1f adc r25, r25 + 8ea: fc 01 movw r30, r24 + 8ec: ee 0f add r30, r30 + 8ee: ff 1f adc r31, r31 + 8f0: ee 0f add r30, r30 + 8f2: ff 1f adc r31, r31 + 8f4: ee 0f add r30, r30 + 8f6: ff 1f adc r31, r31 + 8f8: e8 0f add r30, r24 + 8fa: f9 1f adc r31, r25 + 8fc: e2 0f add r30, r18 + 8fe: f3 1f adc r31, r19 + 900: e7 57 subi r30, 0x77 ; 119 + 902: fd 4f sbci r31, 0xFD ; 253 + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + 904: 84 91 lpm r24, Z + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + 906: da 01 movw r26, r20 + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + 908: 88 23 and r24, r24 + 90a: 59 f0 breq .+22 ; 0x922 + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + 90c: 9c 91 ld r25, X + 90e: 99 23 and r25, r25 + 910: 59 f0 breq .+22 ; 0x928 + /* One String ended before the other did -> unequal length */ + StringMismatch = true; + break; + } + + if (c != *pRequestedConfigName) { + 912: 98 17 cp r25, r24 + 914: 49 f4 brne .+18 ; 0x928 + + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) + 916: e8 01 movw r28, r16 + StringMismatch = true; + break; + } + + /* Proceed to next character */ + pTableConfigName++; + 918: 31 96 adiw r30, 0x01 ; 1 + pRequestedConfigName++; + 91a: 11 96 adiw r26, 0x01 ; 1 + + c = pgm_read_byte(pTableConfigName); + 91c: 84 91 lpm r24, Z + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + 91e: 88 23 and r24, r24 + 920: 71 f4 brne .+28 ; 0x93e + 922: 8c 91 ld r24, X + 924: 88 23 and r24, r24 + 926: 89 f0 breq .+34 ; 0x94a + 928: 2f 5f subi r18, 0xFF ; 255 + 92a: 3f 4f sbci r19, 0xFF ; 255 +bool ConfigurationSetByName(const char* ConfigurationName) +{ + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + 92c: 23 30 cpi r18, 0x03 ; 3 + 92e: 31 05 cpc r19, r1 + 930: b1 f6 brne .-84 ; 0x8de + ConfigurationSetById(i); + return true; + } + } + + return false; + 932: 80 e0 ldi r24, 0x00 ; 0 +} + 934: df 91 pop r29 + 936: cf 91 pop r28 + 938: 1f 91 pop r17 + 93a: 0f 91 pop r16 + 93c: 08 95 ret + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + 93e: 99 91 ld r25, Y+ + 940: 99 23 and r25, r25 + 942: 91 f3 breq .-28 ; 0x928 + /* One String ended before the other did -> unequal length */ + StringMismatch = true; + break; + } + + if (c != *pRequestedConfigName) { + 944: 98 17 cp r25, r24 + 946: 41 f3 breq .-48 ; 0x918 + 948: ef cf rjmp .-34 ; 0x928 + c = pgm_read_byte(pTableConfigName); + } + + if (!StringMismatch) { + /* Configuration found */ + ConfigurationSetById(i); + 94a: 86 2f mov r24, r22 + 94c: 8f df rcall .-226 ; 0x86c + 94e: 81 e0 ldi r24, 0x01 ; 1 + return true; + 950: df 91 pop r29 + } + } + + return false; +} + 952: cf 91 pop r28 + 954: 1f 91 pop r17 + 956: 0f 91 pop r16 + 958: 08 95 ret + +0000095a : + 95a: cf 93 push r28 + +void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount) +{ + 95c: df 93 push r29 + 95e: ec 01 movw r28, r24 + uint8_t i; + + /* Account for '\0' */ + ByteCount--; + 960: 61 50 subi r22, 0x01 ; 1 + 962: 70 40 sbci r23, 0x00 ; 0 + 964: 20 e0 ldi r18, 0x00 ; 0 + 966: 30 e0 ldi r19, 0x00 ; 0 + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + /* No comma on last configuration */ + *ConfigListOut++ = ','; + 968: 4c e2 ldi r20, 0x2C ; 44 + + /* Account for '\0' */ + ByteCount--; + + for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { + 98e: 84 91 lpm r24, Z + 990: 88 23 and r24, r24 + 992: 81 f0 breq .+32 ; 0x9b4 + 994: 61 31 cpi r22, 0x11 ; 17 + 996: 71 05 cpc r23, r1 + 998: 68 f0 brcs .+26 ; 0x9b4 + 99a: de 01 movw r26, r28 + 99c: 03 c0 rjmp .+6 ; 0x9a4 + 99e: 60 31 cpi r22, 0x10 ; 16 + 9a0: 71 05 cpc r23, r1 + 9a2: 41 f0 breq .+16 ; 0x9b4 + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ConfigListOut++ = c; + 9a4: 8d 93 st X+, r24 + 9a6: ed 01 movw r28, r26 + ConfigName++; + 9a8: 31 96 adiw r30, 0x01 ; 1 + ByteCount--; + 9aa: 61 50 subi r22, 0x01 ; 1 + 9ac: 70 40 sbci r23, 0x00 ; 0 + + for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { + 9ae: 84 91 lpm r24, Z + 9b0: 88 23 and r24, r24 + 9b2: a9 f7 brne .-22 ; 0x99e + *ConfigListOut++ = c; + ConfigName++; + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + 9b4: 22 30 cpi r18, 0x02 ; 2 + 9b6: 31 05 cpc r19, r1 + 9b8: 21 f4 brne .+8 ; 0x9c2 + *ConfigListOut++ = ','; + ByteCount--; + } + } + + *ConfigListOut = '\0'; + 9ba: 18 82 st Y, r1 +} + 9bc: df 91 pop r29 + 9be: cf 91 pop r28 + 9c0: 08 95 ret + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + /* No comma on last configuration */ + *ConfigListOut++ = ','; + 9c2: 49 93 st Y+, r20 + ByteCount--; + 9c4: 61 50 subi r22, 0x01 ; 1 + 9c6: 70 40 sbci r23, 0x00 ; 0 + 9c8: 2f 5f subi r18, 0xFF ; 255 + 9ca: 3f 4f sbci r19, 0xFF ; 255 + 9cc: ce cf rjmp .-100 ; 0x96a + +000009ce : +#include + +void RandomInit(void) +{ + +} + 9ce: 08 95 ret + +000009d0 : + +uint8_t RandomGetByte(void) +{ + return rand() & 0xFF; + 9d0: 0c 94 d4 25 jmp 0x4ba8 ; 0x4ba8 +} + 9d4: 08 95 ret + +000009d6 : + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) +{ + 9d6: 0f 93 push r16 + 9d8: 1f 93 push r17 + 9da: cf 93 push r28 + 9dc: df 93 push r29 + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 9de: 66 23 and r22, r22 + 9e0: 61 f0 breq .+24 ; 0x9fa +uint8_t RandomGetByte(void) +{ + return rand() & 0xFF; +} + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) + 9e2: 8c 01 movw r16, r24 + 9e4: 0f 5f subi r16, 0xFF ; 255 + 9e6: 1f 4f sbci r17, 0xFF ; 255 +{ + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 9e8: 61 50 subi r22, 0x01 ; 1 +uint8_t RandomGetByte(void) +{ + return rand() & 0xFF; +} + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) + 9ea: 06 0f add r16, r22 + 9ec: 11 1d adc r17, r1 +{ + uint8_t* BufferPtr = (uint8_t*) Buffer; + 9ee: ec 01 movw r28, r24 + + while(ByteCount--) { + *BufferPtr++ = RandomGetByte(); + 9f0: ef df rcall .-34 ; 0x9d0 + 9f2: 89 93 st Y+, r24 + 9f4: c0 17 cp r28, r16 + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) +{ + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 9f6: d1 07 cpc r29, r17 + 9f8: d9 f7 brne .-10 ; 0x9f0 + 9fa: df 91 pop r29 + *BufferPtr++ = RandomGetByte(); + } +} + 9fc: cf 91 pop r28 + 9fe: 1f 91 pop r17 + a00: 0f 91 pop r16 + a02: 08 95 ret + +00000a04 : + a04: 0e 94 d4 25 call 0x4ba8 ; 0x4ba8 + +void RandomTick(void) +{ + rand(); + rand(); + a08: 0e 94 d4 25 call 0x4ba8 ; 0x4ba8 + rand(); + a0c: 0e 94 d4 25 call 0x4ba8 ; 0x4ba8 + rand(); + a10: 0c 94 d4 25 jmp 0x4ba8 ; 0x4ba8 + +00000a14 : + */ + +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + a14: cf 93 push r28 + a16: df 93 push r29 + a18: fc 01 movw r30, r24 + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + a1a: 21 15 cp r18, r1 + a1c: 31 05 cpc r19, r1 + a1e: 81 f1 breq .+96 ; 0xa80 +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + a20: 61 50 subi r22, 0x01 ; 1 + a22: 70 40 sbci r23, 0x00 ; 0 + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + a24: 62 30 cpi r22, 0x02 ; 2 + a26: 71 05 cpc r23, r1 + a28: 58 f1 brcs .+86 ; 0xa80 + a2a: da 01 movw r26, r20 +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + a2c: 40 e0 ldi r20, 0x00 ; 0 + a2e: 50 e0 ldi r21, 0x00 ; 0 + a30: 18 c0 rjmp .+48 ; 0xa62 + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + uint8_t Byte = *ByteBuffer; + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + a32: d0 5d subi r29, 0xD0 ; 208 + a34: d0 83 st Z, r29 + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + a36: 8c 2f mov r24, r28 + a38: 90 e0 ldi r25, 0x00 ; 0 + a3a: 8f 70 andi r24, 0x0F ; 15 + a3c: 90 70 andi r25, 0x00 ; 0 + a3e: 8a 30 cpi r24, 0x0A ; 10 + a40: 91 05 cpc r25, r1 + a42: d4 f4 brge .+52 ; 0xa78 + a44: 8c 2f mov r24, r28 + a46: 8f 70 andi r24, 0x0F ; 15 + a48: 80 5d subi r24, 0xD0 ; 208 + a4a: 81 83 std Z+1, r24 ; 0x01 + + HexOut += 2; + a4c: 32 96 adiw r30, 0x02 ; 2 + MaxChars -= 2; + CharCount += 2; + a4e: 4e 5f subi r20, 0xFE ; 254 + a50: 5f 4f sbci r21, 0xFF ; 255 + ByteBuffer++; + ByteCount -= 1; + a52: 21 50 subi r18, 0x01 ; 1 + a54: 30 40 sbci r19, 0x00 ; 0 + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + a56: b1 f0 breq .+44 ; 0xa84 + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + + HexOut += 2; + MaxChars -= 2; + a58: 62 50 subi r22, 0x02 ; 2 + a5a: 70 40 sbci r23, 0x00 ; 0 + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + a5c: 62 30 cpi r22, 0x02 ; 2 + a5e: 71 05 cpc r23, r1 + a60: 88 f0 brcs .+34 ; 0xa84 + uint8_t Byte = *ByteBuffer; + a62: cd 91 ld r28, X+ + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + a64: dc 2f mov r29, r28 + a66: d2 95 swap r29 + a68: df 70 andi r29, 0x0F ; 15 + a6a: 8d 2f mov r24, r29 + a6c: 90 e0 ldi r25, 0x00 ; 0 + a6e: 8a 30 cpi r24, 0x0A ; 10 + a70: 91 05 cpc r25, r1 + a72: fc f2 brlt .-66 ; 0xa32 + a74: d9 5c subi r29, 0xC9 ; 201 + a76: de cf rjmp .-68 ; 0xa34 + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + a78: 8c 2f mov r24, r28 + a7a: 8f 70 andi r24, 0x0F ; 15 + a7c: 89 5c subi r24, 0xC9 ; 201 + a7e: e5 cf rjmp .-54 ; 0xa4a +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + a80: 40 e0 ldi r20, 0x00 ; 0 + a82: 50 e0 ldi r21, 0x00 ; 0 + CharCount += 2; + ByteBuffer++; + ByteCount -= 1; + } + + *HexOut = '\0'; + a84: 10 82 st Z, r1 + + return CharCount; +} + a86: ca 01 movw r24, r20 + a88: df 91 pop r29 + a8a: cf 91 pop r28 + a8c: 08 95 ret + +00000a8e : + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) +{ + a8e: cf 93 push r28 + a90: df 93 push r29 + a92: da 01 movw r26, r20 + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + a94: 2c 91 ld r18, X + a96: 22 23 and r18, r18 + a98: 09 f4 brne .+2 ; 0xa9c + a9a: 43 c0 rjmp .+134 ; 0xb22 + a9c: 11 96 adiw r26, 0x01 ; 1 + a9e: 3c 91 ld r19, X + aa0: 11 97 sbiw r26, 0x01 ; 1 + aa2: 33 23 and r19, r19 + aa4: f1 f1 breq .+124 ; 0xb22 + aa6: 61 15 cp r22, r1 + aa8: 71 05 cpc r23, r1 + aaa: d9 f1 breq .+118 ; 0xb22 + *HexOut = '\0'; + + return CharCount; +} + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) + aac: 13 96 adiw r26, 0x03 ; 3 +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + aae: ec 01 movw r28, r24 + uint16_t ByteCount = 0; + ab0: 80 e0 ldi r24, 0x00 ; 0 + ab2: 90 e0 ldi r25, 0x00 ; 0 + ab4: 14 c0 rjmp .+40 ; 0xade + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { + uint8_t Byte = 0; + + Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; + ab6: 22 95 swap r18 + ab8: 20 7f andi r18, 0xF0 ; 240 + Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; + aba: 31 34 cpi r19, 0x41 ; 65 + abc: 30 f5 brcc .+76 ; 0xb0a + abe: 34 2f mov r19, r20 + ac0: 23 2b or r18, r19 + + *ByteBuffer = Byte; + ac2: 29 93 st Y+, r18 + + ByteBuffer++; + MaxBytes--; + ByteCount++; + ac4: 01 96 adiw r24, 0x01 ; 1 + *HexOut = '\0'; + + return CharCount; +} + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) + ac6: fd 01 movw r30, r26 + ac8: 31 97 sbiw r30, 0x01 ; 1 +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + aca: 20 81 ld r18, Z + acc: 22 23 and r18, r18 + ace: 31 f1 breq .+76 ; 0xb1c + ad0: 3c 91 ld r19, X + ad2: 33 23 and r19, r19 + ad4: 31 f1 breq .+76 ; 0xb22 + ad6: 12 96 adiw r26, 0x02 ; 2 + ad8: 68 17 cp r22, r24 + ada: 79 07 cpc r23, r25 + adc: f9 f0 breq .+62 ; 0xb1c + if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { + ade: 42 2f mov r20, r18 + ae0: 40 53 subi r20, 0x30 ; 48 + ae2: 4a 30 cpi r20, 0x0A ; 10 + ae4: 18 f0 brcs .+6 ; 0xaec + ae6: 41 51 subi r20, 0x11 ; 17 + ae8: 46 30 cpi r20, 0x06 ; 6 + aea: d8 f4 brcc .+54 ; 0xb22 + aec: 43 2f mov r20, r19 + aee: 40 53 subi r20, 0x30 ; 48 + af0: 4a 30 cpi r20, 0x0A ; 10 + af2: 20 f0 brcs .+8 ; 0xafc + af4: 53 2f mov r21, r19 + af6: 51 54 subi r21, 0x41 ; 65 + af8: 56 30 cpi r21, 0x06 ; 6 + afa: 98 f4 brcc .+38 ; 0xb22 + uint8_t Byte = 0; + + Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; + afc: 21 34 cpi r18, 0x41 ; 65 + afe: d8 f2 brcs .-74 ; 0xab6 + b00: 22 95 swap r18 + b02: 20 7f andi r18, 0xF0 ; 240 + b04: 20 57 subi r18, 0x70 ; 112 + Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; + b06: 31 34 cpi r19, 0x41 ; 65 + b08: d0 f2 brcs .-76 ; 0xabe + b0a: 37 53 subi r19, 0x37 ; 55 + b0c: 23 2b or r18, r19 + + *ByteBuffer = Byte; + b0e: 29 93 st Y+, r18 + + ByteBuffer++; + MaxBytes--; + ByteCount++; + b10: 01 96 adiw r24, 0x01 ; 1 + *HexOut = '\0'; + + return CharCount; +} + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) + b12: fd 01 movw r30, r26 + b14: 31 97 sbiw r30, 0x01 ; 1 +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + b16: 20 81 ld r18, Z + b18: 22 23 and r18, r18 + b1a: d1 f6 brne .-76 ; 0xad0 + /* Odd number of characters */ + return 0; + } + + return ByteCount; +} + b1c: df 91 pop r29 + b1e: cf 91 pop r28 + b20: 08 95 ret + } + } + + if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) { + /* Odd number of characters */ + return 0; + b22: 80 e0 ldi r24, 0x00 ; 0 + b24: 90 e0 ldi r25, 0x00 ; 0 + } + + return ByteCount; +} + b26: df 91 pop r29 + b28: cf 91 pop r28 + b2a: 08 95 ret + +00000b2c : + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +void MemoryInit(void) +{ + b2c: cf 93 push r28 + b2e: df 93 push r29 + b30: 00 d0 rcall .+0 ; 0xb32 + b32: 00 d0 rcall .+0 ; 0xb34 + b34: cd b7 in r28, 0x3d ; 61 + b36: de b7 in r29, 0x3e ; 62 + /* Configure MEMORY_FLASH_USART for SPI master mode 0 with maximum clock frequency */ + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + b38: a0 e6 ldi r26, 0x60 ; 96 + b3a: b6 e0 ldi r27, 0x06 ; 6 + b3c: 80 e1 ldi r24, 0x10 ; 16 + b3e: 15 96 adiw r26, 0x05 ; 5 + b40: 8c 93 st X, r24 + b42: 15 97 sbiw r26, 0x05 ; 5 + MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS; + b44: 9a e1 ldi r25, 0x1A ; 26 + b46: 11 96 adiw r26, 0x01 ; 1 + b48: 9c 93 st X, r25 + b4a: 11 97 sbiw r26, 0x01 ; 1 + + MEMORY_FLASH_USART.BAUDCTRLA = 0; + b4c: e0 ea ldi r30, 0xA0 ; 160 + b4e: f9 e0 ldi r31, 0x09 ; 9 + b50: 16 82 std Z+6, r1 ; 0x06 + MEMORY_FLASH_USART.BAUDCTRLB = 0; + b52: 17 82 std Z+7, r1 ; 0x07 + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc; + b54: 93 ec ldi r25, 0xC3 ; 195 + b56: 95 83 std Z+5, r25 ; 0x05 + MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; + b58: 98 e1 ldi r25, 0x18 ; 24 + b5a: 94 83 std Z+4, r25 ; 0x04 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + b5c: 16 96 adiw r26, 0x06 ; 6 + b5e: 8c 93 st X, r24 + b60: 16 97 sbiw r26, 0x06 ; 6 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + b62: 87 ed ldi r24, 0xD7 ; 215 + b64: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + b68: 80 91 a1 09 lds r24, 0x09A1 + b6c: 86 ff sbrs r24, 6 + b6e: fc cf rjmp .-8 ; 0xb68 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + b70: 80 e4 ldi r24, 0x40 ; 64 + b72: e0 ea ldi r30, 0xA0 ; 160 + b74: f9 e0 ldi r31, 0x09 ; 9 + b76: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + b78: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + b7c: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + b80: 80 91 a1 09 lds r24, 0x09A1 + b84: 86 ff sbrs r24, 6 + b86: fc cf rjmp .-8 ; 0xb80 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + b88: 80 e4 ldi r24, 0x40 ; 64 + b8a: e0 ea ldi r30, 0xA0 ; 160 + b8c: f9 e0 ldi r31, 0x09 ; 9 + b8e: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + b90: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + b94: 90 e1 ldi r25, 0x10 ; 16 + b96: e0 e6 ldi r30, 0x60 ; 96 + b98: f6 e0 ldi r31, 0x06 ; 6 + b9a: 95 83 std Z+5, r25 ; 0x05 + MEMORY_FLASH_USART.BAUDCTRLB = 0; + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc; + MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; + + + if ( !(FlashReadStatusRegister() & FLASH_STATUS_REG_PAGESIZE_BIT) ) { + b9c: 80 fd sbrc r24, 0 + b9e: 47 c0 rjmp .+142 ; 0xc2e + return !(FlashReadStatusRegister() & FLASH_STATUS_REG_READY_BIT); +} + +INLINE void FlashConfigurePageSize(void) +{ + uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; + ba0: 8d e3 ldi r24, 0x3D ; 61 + ba2: 89 83 std Y+1, r24 ; 0x01 + ba4: 8a e2 ldi r24, 0x2A ; 42 + ba6: 8a 83 std Y+2, r24 ; 0x02 + ba8: 80 e8 ldi r24, 0x80 ; 128 + baa: 8b 83 std Y+3, r24 ; 0x03 + bac: 86 ea ldi r24, 0xA6 ; 166 + bae: 8c 83 std Y+4, r24 ; 0x04 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + bb0: a0 e6 ldi r26, 0x60 ; 96 + bb2: b6 e0 ldi r27, 0x06 ; 6 + bb4: 20 e1 ldi r18, 0x10 ; 16 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + bb6: 37 ed ldi r19, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + bb8: e0 ea ldi r30, 0xA0 ; 160 + bba: f9 e0 ldi r31, 0x09 ; 9 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + bbc: 90 e4 ldi r25, 0x40 ; 64 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + bbe: 16 96 adiw r26, 0x06 ; 6 + bc0: 2c 93 st X, r18 + bc2: 16 97 sbiw r26, 0x06 ; 6 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + bc4: 30 93 a0 09 sts 0x09A0, r19 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + bc8: 80 91 a1 09 lds r24, 0x09A1 + bcc: 86 ff sbrs r24, 6 + bce: fc cf rjmp .-8 ; 0xbc8 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + bd0: 91 83 std Z+1, r25 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + bd2: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + bd6: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + bda: 80 91 a1 09 lds r24, 0x09A1 + bde: 86 ff sbrs r24, 6 + be0: fc cf rjmp .-8 ; 0xbda + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + be2: 91 83 std Z+1, r25 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + be4: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + be8: 15 96 adiw r26, 0x05 ; 5 + bea: 2c 93 st X, r18 + bec: 15 97 sbiw r26, 0x05 ; 5 + +INLINE void FlashConfigurePageSize(void) +{ + uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; + + while(FlashIsBusy()); + bee: 87 ff sbrs r24, 7 + bf0: e6 cf rjmp .-52 ; 0xbbe + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + bf2: 80 e1 ldi r24, 0x10 ; 16 + bf4: e0 e6 ldi r30, 0x60 ; 96 + bf6: f6 e0 ldi r31, 0x06 ; 6 + bf8: 86 83 std Z+6, r24 ; 0x06 + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +void MemoryInit(void) + bfa: ce 01 movw r24, r28 + bfc: 05 96 adiw r24, 0x05 ; 5 + } +} + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + bfe: fe 01 movw r30, r28 + c00: 31 96 adiw r30, 0x01 ; 1 + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + c02: a0 ea ldi r26, 0xA0 ; 160 + c04: b9 e0 ldi r27, 0x09 ; 9 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + c06: 30 e4 ldi r19, 0x40 ; 64 +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + c08: 21 91 ld r18, Z+ + c0a: 20 93 a0 09 sts 0x09A0, r18 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + c0e: 20 91 a1 09 lds r18, 0x09A1 + c12: 26 ff sbrs r18, 6 + c14: fc cf rjmp .-8 ; 0xc0e + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + c16: 11 96 adiw r26, 0x01 ; 1 + c18: 3c 93 st X, r19 + c1a: 11 97 sbiw r26, 0x01 ; 1 + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + c1c: 20 91 a0 09 lds r18, 0x09A0 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + c20: e8 17 cp r30, r24 + c22: f9 07 cpc r31, r25 + c24: 89 f7 brne .-30 ; 0xc08 + + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPIWriteBlock(Sequence, sizeof(Sequence)); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + c26: 80 e1 ldi r24, 0x10 ; 16 + c28: e0 e6 ldi r30, 0x60 ; 96 + c2a: f6 e0 ldi r31, 0x06 ; 6 + c2c: 85 83 std Z+5, r24 ; 0x05 + + if ( !(FlashReadStatusRegister() & FLASH_STATUS_REG_PAGESIZE_BIT) ) { + /* Configure for 256 byte Dataflash if not already done. */ + FlashConfigurePageSize(); + } +} + c2e: 24 96 adiw r28, 0x04 ; 4 + c30: cd bf out 0x3d, r28 ; 61 + c32: de bf out 0x3e, r29 ; 62 + c34: df 91 pop r29 + c36: cf 91 pop r28 + c38: 08 95 ret + +00000c3a : + +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + c3a: 0f 93 push r16 + c3c: 1f 93 push r17 + c3e: cf 93 push r28 + c40: df 93 push r29 + c42: ec 01 movw r28, r24 + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + c44: 8b 01 movw r16, r22 + c46: 20 e0 ldi r18, 0x00 ; 0 + c48: 30 e0 ldi r19, 0x00 ; 0 + c4a: 80 91 0d 21 lds r24, 0x210D + c4e: 90 e0 ldi r25, 0x00 ; 0 + c50: a0 e0 ldi r26, 0x00 ; 0 + c52: b0 e0 ldi r27, 0x00 ; 0 + c54: dc 01 movw r26, r24 + c56: 99 27 eor r25, r25 + c58: 88 27 eor r24, r24 + c5a: 08 0f add r16, r24 + c5c: 19 1f adc r17, r25 + c5e: 2a 1f adc r18, r26 + c60: 3b 1f adc r19, r27 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + c62: a0 e6 ldi r26, 0x60 ; 96 + c64: b6 e0 ldi r27, 0x06 ; 6 + c66: 60 e1 ldi r22, 0x10 ; 16 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + c68: 77 ed ldi r23, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + c6a: e0 ea ldi r30, 0xA0 ; 160 + c6c: f9 e0 ldi r31, 0x09 ; 9 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + c6e: 90 e4 ldi r25, 0x40 ; 64 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + c70: 16 96 adiw r26, 0x06 ; 6 + c72: 6c 93 st X, r22 + c74: 16 97 sbiw r26, 0x06 ; 6 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + c76: 70 93 a0 09 sts 0x09A0, r23 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + c7a: 80 91 a1 09 lds r24, 0x09A1 + c7e: 86 ff sbrs r24, 6 + c80: fc cf rjmp .-8 ; 0xc7a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + c82: 91 83 std Z+1, r25 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + c84: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + c88: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + c8c: 80 91 a1 09 lds r24, 0x09A1 + c90: 86 ff sbrs r24, 6 + c92: fc cf rjmp .-8 ; 0xc8c + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + c94: 91 83 std Z+1, r25 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + c96: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + c9a: 15 96 adiw r26, 0x05 ; 5 + c9c: 6c 93 st X, r22 + c9e: 15 97 sbiw r26, 0x05 ; 5 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashRead(void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + ca0: 87 ff sbrs r24, 7 + ca2: e6 cf rjmp .-52 ; 0xc70 + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + ca4: 80 e1 ldi r24, 0x10 ; 16 + ca6: e0 e6 ldi r30, 0x60 ; 96 + ca8: f6 e0 ldi r31, 0x06 ; 6 + caa: 86 83 std Z+6, r24 ; 0x06 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + cac: 83 e0 ldi r24, 0x03 ; 3 + cae: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + cb2: 80 91 a1 09 lds r24, 0x09A1 + cb6: 86 ff sbrs r24, 6 + cb8: fc cf rjmp .-8 ; 0xcb2 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + cba: 80 e4 ldi r24, 0x40 ; 64 + cbc: e0 ea ldi r30, 0xA0 ; 160 + cbe: f9 e0 ldi r31, 0x09 ; 9 + cc0: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + cc2: 80 91 a0 09 lds r24, 0x09A0 +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + cc6: c9 01 movw r24, r18 + cc8: aa 27 eor r26, r26 + cca: bb 27 eor r27, r27 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + ccc: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + cd0: 80 91 a1 09 lds r24, 0x09A1 + cd4: 86 ff sbrs r24, 6 + cd6: fc cf rjmp .-8 ; 0xcd0 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + cd8: 80 e4 ldi r24, 0x40 ; 64 + cda: e0 ea ldi r30, 0xA0 ; 160 + cdc: f9 e0 ldi r31, 0x09 ; 9 + cde: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + ce0: 80 91 a0 09 lds r24, 0x09A0 + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + SPITransferByte( (Address >> 8) & 0xFF ); + ce4: bb 27 eor r27, r27 + ce6: a3 2f mov r26, r19 + ce8: 92 2f mov r25, r18 + cea: 81 2f mov r24, r17 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + cec: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + cf0: 80 91 a1 09 lds r24, 0x09A1 + cf4: 86 ff sbrs r24, 6 + cf6: fc cf rjmp .-8 ; 0xcf0 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + cf8: 80 e4 ldi r24, 0x40 ; 64 + cfa: e0 ea ldi r30, 0xA0 ; 160 + cfc: f9 e0 ldi r31, 0x09 ; 9 + cfe: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + d00: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + d04: 00 93 a0 09 sts 0x09A0, r16 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + d08: 80 91 a1 09 lds r24, 0x09A1 + d0c: 86 ff sbrs r24, 6 + d0e: fc cf rjmp .-8 ; 0xd08 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + d10: 80 e4 ldi r24, 0x40 ; 64 + d12: e0 ea ldi r30, 0xA0 ; 160 + d14: f9 e0 ldi r31, 0x09 ; 9 + d16: 81 83 std Z+1, r24 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + d18: 80 91 a0 09 lds r24, 0x09A0 + +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + d1c: 41 15 cp r20, r1 + d1e: 51 05 cpc r21, r1 + d20: 71 f0 breq .+28 ; 0xd3e + MEMORY_FLASH_USART.DATA = 0; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + d22: 90 e4 ldi r25, 0x40 ; 64 +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = 0; + d24: 10 92 a0 09 sts 0x09A0, r1 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + d28: 80 91 a1 09 lds r24, 0x09A1 + d2c: 86 ff sbrs r24, 6 + d2e: fc cf rjmp .-8 ; 0xd28 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + d30: 91 83 std Z+1, r25 ; 0x01 + *ByteBuffer++ = MEMORY_FLASH_USART.DATA; + d32: 80 91 a0 09 lds r24, 0x09A0 + d36: 89 93 st Y+, r24 + d38: 41 50 subi r20, 0x01 ; 1 + d3a: 50 40 sbci r21, 0x00 ; 0 + +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + d3c: 99 f7 brne .-26 ; 0xd24 + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + SPITransferByte( (Address >> 8) & 0xFF ); + SPITransferByte( (Address >> 0) & 0xFF ); + SPIReadBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + d3e: 80 e1 ldi r24, 0x10 ; 16 + d40: e0 e6 ldi r30, 0x60 ; 96 + d42: f6 e0 ldi r31, 0x06 ; 6 + d44: 85 83 std Z+5, r24 ; 0x05 + +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + FlashRead(Buffer, FlashAddress, ByteCount); +} + d46: df 91 pop r29 + d48: cf 91 pop r28 + d4a: 1f 91 pop r17 + d4c: 0f 91 pop r16 + d4e: 08 95 ret + +00000d50 : + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + d50: 2f 92 push r2 + d52: 3f 92 push r3 + d54: 4f 92 push r4 + d56: 5f 92 push r5 + d58: 6f 92 push r6 + d5a: 7f 92 push r7 + d5c: 8f 92 push r8 + d5e: 9f 92 push r9 + d60: af 92 push r10 + d62: bf 92 push r11 + d64: cf 92 push r12 + d66: df 92 push r13 + d68: ef 92 push r14 + d6a: ff 92 push r15 + d6c: 0f 93 push r16 + d6e: 1f 93 push r17 + d70: cf 93 push r28 + d72: df 93 push r29 + d74: cd b7 in r28, 0x3d ; 61 + d76: de b7 in r29, 0x3e ; 62 + d78: 26 97 sbiw r28, 0x06 ; 6 + d7a: cd bf out 0x3d, r28 ; 61 + d7c: de bf out 0x3e, r29 ; 62 + d7e: 8b 83 std Y+3, r24 ; 0x03 + d80: 9c 83 std Y+4, r25 ; 0x04 + d82: 4a 01 movw r8, r20 + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + d84: 80 91 0d 21 lds r24, 0x210D + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + d88: 41 15 cp r20, r1 + d8a: 51 05 cpc r21, r1 + d8c: 09 f4 brne .+2 ; 0xd90 + d8e: 1e c1 rjmp .+572 ; 0xfcc + FlashRead(Buffer, FlashAddress, ByteCount); +} + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + d90: 6b 01 movw r12, r22 + d92: ee 24 eor r14, r14 + d94: ff 24 eor r15, r15 + d96: 90 e0 ldi r25, 0x00 ; 0 + d98: a0 e0 ldi r26, 0x00 ; 0 + d9a: b0 e0 ldi r27, 0x00 ; 0 + d9c: dc 01 movw r26, r24 + d9e: 99 27 eor r25, r25 + da0: 88 27 eor r24, r24 + da2: c8 0e add r12, r24 + da4: d9 1e adc r13, r25 + da6: ea 1e adc r14, r26 + da8: fb 1e adc r15, r27 +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / MEMORY_PAGE_SIZE; + uint8_t ByteAddress = Address % MEMORY_PAGE_SIZE; + uint16_t PageBytes = MIN(MEMORY_PAGE_SIZE - ByteAddress, ByteCount); + daa: 21 2c mov r2, r1 + dac: 01 e0 ldi r16, 0x01 ; 1 + dae: 30 2e mov r3, r16 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + db0: 00 e1 ldi r16, 0x10 ; 16 + db2: 30 e1 ldi r19, 0x10 ; 16 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + db4: 47 ed ldi r20, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + db6: e0 ea ldi r30, 0xA0 ; 160 + db8: f9 e0 ldi r31, 0x09 ; 9 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + dba: 50 e4 ldi r21, 0x40 ; 64 + dbc: 20 e4 ldi r18, 0x40 ; 64 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + dbe: 10 e6 ldi r17, 0x60 ; 96 + dc0: 61 2e mov r6, r17 + dc2: 16 e0 ldi r17, 0x06 ; 6 + dc4: 71 2e mov r7, r17 + dc6: 60 e1 ldi r22, 0x10 ; 16 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + dc8: 17 ed ldi r17, 0xD7 ; 215 + dca: 24 01 movw r4, r8 + dcc: 46 01 movw r8, r12 + dce: 57 01 movw r10, r14 +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / MEMORY_PAGE_SIZE; + dd0: bb 27 eor r27, r27 + dd2: ab 2d mov r26, r11 + dd4: 9a 2d mov r25, r10 + dd6: 89 2d mov r24, r9 + dd8: 7c 01 movw r14, r24 + uint8_t ByteAddress = Address % MEMORY_PAGE_SIZE; + dda: 98 2d mov r25, r8 + uint16_t PageBytes = MIN(MEMORY_PAGE_SIZE - ByteAddress, ByteCount); + ddc: 61 01 movw r12, r2 + dde: c8 18 sub r12, r8 + de0: d1 08 sbc r13, r1 + de2: 4c 14 cp r4, r12 + de4: 5d 04 cpc r5, r13 + de6: 08 f4 brcc .+2 ; 0xdea + de8: 62 01 movw r12, r4 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + dea: 60 93 66 06 sts 0x0666, r22 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + dee: 10 93 a0 09 sts 0x09A0, r17 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + df2: 80 91 a1 09 lds r24, 0x09A1 + df6: 86 ff sbrs r24, 6 + df8: fc cf rjmp .-8 ; 0xdf2 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + dfa: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + dfc: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e00: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e04: 80 91 a1 09 lds r24, 0x09A1 + e08: 86 ff sbrs r24, 6 + e0a: fc cf rjmp .-8 ; 0xe04 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e0c: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e0e: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + e12: 30 93 65 06 sts 0x0665, r19 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashMemoryToBuffer(uint16_t PageAddress) +{ + while(FlashIsBusy()); + e16: 87 ff sbrs r24, 7 + e18: e8 cf rjmp .-48 ; 0xdea + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e1a: d3 01 movw r26, r6 + e1c: 16 96 adiw r26, 0x06 ; 6 + e1e: 3c 93 st X, r19 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e20: b3 e5 ldi r27, 0x53 ; 83 + e22: b0 93 a0 09 sts 0x09A0, r27 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e26: 80 91 a1 09 lds r24, 0x09A1 + e2a: 86 ff sbrs r24, 6 + e2c: fc cf rjmp .-8 ; 0xe26 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e2e: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e30: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e34: f0 92 a0 09 sts 0x09A0, r15 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e38: 80 91 a1 09 lds r24, 0x09A1 + e3c: 86 ff sbrs r24, 6 + e3e: fc cf rjmp .-8 ; 0xe38 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e40: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e42: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e46: e0 92 a0 09 sts 0x09A0, r14 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e4a: 80 91 a1 09 lds r24, 0x09A1 + e4e: 86 ff sbrs r24, 6 + e50: fc cf rjmp .-8 ; 0xe4a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e52: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e54: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e58: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e5c: 80 91 a1 09 lds r24, 0x09A1 + e60: 86 ff sbrs r24, 6 + e62: fc cf rjmp .-8 ; 0xe5c + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e64: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e66: 80 91 a0 09 lds r24, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + e6a: 00 93 65 06 sts 0x0665, r16 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e6e: 30 93 66 06 sts 0x0666, r19 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e72: 40 93 a0 09 sts 0x09A0, r20 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e76: 80 91 a1 09 lds r24, 0x09A1 + e7a: 86 ff sbrs r24, 6 + e7c: fc cf rjmp .-8 ; 0xe76 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e7e: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e80: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + e84: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + e88: 80 91 a1 09 lds r24, 0x09A1 + e8c: 86 ff sbrs r24, 6 + e8e: fc cf rjmp .-8 ; 0xe88 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + e90: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + e92: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + e96: 30 93 65 06 sts 0x0665, r19 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + e9a: 87 ff sbrs r24, 7 + e9c: e8 cf rjmp .-48 ; 0xe6e + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + e9e: d3 01 movw r26, r6 + ea0: 16 96 adiw r26, 0x06 ; 6 + ea2: 3c 93 st X, r19 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + ea4: b4 e8 ldi r27, 0x84 ; 132 + ea6: b0 93 a0 09 sts 0x09A0, r27 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + eaa: 80 91 a1 09 lds r24, 0x09A1 + eae: 86 ff sbrs r24, 6 + eb0: fc cf rjmp .-8 ; 0xeaa + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + eb2: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + eb4: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + eb8: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ebc: 80 91 a1 09 lds r24, 0x09A1 + ec0: 86 ff sbrs r24, 6 + ec2: fc cf rjmp .-8 ; 0xebc + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ec4: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + ec6: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + eca: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ece: 80 91 a1 09 lds r24, 0x09A1 + ed2: 86 ff sbrs r24, 6 + ed4: fc cf rjmp .-8 ; 0xece + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ed6: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + ed8: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + edc: 90 93 a0 09 sts 0x09A0, r25 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + ee0: 80 91 a1 09 lds r24, 0x09A1 + ee4: 86 ff sbrs r24, 6 + ee6: fc cf rjmp .-8 ; 0xee0 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + ee8: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + eea: 80 91 a0 09 lds r24, 0x09A0 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + eee: c1 14 cp r12, r1 + ef0: d1 04 cpc r13, r1 + ef2: d9 f0 breq .+54 ; 0xf2a + ef4: c6 01 movw r24, r12 + } +} + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + ef6: ab 81 ldd r26, Y+3 ; 0x03 + ef8: ad 83 std Y+5, r26 ; 0x05 + efa: bc 81 ldd r27, Y+4 ; 0x04 + efc: be 83 std Y+6, r27 ; 0x06 + efe: c9 82 std Y+1, r12 ; 0x01 + f00: da 82 std Y+2, r13 ; 0x02 + f02: ad 81 ldd r26, Y+5 ; 0x05 + f04: be 81 ldd r27, Y+6 ; 0x06 + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + f06: 7d 91 ld r23, X+ + f08: 70 93 a0 09 sts 0x09A0, r23 + f0c: 6d 01 movw r12, r26 + f0e: dc 01 movw r26, r24 + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f10: 80 91 a1 09 lds r24, 0x09A1 + f14: 86 ff sbrs r24, 6 + f16: fc cf rjmp .-8 ; 0xf10 + f18: cd 01 movw r24, r26 + f1a: d6 01 movw r26, r12 + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f1c: 21 83 std Z+1, r18 ; 0x01 + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + f1e: 70 91 a0 09 lds r23, 0x09A0 + f22: 01 97 sbiw r24, 0x01 ; 1 + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + f24: 81 f7 brne .-32 ; 0xf06 + f26: c9 80 ldd r12, Y+1 ; 0x01 + f28: da 80 ldd r13, Y+2 ; 0x02 + SPITransferByte(FLASH_CMD_BUF1_WRITE); + SPITransferByte( 0 ); + SPITransferByte( 0 ); + SPITransferByte( Address ); + SPIWriteBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + f2a: 00 93 65 06 sts 0x0665, r16 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + f2e: 30 93 66 06 sts 0x0666, r19 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f32: 40 93 a0 09 sts 0x09A0, r20 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f36: 80 91 a1 09 lds r24, 0x09A1 + f3a: 86 ff sbrs r24, 6 + f3c: fc cf rjmp .-8 ; 0xf36 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f3e: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + f40: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f44: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f48: 80 91 a1 09 lds r24, 0x09A1 + f4c: 86 ff sbrs r24, 6 + f4e: fc cf rjmp .-8 ; 0xf48 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f50: 21 83 std Z+1, r18 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + f52: 80 91 a0 09 lds r24, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + f56: 30 93 65 06 sts 0x0665, r19 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashBufferToMemory(uint16_t PageAddress) +{ + while(FlashIsBusy()); + f5a: 87 ff sbrs r24, 7 + f5c: e8 cf rjmp .-48 ; 0xf2e + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + f5e: d3 01 movw r26, r6 + f60: 16 96 adiw r26, 0x06 ; 6 + f62: 3c 93 st X, r19 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f64: b3 e8 ldi r27, 0x83 ; 131 + f66: b0 93 a0 09 sts 0x09A0, r27 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f6a: 80 91 a1 09 lds r24, 0x09A1 + f6e: 86 ff sbrs r24, 6 + f70: fc cf rjmp .-8 ; 0xf6a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f72: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + f74: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f78: f0 92 a0 09 sts 0x09A0, r15 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f7c: 80 91 a1 09 lds r24, 0x09A1 + f80: 86 ff sbrs r24, 6 + f82: fc cf rjmp .-8 ; 0xf7c + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f84: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + f86: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f8a: e0 92 a0 09 sts 0x09A0, r14 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + f8e: 80 91 a1 09 lds r24, 0x09A1 + f92: 86 ff sbrs r24, 6 + f94: fc cf rjmp .-8 ; 0xf8e + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + f96: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + f98: 80 91 a0 09 lds r24, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + f9c: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + fa0: 80 91 a1 09 lds r24, 0x09A1 + fa4: 86 ff sbrs r24, 6 + fa6: fc cf rjmp .-8 ; 0xfa0 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + fa8: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + faa: 80 91 a0 09 lds r24, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + fae: 00 93 65 06 sts 0x0665, r16 + + FlashMemoryToBuffer(PageAddress); + FlashWriteBuffer(Buffer, ByteAddress, PageBytes); + FlashBufferToMemory(PageAddress); + + ByteCount -= PageBytes; + fb2: 4c 18 sub r4, r12 + fb4: 5d 08 sbc r5, r13 + Address += PageBytes; + fb6: c6 01 movw r24, r12 + fb8: a0 e0 ldi r26, 0x00 ; 0 + fba: b0 e0 ldi r27, 0x00 ; 0 + fbc: 88 0e add r8, r24 + fbe: 99 1e adc r9, r25 + fc0: aa 1e adc r10, r26 + fc2: bb 1e adc r11, r27 + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + fc4: 41 14 cp r4, r1 + fc6: 51 04 cpc r5, r1 + fc8: 09 f0 breq .+2 ; 0xfcc + fca: 02 cf rjmp .-508 ; 0xdd0 + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + FlashWrite(Buffer, FlashAddress, ByteCount); +} + fcc: 26 96 adiw r28, 0x06 ; 6 + fce: cd bf out 0x3d, r28 ; 61 + fd0: de bf out 0x3e, r29 ; 62 + fd2: df 91 pop r29 + fd4: cf 91 pop r28 + fd6: 1f 91 pop r17 + fd8: 0f 91 pop r16 + fda: ff 90 pop r15 + fdc: ef 90 pop r14 + fde: df 90 pop r13 + fe0: cf 90 pop r12 + fe2: bf 90 pop r11 + fe4: af 90 pop r10 + fe6: 9f 90 pop r9 + fe8: 8f 90 pop r8 + fea: 7f 90 pop r7 + fec: 6f 90 pop r6 + fee: 5f 90 pop r5 + ff0: 4f 90 pop r4 + ff2: 3f 90 pop r3 + ff4: 2f 90 pop r2 + ff6: 08 95 ret + +00000ff8 : + +void MemoryClear(void) +{ + ff8: 1f 93 push r17 + ffa: cf 93 push r28 + ffc: df 93 push r29 + uint32_t PageAddress = ((uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING) / MEMORY_PAGE_SIZE; + ffe: 80 91 0d 21 lds r24, 0x210D + 1002: 90 e0 ldi r25, 0x00 ; 0 + 1004: a0 e0 ldi r26, 0x00 ; 0 + 1006: b0 e0 ldi r27, 0x00 ; 0 + 1008: ba 2f mov r27, r26 + 100a: a9 2f mov r26, r25 + 100c: 98 2f mov r25, r24 + 100e: 88 27 eor r24, r24 +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + FlashWrite(Buffer, FlashAddress, ByteCount); +} + +void MemoryClear(void) + 1010: 9c 01 movw r18, r24 + 1012: 20 50 subi r18, 0x00 ; 0 + 1014: 3f 4f sbci r19, 0xFF ; 255 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 1016: a0 e6 ldi r26, 0x60 ; 96 + 1018: b6 e0 ldi r27, 0x06 ; 6 + 101a: d0 e1 ldi r29, 0x10 ; 16 + 101c: 60 e1 ldi r22, 0x10 ; 16 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 101e: 77 ed ldi r23, 0xD7 ; 215 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1020: e0 ea ldi r30, 0xA0 ; 160 + 1022: f9 e0 ldi r31, 0x09 ; 9 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1024: c0 e4 ldi r28, 0x40 ; 64 + 1026: 50 e4 ldi r21, 0x40 ; 64 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1028: 11 e8 ldi r17, 0x81 ; 129 + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 102a: 16 96 adiw r26, 0x06 ; 6 + 102c: 6c 93 st X, r22 + 102e: 16 97 sbiw r26, 0x06 ; 6 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1030: 70 93 a0 09 sts 0x09A0, r23 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1034: 40 91 a1 09 lds r20, 0x09A1 + 1038: 46 ff sbrs r20, 6 + 103a: fc cf rjmp .-8 ; 0x1034 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 103c: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 103e: 40 91 a0 09 lds r20, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1042: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1046: 40 91 a1 09 lds r20, 0x09A1 + 104a: 46 ff sbrs r20, 6 + 104c: fc cf rjmp .-8 ; 0x1046 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 104e: 51 83 std Z+1, r21 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 1050: 40 91 a0 09 lds r20, 0x09A0 + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 1054: 15 96 adiw r26, 0x05 ; 5 + 1056: 6c 93 st X, r22 + 1058: 15 97 sbiw r26, 0x05 ; 5 + } +} + +INLINE void FlashClearPage(uint16_t PageAddress) +{ + while(FlashIsBusy()); + 105a: 47 ff sbrs r20, 7 + 105c: e6 cf rjmp .-52 ; 0x102a + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + 105e: 16 96 adiw r26, 0x06 ; 6 + 1060: dc 93 st X, r29 + 1062: 16 97 sbiw r26, 0x06 ; 6 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1064: 10 93 a0 09 sts 0x09A0, r17 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 1068: 40 91 a1 09 lds r20, 0x09A1 + 106c: 46 ff sbrs r20, 6 + 106e: fc cf rjmp .-8 ; 0x1068 + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1070: c1 83 std Z+1, r28 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 1072: 40 91 a0 09 lds r20, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1076: 90 93 a0 09 sts 0x09A0, r25 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 107a: 40 91 a1 09 lds r20, 0x09A1 + 107e: 46 ff sbrs r20, 6 + 1080: fc cf rjmp .-8 ; 0x107a + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1082: c1 83 std Z+1, r28 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 1084: 40 91 a0 09 lds r20, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 1088: 80 93 a0 09 sts 0x09A0, r24 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 108c: 40 91 a1 09 lds r20, 0x09A1 + 1090: 46 ff sbrs r20, 6 + 1092: fc cf rjmp .-8 ; 0x108c + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 1094: c1 83 std Z+1, r28 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 1096: 40 91 a0 09 lds r20, 0x09A0 +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + 109a: 10 92 a0 09 sts 0x09A0, r1 + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + 109e: 40 91 a1 09 lds r20, 0x09A1 + 10a2: 46 ff sbrs r20, 6 + 10a4: fc cf rjmp .-8 ; 0x109e + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + 10a6: c1 83 std Z+1, r28 ; 0x01 + + return MEMORY_FLASH_USART.DATA; + 10a8: 40 91 a0 09 lds r20, 0x09A0 + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_PAGE_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + 10ac: 15 96 adiw r26, 0x05 ; 5 + 10ae: dc 93 st X, r29 + 10b0: 15 97 sbiw r26, 0x05 ; 5 + 10b2: 01 96 adiw r24, 0x01 ; 1 +void MemoryClear(void) +{ + uint32_t PageAddress = ((uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING) / MEMORY_PAGE_SIZE; + uint16_t PageCount = MEMORY_SIZE_PER_SETTING / MEMORY_PAGE_SIZE; + + while(PageCount > 0) { + 10b4: 82 17 cp r24, r18 + 10b6: 93 07 cpc r25, r19 + 10b8: 09 f0 breq .+2 ; 0x10bc + 10ba: b7 cf rjmp .-146 ; 0x102a + FlashClearPage(PageAddress); + PageCount--; + PageAddress++; + } +} + 10bc: df 91 pop r29 + 10be: cf 91 pop r28 + 10c0: 1f 91 pop r17 + 10c2: 08 95 ret + +000010c4 : + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + 10c4: 0f 93 push r16 + 10c6: 1f 93 push r17 + 10c8: fc 01 movw r30, r24 + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + 10ca: 40 30 cpi r20, 0x00 ; 0 + 10cc: 80 e0 ldi r24, 0x00 ; 0 + 10ce: 58 07 cpc r21, r24 + 10d0: 81 e0 ldi r24, 0x01 ; 1 + 10d2: 68 07 cpc r22, r24 + 10d4: 80 e0 ldi r24, 0x00 ; 0 + 10d6: 78 07 cpc r23, r24 + 10d8: 20 f0 brcs .+8 ; 0x10e2 + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + MemoryWriteBlock(Buffer, BlockAddress, ByteCount); + return true; + } +} + 10da: 81 e0 ldi r24, 0x01 ; 1 + 10dc: 1f 91 pop r17 + 10de: 0f 91 pop r16 + 10e0: 08 95 ret + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* Prevent writing out of bounds by silently ignoring it */ + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + 10e2: 80 e0 ldi r24, 0x00 ; 0 + 10e4: 90 e0 ldi r25, 0x00 ; 0 + 10e6: a1 e0 ldi r26, 0x01 ; 1 + 10e8: b0 e0 ldi r27, 0x00 ; 0 + 10ea: 84 1b sub r24, r20 + 10ec: 95 0b sbc r25, r21 + 10ee: a6 0b sbc r26, r22 + 10f0: b7 0b sbc r27, r23 + ByteCount = MIN(ByteCount, BytesLeft); + 10f2: 89 01 movw r16, r18 + 10f4: 20 e0 ldi r18, 0x00 ; 0 + 10f6: 30 e0 ldi r19, 0x00 ; 0 + 10f8: 80 17 cp r24, r16 + 10fa: 91 07 cpc r25, r17 + 10fc: a2 07 cpc r26, r18 + 10fe: b3 07 cpc r27, r19 + 1100: 40 f0 brcs .+16 ; 0x1112 + MemoryWriteBlock(Buffer, BlockAddress, ByteCount); + 1102: cf 01 movw r24, r30 + 1104: ba 01 movw r22, r20 + 1106: a8 01 movw r20, r16 + 1108: 23 de rcall .-954 ; 0xd50 + 110a: 81 e0 ldi r24, 0x01 ; 1 + return true; + } +} + 110c: 1f 91 pop r17 + 110e: 0f 91 pop r16 + 1110: 08 95 ret + 1112: 8c 01 movw r16, r24 + /* Prevent writing out of bounds by silently ignoring it */ + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + 1114: 9d 01 movw r18, r26 + 1116: cf 01 movw r24, r30 + MemoryWriteBlock(Buffer, BlockAddress, ByteCount); + 1118: ba 01 movw r22, r20 + 111a: a8 01 movw r20, r16 + 111c: 19 de rcall .-974 ; 0xd50 + 111e: f5 cf rjmp .-22 ; 0x110a + +00001120 : + 1120: 0f 93 push r16 + 1122: 1f 93 push r17 + return true; + } +} + +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + 1124: fc 01 movw r30, r24 + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + 1126: 40 30 cpi r20, 0x00 ; 0 + 1128: 80 e0 ldi r24, 0x00 ; 0 + 112a: 58 07 cpc r21, r24 + 112c: 81 e0 ldi r24, 0x01 ; 1 + 112e: 68 07 cpc r22, r24 + 1130: 80 e0 ldi r24, 0x00 ; 0 + 1132: 78 07 cpc r23, r24 + 1134: 20 f0 brcs .+8 ; 0x113e + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + 1136: 80 e0 ldi r24, 0x00 ; 0 + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + MemoryReadBlock(Buffer, BlockAddress, ByteCount); + return true; + } +} + 1138: 1f 91 pop r17 + 113a: 0f 91 pop r16 + 113c: 08 95 ret + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + } else { + /* Calculate bytes left in memory and issue reading */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + 113e: 80 e0 ldi r24, 0x00 ; 0 + 1140: 90 e0 ldi r25, 0x00 ; 0 + 1142: a1 e0 ldi r26, 0x01 ; 1 + 1144: b0 e0 ldi r27, 0x00 ; 0 + 1146: 84 1b sub r24, r20 + 1148: 95 0b sbc r25, r21 + 114a: a6 0b sbc r26, r22 + 114c: b7 0b sbc r27, r23 + ByteCount = MIN(ByteCount, BytesLeft); + 114e: 89 01 movw r16, r18 + 1150: 20 e0 ldi r18, 0x00 ; 0 + 1152: 30 e0 ldi r19, 0x00 ; 0 + 1154: 80 17 cp r24, r16 + 1156: 91 07 cpc r25, r17 + 1158: a2 07 cpc r26, r18 + 115a: b3 07 cpc r27, r19 + 115c: 40 f0 brcs .+16 ; 0x116e + MemoryReadBlock(Buffer, BlockAddress, ByteCount); + 115e: cf 01 movw r24, r30 + 1160: ba 01 movw r22, r20 + 1162: a8 01 movw r20, r16 + 1164: 6a dd rcall .-1324 ; 0xc3a + 1166: 81 e0 ldi r24, 0x01 ; 1 + return true; + 1168: 1f 91 pop r17 + } +} + 116a: 0f 91 pop r16 + 116c: 08 95 ret + 116e: 8c 01 movw r16, r24 + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + } else { + /* Calculate bytes left in memory and issue reading */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + 1170: 9d 01 movw r18, r26 + 1172: cf 01 movw r24, r30 + MemoryReadBlock(Buffer, BlockAddress, ByteCount); + 1174: ba 01 movw r22, r20 + 1176: a8 01 movw r20, r16 + 1178: 60 dd rcall .-1344 ; 0xc3a + 117a: 81 e0 ldi r24, 0x01 ; 1 + 117c: f5 cf rjmp .-22 ; 0x1168 + +0000117e : + [BUTTON_ACTION_UID_RIGHT_DECREMENT] = "UID_RIGHT_DECREMENT" +}; + +void ButtonInit(void) +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + 117e: e0 e0 ldi r30, 0x00 ; 0 + 1180: f6 e0 ldi r31, 0x06 ; 6 + 1182: 80 e4 ldi r24, 0x40 ; 64 + 1184: 82 83 std Z+2, r24 ; 0x02 + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; + 1186: 88 e1 ldi r24, 0x18 ; 24 + 1188: 86 8b std Z+22, r24 ; 0x16 +} + 118a: 08 95 ret + +0000118c : + +void ButtonTick(void) +{ + 118c: ff 92 push r15 + 118e: 0f 93 push r16 + 1190: 1f 93 push r17 + 1192: cf 93 push r28 + 1194: df 93 push r29 + 1196: cd b7 in r28, 0x3d ; 61 + 1198: de b7 in r29, 0x3e ; 62 + 119a: a0 97 sbiw r28, 0x20 ; 32 + 119c: cd bf out 0x3d, r28 ; 61 + 119e: de bf out 0x3e, r29 ; 62 + static uint8_t LastButtonState = 0; + uint8_t ThisButtonState = ~BUTTON_PORT.IN; + 11a0: 90 91 08 06 lds r25, 0x0608 + 11a4: 90 95 com r25 + uint8_t ThisButtonChange = ThisButtonState ^ LastButtonState; + 11a6: 80 91 a2 20 lds r24, 0x20A2 + 11aa: 89 27 eor r24, r25 + uint8_t ThisButtonPress = ThisButtonChange & ThisButtonState; + 11ac: 89 23 and r24, r25 + LastButtonState = ThisButtonState; + 11ae: 90 93 a2 20 sts 0x20A2, r25 + + if ( ThisButtonPress & BUTTON_MASK ) { + 11b2: 86 ff sbrs r24, 6 + 11b4: 15 c0 rjmp .+42 ; 0x11e0 + uint8_t UidBuffer[32]; + ButtonActionEnum ButtonAction = GlobalSettings.ActiveSettingPtr->ButtonAction; + 11b6: e0 91 0e 21 lds r30, 0x210E + 11ba: f0 91 0f 21 lds r31, 0x210F + 11be: 80 81 ld r24, Z + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + 11c0: 81 30 cpi r24, 0x01 ; 1 + 11c2: b9 f0 breq .+46 ; 0x11f2 + for (uint8_t i=0; i + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + 11c8: 83 30 cpi r24, 0x03 ; 3 + 11ca: 09 f4 brne .+2 ; 0x11ce + 11cc: 4e c0 rjmp .+156 ; 0x126a + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + 11ce: 84 30 cpi r24, 0x04 ; 4 + 11d0: 09 f4 brne .+2 ; 0x11d4 + 11d2: 70 c0 rjmp .+224 ; 0x12b4 + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + 11d4: 85 30 cpi r24, 0x05 ; 5 + 11d6: 09 f4 brne .+2 ; 0x11da + 11d8: 8f c0 rjmp .+286 ; 0x12f8 + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + 11da: 86 30 cpi r24, 0x06 ; 6 + 11dc: 09 f4 brne .+2 ; 0x11e0 + 11de: 68 c0 rjmp .+208 ; 0x12b0 + SettingsCycle(); + } + } +} + 11e0: a0 96 adiw r28, 0x20 ; 32 + 11e2: cd bf out 0x3d, r28 ; 61 + 11e4: de bf out 0x3e, r29 ; 62 + 11e6: df 91 pop r29 + 11e8: cf 91 pop r28 + 11ea: 1f 91 pop r17 + 11ec: 0f 91 pop r16 + 11ee: ff 90 pop r15 + 11f0: 08 95 ret + if ( ThisButtonPress & BUTTON_MASK ) { + uint8_t UidBuffer[32]; + ButtonActionEnum ButtonAction = GlobalSettings.ActiveSettingPtr->ButtonAction; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i + 11fa: a1 c0 rjmp .+322 ; 0x133e + 11fc: ff 24 eor r15, r15 + 11fe: 8e 01 movw r16, r28 + 1200: 0f 5f subi r16, 0xFF ; 255 + 1202: 1f 4f sbci r17, 0xFF ; 255 + UidBuffer[i] = RandomGetByte(); + 1204: e5 db rcall .-2102 ; 0x9d0 + 1206: f8 01 movw r30, r16 + 1208: ef 0d add r30, r15 + 120a: f1 1d adc r31, r1 + 120c: 80 83 st Z, r24 + 120e: f3 94 inc r15 + if ( ThisButtonPress & BUTTON_MASK ) { + uint8_t UidBuffer[32]; + ButtonActionEnum ButtonAction = GlobalSettings.ActiveSettingPtr->ButtonAction; + + if (ButtonAction == BUTTON_ACTION_UID_RANDOM) { + for (uint8_t i=0; i + 1218: e0 91 07 21 lds r30, 0x2107 +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + 121c: f0 91 08 21 lds r31, 0x2108 + 1220: c8 01 movw r24, r16 + 1222: 09 95 icall + 1224: dd cf rjmp .-70 ; 0x11e0 + 1226: e0 91 05 21 lds r30, 0x2105 +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); + 122a: f0 91 06 21 lds r31, 0x2106 + 122e: 8e 01 movw r16, r28 + 1230: 0f 5f subi r16, 0xFF ; 255 + 1232: 1f 4f sbci r17, 0xFF ; 255 + 1234: c8 01 movw r24, r16 + 1236: 09 95 icall + 1238: 20 91 0b 21 lds r18, 0x210B + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 1240: f8 01 movw r30, r16 + 1242: ce 01 movw r24, r28 +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; +} + +void ButtonTick(void) + 1244: 02 96 adiw r24, 0x02 ; 2 + 1246: 21 50 subi r18, 0x01 ; 1 + 1248: 82 0f add r24, r18 + 124a: 91 1d adc r25, r1 + 124c: 21 e0 ldi r18, 0x01 ; 1 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 124e: 22 23 and r18, r18 + uint8_t i; + + for (i=0; i + 1252: 30 81 ld r19, Z + if (UidBuffer[i] == 0xFF) { + 1254: 21 e0 ldi r18, 0x01 ; 1 +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; +} + +void ButtonTick(void) + 1256: 3f 3f cpi r19, 0xFF ; 255 + 1258: 09 f0 breq .+2 ; 0x125c + 125a: 20 e0 ldi r18, 0x00 ; 0 + 125c: 3f 5f subi r19, 0xFF ; 255 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + 125e: 30 83 st Z, r19 + 1260: 31 96 adiw r30, 0x01 ; 1 + 1262: e8 17 cp r30, r24 + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 1268: d7 cf rjmp .-82 ; 0x1218 + 126a: e0 91 05 21 lds r30, 0x2105 + 126e: f0 91 06 21 lds r31, 0x2106 + 1272: 8e 01 movw r16, r28 + 1274: 0f 5f subi r16, 0xFF ; 255 + 1276: 1f 4f sbci r17, 0xFF ; 255 + 1278: c8 01 movw r24, r16 + 127a: 09 95 icall + 127c: 20 91 0b 21 lds r18, 0x210B + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + 1280: 31 e0 ldi r19, 0x01 ; 1 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 1282: 22 23 and r18, r18 + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 1284: 49 f2 breq .-110 ; 0x1218 + 1286: 21 50 subi r18, 0x01 ; 1 + 1288: 33 23 and r19, r19 + if (Carry) { + 128a: d9 f3 breq .-10 ; 0x1282 + 128c: 82 2f mov r24, r18 + if (UidBuffer[i] == 0xFF) { + 128e: 90 e0 ldi r25, 0x00 ; 0 + 1290: f8 01 movw r30, r16 + 1292: e8 0f add r30, r24 + 1294: f9 1f adc r31, r25 + 1296: 40 81 ld r20, Z + 1298: 31 e0 ldi r19, 0x01 ; 1 +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; +} + +void ButtonTick(void) + 129a: 4f 3f cpi r20, 0xFF ; 255 + 129c: 09 f0 breq .+2 ; 0x12a0 + 129e: 30 e0 ldi r19, 0x00 ; 0 + 12a0: 80 0f add r24, r16 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF; + 12a2: 91 1f adc r25, r17 + 12a4: 4f 5f subi r20, 0xFF ; 255 + 12a6: fc 01 movw r30, r24 + 12a8: 40 83 st Z, r20 + 12aa: 22 23 and r18, r18 + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_INCREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 12ac: 61 f7 brne .-40 ; 0x1286 + 12ae: b4 cf rjmp .-152 ; 0x1218 + 12b0: fb d0 rcall .+502 ; 0x14a8 + } + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) { + SettingsCycle(); + 12b2: 96 cf rjmp .-212 ; 0x11e0 + 12b4: e0 91 05 21 lds r30, 0x2105 + 12b8: f0 91 06 21 lds r31, 0x2106 + 12bc: 8e 01 movw r16, r28 + 12be: 0f 5f subi r16, 0xFF ; 255 + 12c0: 1f 4f sbci r17, 0xFF ; 255 + 12c2: c8 01 movw r24, r16 + 12c4: 09 95 icall + 12c6: 20 91 0b 21 lds r18, 0x210B + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i; + + for (i=0; i + 12ce: a4 cf rjmp .-184 ; 0x1218 + 12d0: f8 01 movw r30, r16 + 12d2: ce 01 movw r24, r28 + 12d4: 02 96 adiw r24, 0x02 ; 2 +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; +} + +void ButtonTick(void) + 12d6: 21 50 subi r18, 0x01 ; 1 + 12d8: 82 0f add r24, r18 + 12da: 91 1d adc r25, r1 + 12dc: 21 e0 ldi r18, 0x01 ; 1 + 12de: 22 23 and r18, r18 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 12e0: 31 f0 breq .+12 ; 0x12ee + uint8_t i; + + for (i=0; i + 12f6: 90 cf rjmp .-224 ; 0x1218 + 12f8: e0 91 05 21 lds r30, 0x2105 + 12fc: f0 91 06 21 lds r31, 0x2106 + 1300: 8e 01 movw r16, r28 + 1302: 0f 5f subi r16, 0xFF ; 255 + 1304: 1f 4f sbci r17, 0xFF ; 255 + 1306: c8 01 movw r24, r16 + 1308: 09 95 icall + 130a: 20 91 0b 21 lds r18, 0x210B + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + 130e: 31 e0 ldi r19, 0x01 ; 1 + 1310: 22 23 and r18, r18 + } + + ApplicationSetUid(UidBuffer); + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + 1312: 09 f4 brne .+2 ; 0x1316 + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 1314: 81 cf rjmp .-254 ; 0x1218 + 1316: 21 50 subi r18, 0x01 ; 1 + 1318: 33 23 and r19, r19 + 131a: d1 f3 breq .-12 ; 0x1310 + if (Carry) { + 131c: 82 2f mov r24, r18 + 131e: 90 e0 ldi r25, 0x00 ; 0 + if (UidBuffer[i] == 0x00) { + 1320: f8 01 movw r30, r16 + 1322: e8 0f add r30, r24 + 1324: f9 1f adc r31, r25 + 1326: 40 81 ld r20, Z + 1328: 31 e0 ldi r19, 0x01 ; 1 + 132a: 41 11 cpse r20, r1 +{ + BUTTON_PORT.DIRCLR = BUTTON_MASK; + BUTTON_PORT.BUTTON_PINCTRL = PORT_OPC_PULLUP_gc; +} + +void ButtonTick(void) + 132c: 30 e0 ldi r19, 0x00 ; 0 + 132e: 80 0f add r24, r16 + 1330: 91 1f adc r25, r17 + Carry = 1; + } else { + Carry = 0; + } + + UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF; + 1332: 41 50 subi r20, 0x01 ; 1 + 1334: fc 01 movw r30, r24 + 1336: 40 83 st Z, r20 + 1338: 22 23 and r18, r18 + 133a: 69 f7 brne .-38 ; 0x1316 + } else if (ButtonAction == BUTTON_ACTION_UID_RIGHT_DECREMENT) { + ApplicationGetUid(UidBuffer); + bool Carry = 1; + uint8_t i = ActiveConfiguration.UidSize; + + while(i-- > 0) { + 133c: 6d cf rjmp .-294 ; 0x1218 + 133e: 8e 01 movw r16, r28 + 1340: 0f 5f subi r16, 0xFF ; 255 + 1342: 1f 4f sbci r17, 0xFF ; 255 + 1344: 69 cf rjmp .-302 ; 0x1218 + +00001346 : + 1346: cf 93 push r28 + 1348: df 93 push r29 + } + } +} + +void ButtonGetActionList(char* ListOut, uint16_t BufferSize) +{ + 134a: ec 01 movw r28, r24 + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + 134c: 61 50 subi r22, 0x01 ; 1 + 134e: 70 40 sbci r23, 0x00 ; 0 + 1350: 27 ef ldi r18, 0xF7 ; 247 + 1352: 32 e0 ldi r19, 0x02 ; 2 + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 1354: 4c e2 ldi r20, 0x2C ; 44 + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i sizeof(ButtonActionTable[i]) ) { + 1358: f9 01 movw r30, r18 + 135a: 54 91 lpm r21, Z + 135c: 55 23 and r21, r21 + 135e: 89 f0 breq .+34 ; 0x1382 + 1360: 61 32 cpi r22, 0x21 ; 33 + 1362: 71 05 cpc r23, r1 + 1364: 70 f0 brcs .+28 ; 0x1382 + 1366: de 01 movw r26, r28 + 1368: 03 c0 rjmp .+6 ; 0x1370 + 136a: 60 32 cpi r22, 0x20 ; 32 + 136c: 71 05 cpc r23, r1 + 136e: 49 f0 breq .+18 ; 0x1382 + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ListOut++ = c; + 1370: 5d 93 st X+, r21 + 1372: ed 01 movw r28, r26 + ActionName++; + 1374: 01 96 adiw r24, 0x01 ; 1 + BufferSize--; + 1376: 61 50 subi r22, 0x01 ; 1 + 1378: 70 40 sbci r23, 0x00 ; 0 + + for (i=0; i sizeof(ButtonActionTable[i]) ) { + 137a: fc 01 movw r30, r24 + 137c: 54 91 lpm r21, Z + 137e: 55 23 and r21, r21 + 1380: a1 f7 brne .-24 ; 0x136a + *ListOut++ = c; + ActionName++; + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + 1382: f3 e0 ldi r31, 0x03 ; 3 + 1384: 27 3b cpi r18, 0xB7 ; 183 + 1386: 3f 07 cpc r19, r31 + 1388: 21 f4 brne .+8 ; 0x1392 + *ListOut++ = ','; + BufferSize--; + } + } + + *ListOut = '\0'; + 138a: 18 82 st Y, r1 +} + 138c: df 91 pop r29 + 138e: cf 91 pop r28 + 1390: 08 95 ret + BufferSize--; + } + + if ( i < (BUTTON_ACTION_COUNT - 1) ) { + /* No comma on last configuration */ + *ListOut++ = ','; + 1392: 49 93 st Y+, r20 + BufferSize--; + 1394: 61 50 subi r22, 0x01 ; 1 + 1396: 70 40 sbci r23, 0x00 ; 0 + 1398: 20 5e subi r18, 0xE0 ; 224 + 139a: 3f 4f sbci r19, 0xFF ; 255 + uint8_t i; + + /* Account for '\0' */ + BufferSize--; + + for (i=0; i + 13a4: f2 cf rjmp .-28 ; 0x138a + +000013a6 : + *ListOut = '\0'; +} + +void ButtonSetActionById(ButtonActionEnum Action) +{ + GlobalSettings.ActiveSettingPtr->ButtonAction = Action; + 13a6: e0 91 0e 21 lds r30, 0x210E + 13aa: f0 91 0f 21 lds r31, 0x210F + 13ae: 80 83 st Z, r24 +} + 13b0: 08 95 ret + +000013b2 : + +void ButtonGetActionByName(char* ActionOut, uint16_t BufferSize) +{ + 13b2: ab 01 movw r20, r22 + strncpy_P(ActionOut, ButtonActionTable[GlobalSettings.ActiveSettingPtr->ButtonAction], BufferSize); + 13b4: e0 91 0e 21 lds r30, 0x210E + 13b8: f0 91 0f 21 lds r31, 0x210F + 13bc: 60 81 ld r22, Z + 13be: 70 e0 ldi r23, 0x00 ; 0 + 13c0: 66 0f add r22, r22 + 13c2: 77 1f adc r23, r23 + 13c4: 62 95 swap r22 + 13c6: 72 95 swap r23 + 13c8: 70 7f andi r23, 0xF0 ; 240 + 13ca: 76 27 eor r23, r22 + 13cc: 60 7f andi r22, 0xF0 ; 240 + 13ce: 76 27 eor r23, r22 + 13d0: 69 50 subi r22, 0x09 ; 9 + 13d2: 7d 4f sbci r23, 0xFD ; 253 + 13d4: 0c 94 f4 25 jmp 0x4be8 ; 0x4be8 + +000013d8 : +} + 13d8: cf 93 push r28 + +bool ButtonSetActionByName(const char* Action) +{ + 13da: df 93 push r29 + 13dc: ec 01 movw r28, r24 + uint8_t i; + + for (i=0; i + 13e6: 00 97 sbiw r24, 0x00 ; 0 + 13e8: 71 f1 breq .+92 ; 0x1446 + 13ea: ce 01 movw r24, r28 + 13ec: 67 e1 ldi r22, 0x17 ; 23 + 13ee: 73 e0 ldi r23, 0x03 ; 3 + 13f0: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 13f4: 00 97 sbiw r24, 0x00 ; 0 + 13f6: 69 f1 breq .+90 ; 0x1452 + 13f8: ce 01 movw r24, r28 + 13fa: 67 e3 ldi r22, 0x37 ; 55 + 13fc: 73 e0 ldi r23, 0x03 ; 3 + 13fe: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1402: 00 97 sbiw r24, 0x00 ; 0 + 1404: 41 f1 breq .+80 ; 0x1456 + 1406: ce 01 movw r24, r28 + 1408: 67 e5 ldi r22, 0x57 ; 87 + 140a: 73 e0 ldi r23, 0x03 ; 3 + 140c: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1410: 00 97 sbiw r24, 0x00 ; 0 + 1412: 19 f1 breq .+70 ; 0x145a + 1414: ce 01 movw r24, r28 + 1416: 67 e7 ldi r22, 0x77 ; 119 + 1418: 73 e0 ldi r23, 0x03 ; 3 + 141a: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 141e: 00 97 sbiw r24, 0x00 ; 0 + 1420: f1 f0 breq .+60 ; 0x145e + 1422: ce 01 movw r24, r28 + 1424: 67 e9 ldi r22, 0x97 ; 151 + 1426: 73 e0 ldi r23, 0x03 ; 3 + 1428: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 142c: 00 97 sbiw r24, 0x00 ; 0 + 142e: c9 f0 breq .+50 ; 0x1462 + 1430: ce 01 movw r24, r28 + 1432: 67 eb ldi r22, 0xB7 ; 183 + 1434: 73 e0 ldi r23, 0x03 ; 3 + 1436: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 143a: 00 97 sbiw r24, 0x00 ; 0 + 143c: a1 f0 breq .+40 ; 0x1466 + return true; + } + } + + /* Button action not found */ + return false; + 143e: 80 e0 ldi r24, 0x00 ; 0 +} + 1440: df 91 pop r29 + 1442: cf 91 pop r28 + 1444: 08 95 ret + +bool ButtonSetActionByName(const char* Action) +{ + uint8_t i; + + for (i=0; i + 144a: 81 e0 ldi r24, 0x01 ; 1 + return true; + 144c: df 91 pop r29 + } + } + + /* Button action not found */ + return false; +} + 144e: cf 91 pop r28 + 1450: 08 95 ret + 1452: 81 e0 ldi r24, 0x01 ; 1 + +bool ButtonSetActionByName(const char* Action) +{ + uint8_t i; + + for (i=0; i + 1456: 82 e0 ldi r24, 0x02 ; 2 + 1458: f7 cf rjmp .-18 ; 0x1448 + 145a: 83 e0 ldi r24, 0x03 ; 3 + 145c: f5 cf rjmp .-22 ; 0x1448 + 145e: 84 e0 ldi r24, 0x04 ; 4 + 1460: f3 cf rjmp .-26 ; 0x1448 + 1462: 85 e0 ldi r24, 0x05 ; 5 + 1464: f1 cf rjmp .-30 ; 0x1448 + 1466: 86 e0 ldi r24, 0x06 ; 6 + if (strcmp_P(Action, ButtonActionTable[i]) == 0) { + 1468: ef cf rjmp .-34 ; 0x1448 + +0000146a : + .ButtonAction = DEFAULT_BUTTON_ACTION, + } } +}; + +void SettingsLoad(void) { + eeprom_read_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); + 146a: 8d e0 ldi r24, 0x0D ; 13 + 146c: 91 e2 ldi r25, 0x21 ; 33 + 146e: 60 e0 ldi r22, 0x00 ; 0 + 1470: 70 e0 ldi r23, 0x00 ; 0 + 1472: 43 e1 ldi r20, 0x13 ; 19 + 1474: 50 e0 ldi r21, 0x00 ; 0 + 1476: 0c 94 08 28 jmp 0x5010 ; 0x5010 <__eerd_block_x32a4u> + +0000147a : +} + 147a: 8d e0 ldi r24, 0x0D ; 13 + +void SettingsSave(void) { +#if ENABLE_EEPROM_SETTINGS + eeprom_write_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); + 147c: 91 e2 ldi r25, 0x21 ; 33 + 147e: 60 e0 ldi r22, 0x00 ; 0 + 1480: 70 e0 ldi r23, 0x00 ; 0 + 1482: 43 e1 ldi r20, 0x13 ; 19 + 1484: 50 e0 ldi r21, 0x00 ; 0 + 1486: 0c 94 13 28 jmp 0x5026 ; 0x5026 <__eewr_block_x32a4u> + +0000148a : +#endif +} + 148a: 88 30 cpi r24, 0x08 ; 8 + } + } +} + +void SettingsSetActiveById(uint8_t Setting) { + if (Setting < SETTINGS_COUNT) { + 148c: 08 f0 brcs .+2 ; 0x1490 + 148e: 08 95 ret + GlobalSettings.ActiveSetting = Setting; + 1490: 80 93 0d 21 sts 0x210D, r24 + GlobalSettings.ActiveSettingPtr = + &GlobalSettings.Settings[GlobalSettings.ActiveSetting]; + 1494: 90 e0 ldi r25, 0x00 ; 0 + 1496: 88 0f add r24, r24 + 1498: 99 1f adc r25, r25 + 149a: 80 5f subi r24, 0xF0 ; 240 + 149c: 9e 4d sbci r25, 0xDE ; 222 +} + +void SettingsSetActiveById(uint8_t Setting) { + if (Setting < SETTINGS_COUNT) { + GlobalSettings.ActiveSetting = Setting; + GlobalSettings.ActiveSettingPtr = + 149e: 80 93 0e 21 sts 0x210E, r24 + 14a2: 90 93 0f 21 sts 0x210F, r25 + &GlobalSettings.Settings[GlobalSettings.ActiveSetting]; + + /* Settings have changed. Progress changes through system */ + ConfigurationInit(); + 14a6: 0b ca rjmp .-3050 ; 0x8be + +000014a8 : + 14a8: 80 91 0d 21 lds r24, 0x210D +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 14ac: 8f 5f subi r24, 0xFF ; 255 + 14ae: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 14b0: 28 2f mov r18, r24 + 14b2: 30 e0 ldi r19, 0x00 ; 0 + 14b4: f9 01 movw r30, r18 + 14b6: ee 0f add r30, r30 + 14b8: ff 1f adc r31, r31 + 14ba: ef 5e subi r30, 0xEF ; 239 + 14bc: fe 4d sbci r31, 0xDE ; 222 + 14be: 90 81 ld r25, Z + 14c0: 99 23 and r25, r25 + 14c2: 09 f0 breq .+2 ; 0x14c6 + 14c4: 5d c0 rjmp .+186 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 14c6: c9 01 movw r24, r18 + 14c8: 01 96 adiw r24, 0x01 ; 1 + 14ca: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 14cc: 28 2f mov r18, r24 + 14ce: 30 e0 ldi r19, 0x00 ; 0 + 14d0: f9 01 movw r30, r18 + 14d2: ee 0f add r30, r30 + 14d4: ff 1f adc r31, r31 + 14d6: ef 5e subi r30, 0xEF ; 239 + 14d8: fe 4d sbci r31, 0xDE ; 222 + 14da: 90 81 ld r25, Z + 14dc: 99 23 and r25, r25 + 14de: 09 f0 breq .+2 ; 0x14e2 + 14e0: 4f c0 rjmp .+158 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 14e2: c9 01 movw r24, r18 + 14e4: 01 96 adiw r24, 0x01 ; 1 + 14e6: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 14e8: 28 2f mov r18, r24 + 14ea: 30 e0 ldi r19, 0x00 ; 0 + 14ec: f9 01 movw r30, r18 + 14ee: ee 0f add r30, r30 + 14f0: ff 1f adc r31, r31 + 14f2: ef 5e subi r30, 0xEF ; 239 + 14f4: fe 4d sbci r31, 0xDE ; 222 + 14f6: 90 81 ld r25, Z + 14f8: 99 23 and r25, r25 + 14fa: 09 f0 breq .+2 ; 0x14fe + 14fc: 41 c0 rjmp .+130 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 14fe: c9 01 movw r24, r18 + 1500: 01 96 adiw r24, 0x01 ; 1 + 1502: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 1504: 28 2f mov r18, r24 + 1506: 30 e0 ldi r19, 0x00 ; 0 + 1508: f9 01 movw r30, r18 + 150a: ee 0f add r30, r30 + 150c: ff 1f adc r31, r31 + 150e: ef 5e subi r30, 0xEF ; 239 + 1510: fe 4d sbci r31, 0xDE ; 222 + 1512: 90 81 ld r25, Z + 1514: 99 23 and r25, r25 + 1516: a1 f5 brne .+104 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 1518: c9 01 movw r24, r18 + 151a: 01 96 adiw r24, 0x01 ; 1 + 151c: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 151e: 28 2f mov r18, r24 + 1520: 30 e0 ldi r19, 0x00 ; 0 + 1522: f9 01 movw r30, r18 + 1524: ee 0f add r30, r30 + 1526: ff 1f adc r31, r31 + 1528: ef 5e subi r30, 0xEF ; 239 + 152a: fe 4d sbci r31, 0xDE ; 222 + 152c: 90 81 ld r25, Z + 152e: 99 23 and r25, r25 + 1530: 39 f5 brne .+78 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 1532: c9 01 movw r24, r18 + 1534: 01 96 adiw r24, 0x01 ; 1 + 1536: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 1538: 28 2f mov r18, r24 + 153a: 30 e0 ldi r19, 0x00 ; 0 + 153c: f9 01 movw r30, r18 + 153e: ee 0f add r30, r30 + 1540: ff 1f adc r31, r31 + 1542: ef 5e subi r30, 0xEF ; 239 + 1544: fe 4d sbci r31, 0xDE ; 222 + 1546: 90 81 ld r25, Z + 1548: 99 23 and r25, r25 + 154a: d1 f4 brne .+52 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 154c: c9 01 movw r24, r18 + 154e: 01 96 adiw r24, 0x01 ; 1 + 1550: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 1552: 28 2f mov r18, r24 + 1554: 30 e0 ldi r19, 0x00 ; 0 + 1556: f9 01 movw r30, r18 + 1558: ee 0f add r30, r30 + 155a: ff 1f adc r31, r31 + 155c: ef 5e subi r30, 0xEF ; 239 + 155e: fe 4d sbci r31, 0xDE ; 222 + 1560: 90 81 ld r25, Z + 1562: 99 23 and r25, r25 + 1564: 69 f4 brne .+26 ; 0x1580 +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + 1566: c9 01 movw r24, r18 + 1568: 01 96 adiw r24, 0x01 ; 1 + 156a: 87 70 andi r24, 0x07 ; 7 + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + 156c: e8 2f mov r30, r24 + 156e: f0 e0 ldi r31, 0x00 ; 0 + 1570: ee 0f add r30, r30 + 1572: ff 1f adc r31, r31 + 1574: ef 5e subi r30, 0xEF ; 239 + 1576: fe 4d sbci r31, 0xDE ; 222 + 1578: 90 81 ld r25, Z + 157a: 99 23 and r25, r25 + 157c: 09 f4 brne .+2 ; 0x1580 + 157e: 08 95 ret + SettingsSetActiveById(Setting); + 1580: 84 cf rjmp .-248 ; 0x148a + +00001582 : + 1582: 80 91 0d 21 lds r24, 0x210D + } +} + +uint8_t SettingsGetActiveById(void) { + return GlobalSettings.ActiveSetting; +} + 1586: 08 95 ret + +00001588 : + +void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { + 1588: cf 93 push r28 + 158a: df 93 push r29 + 158c: ec 01 movw r28, r24 + SettingOut[0] = SettingsGetActiveById() + '0'; + 158e: f9 df rcall .-14 ; 0x1582 + 1590: 80 5d subi r24, 0xD0 ; 208 + 1592: 88 83 st Y, r24 + 1594: 19 82 std Y+1, r1 ; 0x01 + SettingOut[1] = '\0'; + 1596: df 91 pop r29 +} + 1598: cf 91 pop r28 + 159a: 08 95 ret + +0000159c : + 159c: fc 01 movw r30, r24 + +bool SettingsSetActiveByName(const char* Setting) { + uint8_t SettingNr = Setting[0] - '0'; + 159e: 80 81 ld r24, Z + + if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { + 15a0: 91 81 ldd r25, Z+1 ; 0x01 + 15a2: 99 23 and r25, r25 + 15a4: 41 f4 brne .+16 ; 0x15b6 + SettingOut[0] = SettingsGetActiveById() + '0'; + SettingOut[1] = '\0'; +} + +bool SettingsSetActiveByName(const char* Setting) { + uint8_t SettingNr = Setting[0] - '0'; + 15a6: 80 53 subi r24, 0x30 ; 48 + + if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { + 15a8: 88 30 cpi r24, 0x08 ; 8 + 15aa: 10 f0 brcs .+4 ; 0x15b0 + SettingsSetActiveById(SettingNr); + return true; + } else { + return false; + 15ac: 80 e0 ldi r24, 0x00 ; 0 + } +} + 15ae: 08 95 ret + +bool SettingsSetActiveByName(const char* Setting) { + uint8_t SettingNr = Setting[0] - '0'; + + if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { + SettingsSetActiveById(SettingNr); + 15b0: 6c df rcall .-296 ; 0x148a + 15b2: 81 e0 ldi r24, 0x01 ; 1 + return true; + 15b4: 08 95 ret + 15b6: 80 e0 ldi r24, 0x00 ; 0 + } else { + return false; + 15b8: 08 95 ret + +000015ba : + +uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE]; +TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED; +static uint8_t TerminalInitDelay = INIT_DELAY; + +void TerminalSendString(const char* s) { + 15ba: bc 01 movw r22, r24 + CDC_Device_SendString(&TerminalHandle, s); + 15bc: 80 e0 ldi r24, 0x00 ; 0 + 15be: 90 e2 ldi r25, 0x20 ; 32 + 15c0: 0c 94 2b 24 jmp 0x4856 ; 0x4856 + +000015c4 : +} + 15c4: cf 93 push r28 + +void TerminalSendStringP(const char* s) { + 15c6: df 93 push r29 + char c; + + while( (c = pgm_read_byte(s++)) != '\0' ) { + 15c8: fc 01 movw r30, r24 + 15ca: 64 91 lpm r22, Z + 15cc: 66 23 and r22, r22 + 15ce: 59 f0 breq .+22 ; 0x15e6 + 15d0: ec 01 movw r28, r24 + 15d2: 21 96 adiw r28, 0x01 ; 1 +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } + 15d4: 80 e0 ldi r24, 0x00 ; 0 + 15d6: 90 e2 ldi r25, 0x20 ; 32 + 15d8: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 15dc: fe 01 movw r30, r28 + 15de: 21 96 adiw r28, 0x01 ; 1 + 15e0: 64 91 lpm r22, Z + 15e2: 66 23 and r22, r22 + 15e4: b9 f7 brne .-18 ; 0x15d4 + TerminalSendChar(c); + } +} + 15e6: df 91 pop r29 + 15e8: cf 91 pop r28 + 15ea: 08 95 ret + +000015ec : +#endif + + + +void TerminalSendBlock(void* Buffer, uint16_t ByteCount) +{ + 15ec: 9c 01 movw r18, r24 + 15ee: ab 01 movw r20, r22 + CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); + 15f0: 80 e0 ldi r24, 0x00 ; 0 + 15f2: 90 e2 ldi r25, 0x20 ; 32 + 15f4: b9 01 movw r22, r18 + 15f6: 0c 94 4f 24 jmp 0x489e ; 0x489e + +000015fa : +} + 15fa: 80 e2 ldi r24, 0x20 ; 32 + } +} + +void TerminalInit(void) +{ + TERMINAL_VBUS_PORT.DIRCLR = TERMINAL_VBUS_MASK; + 15fc: e0 e6 ldi r30, 0x60 ; 96 + 15fe: f6 e0 ldi r31, 0x06 ; 6 + 1600: 82 83 std Z+2, r24 ; 0x02 +} + 1602: 08 95 ret + +00001604 : + +void TerminalTask(void) +{ + 1604: cf 93 push r28 + 1606: df 93 push r29 + CDC_Device_USBTask(&TerminalHandle); + 1608: 80 e0 ldi r24, 0x00 ; 0 + 160a: 90 e2 ldi r25, 0x20 ; 32 + 160c: 0e 94 e5 24 call 0x49ca ; 0x49ca + USB_USBTask(); + 1610: 0e 94 44 1e call 0x3c88 ; 0x3c88 + CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); +} + + +static void ProcessByte(void) { + int16_t Byte = CDC_Device_ReceiveByte(&TerminalHandle); + 1614: 80 e0 ldi r24, 0x00 ; 0 + 1616: 90 e2 ldi r25, 0x20 ; 32 + 1618: 0e 94 ff 24 call 0x49fe ; 0x49fe + 161c: ec 01 movw r28, r24 + + if (Byte >= 0) { + 161e: 97 fd sbrc r25, 7 + 1620: 0a c0 rjmp .+20 ; 0x1636 + LED_PORT.OUTTGL = Mask; +} + +static inline +void LEDPulse(uint8_t Mask) { + LEDPulseMask = Mask; + 1622: 80 e1 ldi r24, 0x10 ; 16 + 1624: 80 93 a3 20 sts 0x20A3, r24 + LED_PORT.OUTSET = Mask; + 1628: e0 e0 ldi r30, 0x00 ; 0 + 162a: f6 e0 ldi r31, 0x06 ; 6 + 162c: 85 83 std Z+5, r24 ; 0x05 + /* Byte received */ + LEDPulse(LED_RED); + + if (XModemProcessByte(Byte)) { + 162e: 8c 2f mov r24, r28 + 1630: b3 d2 rcall .+1382 ; 0x1b98 + 1632: 88 23 and r24, r24 + 1634: 19 f0 breq .+6 ; 0x163c + 1636: df 91 pop r29 +{ + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); + + ProcessByte(); +} + 1638: cf 91 pop r28 + 163a: 08 95 ret + 163c: 8c 2f mov r24, r28 + /* Byte received */ + LEDPulse(LED_RED); + + if (XModemProcessByte(Byte)) { + /* XModem handled the byte */ + } else if (CommandLineProcessByte(Byte)) { + 163e: 33 d4 rcall .+2150 ; 0x1ea6 + 1640: df 91 pop r29 + 1642: cf 91 pop r28 +{ + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); + + ProcessByte(); +} + 1644: 08 95 ret + +00001646 : + 1646: 80 91 a4 20 lds r24, 0x20A4 + } +} + +static void SenseVBus(void) +{ + switch(TerminalState) { + 164a: 81 30 cpi r24, 0x01 ; 1 + 164c: 09 f1 breq .+66 ; 0x1690 + 164e: 81 30 cpi r24, 0x01 ; 1 + 1650: 30 f0 brcs .+12 ; 0x165e + 1652: 82 30 cpi r24, 0x02 ; 2 + 1654: 59 f1 breq .+86 ; 0x16ac + 1656: 83 30 cpi r24, 0x03 ; 3 + 1658: 71 f0 breq .+28 ; 0x1676 + +void TerminalTick(void) +{ + SenseVBus(); + + XModemTick(); + 165a: f7 d3 rcall .+2030 ; 0x1e4a + 165c: c7 c5 rjmp .+2958 ; 0x21ec + CommandLineTick(); + 165e: 80 91 68 06 lds r24, 0x0668 +} + 1662: 85 ff sbrs r24, 5 + +static void SenseVBus(void) +{ + switch(TerminalState) { + case TERMINAL_UNINITIALIZED: + if (TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK) { + 1664: fa cf rjmp .-12 ; 0x165a + 1666: 84 e1 ldi r24, 0x14 ; 20 + 1668: 80 93 1b 20 sts 0x201B, r24 + /* Not initialized and VBUS sense high */ + TerminalInitDelay = INIT_DELAY; + 166c: 81 e0 ldi r24, 0x01 ; 1 + 166e: 80 93 a4 20 sts 0x20A4, r24 + TerminalState = TERMINAL_INITIALIZING; + 1672: eb d3 rcall .+2006 ; 0x1e4a + 1674: bb c5 rjmp .+2934 ; 0x21ec + 1676: 80 91 1b 20 lds r24, 0x201B + +void TerminalTick(void) +{ + SenseVBus(); + + XModemTick(); + 167a: 81 50 subi r24, 0x01 ; 1 + CommandLineTick(); + 167c: 80 93 1b 20 sts 0x201B, r24 +} + 1680: 88 23 and r24, r24 + TerminalState = TERMINAL_UNITIALIZING; + } + break; + + case TERMINAL_UNITIALIZING: + if (--TerminalInitDelay == 0) { + 1682: 59 f7 brne .-42 ; 0x165a + 1684: 0e 94 78 22 call 0x44f0 ; 0x44f0 + 1688: d3 d8 rcall .-3674 ; 0x830 + 168a: 10 92 a4 20 sts 0x20A4, r1 + 168e: e5 cf rjmp .-54 ; 0x165a + USB_Disable(); + 1690: 80 91 1b 20 lds r24, 0x201B + SystemStopUSBClock(); + 1694: 81 50 subi r24, 0x01 ; 1 + 1696: 80 93 1b 20 sts 0x201B, r24 + TerminalState = TERMINAL_UNINITIALIZED; + 169a: 88 23 and r24, r24 + 169c: f1 f6 brne .-68 ; 0x165a + TerminalState = TERMINAL_INITIALIZING; + } + break; + + case TERMINAL_INITIALIZING: + if (--TerminalInitDelay == 0) { + 169e: ad d8 rcall .-3750 ; 0x7fa + 16a0: 0e 94 b3 22 call 0x4566 ; 0x4566 + 16a4: 82 e0 ldi r24, 0x02 ; 2 + 16a6: 80 93 a4 20 sts 0x20A4, r24 + 16aa: d7 cf rjmp .-82 ; 0x165a + SystemStartUSBClock(); + 16ac: 80 91 68 06 lds r24, 0x0668 + USB_Init(); + 16b0: 85 fd sbrc r24, 5 + 16b2: d3 cf rjmp .-90 ; 0x165a + TerminalState = TERMINAL_INITIALIZED; + 16b4: 84 e1 ldi r24, 0x14 ; 20 + 16b6: 80 93 1b 20 sts 0x201B, r24 + 16ba: 83 e0 ldi r24, 0x03 ; 3 + } + break; + + case TERMINAL_INITIALIZED: + if (!(TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK)) { + 16bc: 80 93 a4 20 sts 0x20A4, r24 + 16c0: c4 d3 rcall .+1928 ; 0x1e4a + 16c2: 94 c5 rjmp .+2856 ; 0x21ec + +000016c4 : + /* Initialized and VBUS sense low */ + TerminalInitDelay = INIT_DELAY; + 16c4: 80 e2 ldi r24, 0x20 ; 32 + 16c6: e0 e0 ldi r30, 0x00 ; 0 + 16c8: f6 e0 ldi r31, 0x06 ; 6 + TerminalState = TERMINAL_UNITIALIZING; + 16ca: 85 83 std Z+5, r24 ; 0x05 + 16cc: 08 95 ret + +000016ce : + 16ce: 80 e2 ldi r24, 0x20 ; 32 + +void TerminalTick(void) +{ + SenseVBus(); + + XModemTick(); + 16d0: e0 e0 ldi r30, 0x00 ; 0 + 16d2: f6 e0 ldi r31, 0x06 ; 6 + CommandLineTick(); + 16d4: 86 83 std Z+6, r24 ; 0x06 + 16d6: 08 95 ret + +000016d8 : +} + 16d8: 80 e0 ldi r24, 0x00 ; 0 + + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + CDC_Device_ConfigureEndpoints(&TerminalHandle); + 16da: 90 e2 ldi r25, 0x20 ; 32 + 16dc: 0c 94 05 24 jmp 0x480a ; 0x480a + +000016e0 : +} + 16e0: 80 e0 ldi r24, 0x00 ; 0 + +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&TerminalHandle); + 16e2: 90 e2 ldi r25, 0x20 ; 32 + 16e4: 0c 94 5a 23 jmp 0x46b4 ; 0x46b4 + +000016e8 : + +extern const PROGMEM CommandEntryType CommandTable[]; + +CommandStatusIdType CommandGetVersion(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR( + 16e8: 2d b7 in r18, 0x3d ; 61 + 16ea: 3e b7 in r19, 0x3e ; 62 + 16ec: 2c 50 subi r18, 0x0C ; 12 + 16ee: 30 40 sbci r19, 0x00 ; 0 + 16f0: 2d bf out 0x3d, r18 ; 61 + 16f2: 3e bf out 0x3e, r19 ; 62 + 16f4: ed b7 in r30, 0x3d ; 61 + 16f6: fe b7 in r31, 0x3e ; 62 + 16f8: 31 96 adiw r30, 0x01 ; 1 + 16fa: ad b7 in r26, 0x3d ; 61 + 16fc: be b7 in r27, 0x3e ; 62 + 16fe: 11 96 adiw r26, 0x01 ; 1 + 1700: 8d 93 st X+, r24 + 1702: 9c 93 st X, r25 + 1704: 12 97 sbiw r26, 0x02 ; 2 + 1706: 80 e0 ldi r24, 0x00 ; 0 + 1708: 91 e0 ldi r25, 0x01 ; 1 + 170a: 82 83 std Z+2, r24 ; 0x02 + 170c: 93 83 std Z+3, r25 ; 0x03 + 170e: 87 eb ldi r24, 0xB7 ; 183 + 1710: 93 e0 ldi r25, 0x03 ; 3 + 1712: 84 83 std Z+4, r24 ; 0x04 + 1714: 95 83 std Z+5, r25 ; 0x05 + 1716: 80 ef ldi r24, 0xF0 ; 240 + 1718: 93 e0 ldi r25, 0x03 ; 3 + 171a: 86 83 std Z+6, r24 ; 0x06 + 171c: 97 83 std Z+7, r25 ; 0x07 + 171e: 87 ef ldi r24, 0xF7 ; 247 + 1720: 93 e0 ldi r25, 0x03 ; 3 + 1722: 80 87 std Z+8, r24 ; 0x08 + 1724: 91 87 std Z+9, r25 ; 0x09 + 1726: 8e ef ldi r24, 0xFE ; 254 + 1728: 93 e0 ldi r25, 0x03 ; 3 + 172a: 82 87 std Z+10, r24 ; 0x0a + 172c: 93 87 std Z+11, r25 ; 0x0b + 172e: 0e 94 0c 26 call 0x4c18 ; 0x4c18 + "Chameleon-Mini %S using LUFA %S compiled with AVR-GCC %S" + ), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__) + ); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 1732: 2d b7 in r18, 0x3d ; 61 + 1734: 3e b7 in r19, 0x3e ; 62 + 1736: 24 5f subi r18, 0xF4 ; 244 + 1738: 3f 4f sbci r19, 0xFF ; 255 + 173a: 2d bf out 0x3d, r18 ; 61 + 173c: 3e bf out 0x3e, r19 ; 62 +} + 173e: 85 e6 ldi r24, 0x65 ; 101 + 1740: 08 95 ret + +00001742 : + +CommandStatusIdType CommandGetConfig(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + 1742: 2d b7 in r18, 0x3d ; 61 + 1744: 3e b7 in r19, 0x3e ; 62 + 1746: 28 50 subi r18, 0x08 ; 8 + 1748: 30 40 sbci r19, 0x00 ; 0 + 174a: 2d bf out 0x3d, r18 ; 61 + 174c: 3e bf out 0x3e, r19 ; 62 + 174e: ed b7 in r30, 0x3d ; 61 + 1750: fe b7 in r31, 0x3e ; 62 + 1752: 31 96 adiw r30, 0x01 ; 1 + 1754: ad b7 in r26, 0x3d ; 61 + 1756: be b7 in r27, 0x3e ; 62 + 1758: 11 96 adiw r26, 0x01 ; 1 + 175a: 8d 93 st X+, r24 + 175c: 9c 93 st X, r25 + 175e: 12 97 sbiw r26, 0x02 ; 2 + 1760: 80 e0 ldi r24, 0x00 ; 0 + 1762: 91 e0 ldi r25, 0x01 ; 1 + 1764: 82 83 std Z+2, r24 ; 0x02 + 1766: 93 83 std Z+3, r25 ; 0x03 + 1768: 84 e0 ldi r24, 0x04 ; 4 + 176a: 94 e0 ldi r25, 0x04 ; 4 + 176c: 84 83 std Z+4, r24 ; 0x04 + 176e: 95 83 std Z+5, r25 ; 0x05 + 1770: 89 ee ldi r24, 0xE9 ; 233 + 1772: 90 e2 ldi r25, 0x20 ; 32 + 1774: 86 83 std Z+6, r24 ; 0x06 + 1776: 97 83 std Z+7, r25 ; 0x07 + 1778: 0e 94 0c 26 call 0x4c18 ; 0x4c18 + PSTR("%s"), ActiveConfiguration.ConfigurationName); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 177c: 2d b7 in r18, 0x3d ; 61 + 177e: 3e b7 in r19, 0x3e ; 62 + 1780: 28 5f subi r18, 0xF8 ; 248 + 1782: 3f 4f sbci r19, 0xFF ; 255 + 1784: 2d bf out 0x3d, r18 ; 61 + 1786: 3e bf out 0x3e, r19 ; 62 + +} + 1788: 85 e6 ldi r24, 0x65 ; 101 + 178a: 08 95 ret + +0000178c : + +CommandStatusIdType CommandSetConfig(const char* InParam) +{ + if (ConfigurationSetByName(InParam)) { + 178c: 9e d8 rcall .-3780 ; 0x8ca + 178e: 88 23 and r24, r24 + 1790: 11 f4 brne .+4 ; 0x1796 + 1792: 8a ec ldi r24, 0xCA ; 202 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 1794: 08 95 ret + } +} + 1796: 71 de rcall .-798 ; 0x147a +} + +CommandStatusIdType CommandSetConfig(const char* InParam) +{ + if (ConfigurationSetByName(InParam)) { + SettingsSave(); + 1798: 84 e6 ldi r24, 0x64 ; 100 + 179a: 08 95 ret + +0000179c : + return COMMAND_INFO_OK_ID; + 179c: 60 e0 ldi r22, 0x00 ; 0 + 179e: 71 e0 ldi r23, 0x01 ; 1 + } +} + +CommandStatusIdType CommandExecConfig(char* OutMessage) +{ + ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE); + 17a0: dc d8 rcall .-3656 ; 0x95a + 17a2: 85 e6 ldi r24, 0x65 ; 101 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 17a4: 08 95 ret + +000017a6 : + 17a6: 0f 93 push r16 + +CommandStatusIdType CommandGetUid(char* OutParam) +{ + 17a8: 1f 93 push r17 + 17aa: cf 93 push r28 + 17ac: df 93 push r29 + 17ae: cd b7 in r28, 0x3d ; 61 + 17b0: de b7 in r29, 0x3e ; 62 + 17b2: a1 97 sbiw r28, 0x21 ; 33 + 17b4: cd bf out 0x3d, r28 ; 61 + 17b6: de bf out 0x3e, r29 ; 62 + 17b8: 8c 01 movw r16, r24 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + 17ba: 20 91 0b 21 lds r18, 0x210B +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); + 17be: e0 91 05 21 lds r30, 0x2105 + 17c2: f0 91 06 21 lds r31, 0x2106 + 17c6: ce 01 movw r24, r28 + 17c8: 01 96 adiw r24, 0x01 ; 1 + 17ca: 29 a3 lds r18, 0x59 + 17cc: 09 95 icall + + ApplicationGetUid(UidBuffer); + + BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, + 17ce: c8 01 movw r24, r16 + 17d0: 60 e0 ldi r22, 0x00 ; 0 + 17d2: 71 e0 ldi r23, 0x01 ; 1 + 17d4: ae 01 movw r20, r28 + 17d6: 4f 5f subi r20, 0xFF ; 255 + 17d8: 5f 4f sbci r21, 0xFF ; 255 + 17da: 29 a1 lds r18, 0x49 + 17dc: 30 e0 ldi r19, 0x00 ; 0 + 17de: 1a d9 rcall .-3532 ; 0xa14 + 17e0: 85 e6 ldi r24, 0x65 ; 101 + UidBuffer, UidSize); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 17e2: a1 96 adiw r28, 0x21 ; 33 + 17e4: cd bf out 0x3d, r28 ; 61 + 17e6: de bf out 0x3e, r29 ; 62 + 17e8: df 91 pop r29 + 17ea: cf 91 pop r28 + 17ec: 1f 91 pop r17 + 17ee: 0f 91 pop r16 + 17f0: 08 95 ret + +000017f2 : + 17f2: bf 92 push r11 + +CommandStatusIdType CommandSetUid(const char* InParam) +{ + 17f4: cf 92 push r12 + 17f6: df 92 push r13 + 17f8: ef 92 push r14 + 17fa: ff 92 push r15 + 17fc: 0f 93 push r16 + 17fe: 1f 93 push r17 + 1800: cf 93 push r28 + 1802: df 93 push r29 + 1804: cd b7 in r28, 0x3d ; 61 + 1806: de b7 in r29, 0x3e ; 62 + 1808: a0 97 sbiw r28, 0x20 ; 32 + 180a: cd bf out 0x3d, r28 ; 61 + 180c: de bf out 0x3e, r29 ; 62 + 180e: 8c 01 movw r16, r24 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + 1810: e0 90 0b 21 lds r14, 0x210B + 1814: ff 24 eor r15, r15 + + if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { + 1816: 67 e0 ldi r22, 0x07 ; 7 + 1818: 74 e0 ldi r23, 0x04 ; 4 + 181a: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 181e: 00 97 sbiw r24, 0x00 ; 0 + 1820: 49 f5 brne .+82 ; 0x1874 + /* Load with random bytes */ + for (uint8_t i=0; i + 1828: bb 24 eor r11, r11 + 182a: 00 e0 ldi r16, 0x00 ; 0 + 182c: 10 e0 ldi r17, 0x00 ; 0 + 182e: 6e 01 movw r12, r28 + 1830: 08 94 sec + 1832: c1 1c adc r12, r1 + 1834: d1 1c adc r13, r1 + UidBuffer[i] = RandomGetByte(); + 1836: cc d8 rcall .-3688 ; 0x9d0 + 1838: f6 01 movw r30, r12 + 183a: e0 0f add r30, r16 + 183c: f1 1f adc r31, r17 + 183e: 80 83 st Z, r24 + 1840: b3 94 inc r11 + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + + if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { + /* Load with random bytes */ + for (uint8_t i=0; i + 184c: e0 91 07 21 lds r30, 0x2107 +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + 1850: f0 91 08 21 lds r31, 0x2108 + 1854: c6 01 movw r24, r12 + 1856: 09 95 icall + 1858: 84 e6 ldi r24, 0x64 ; 100 + } + } + + ApplicationSetUid(UidBuffer); + + return COMMAND_INFO_OK_ID; + 185a: a0 96 adiw r28, 0x20 ; 32 +} + 185c: cd bf out 0x3d, r28 ; 61 + 185e: de bf out 0x3e, r29 ; 62 + 1860: df 91 pop r29 + 1862: cf 91 pop r28 + 1864: 1f 91 pop r17 + 1866: 0f 91 pop r16 + 1868: ff 90 pop r15 + 186a: ef 90 pop r14 + 186c: df 90 pop r13 + 186e: cf 90 pop r12 + 1870: bf 90 pop r11 + 1872: 08 95 ret + 1874: 6e 01 movw r12, r28 + for (uint8_t i=0; i + 1886: 8e 15 cp r24, r14 + 1888: 9f 05 cpc r25, r15 + 188a: 01 f3 breq .-64 ; 0x184c + 188c: 8a ec ldi r24, 0xCA ; 202 + 188e: e5 cf rjmp .-54 ; 0x185a + /* Malformed input. Abort */ + return COMMAND_ERR_INVALID_PARAM_ID; + 1890: 6e 01 movw r12, r28 + 1892: 08 94 sec + 1894: c1 1c adc r12, r1 + 1896: d1 1c adc r13, r1 + 1898: d9 cf rjmp .-78 ; 0x184c + +0000189a : + 189a: fc 01 movw r30, r24 + 189c: 80 91 0c 21 lds r24, 0x210C + return COMMAND_INFO_OK_ID; +} + +CommandStatusIdType CommandGetReadOnly(char* OutParam) +{ + if (ActiveConfiguration.ReadOnly) { + 18a0: 88 23 and r24, r24 + 18a2: 29 f4 brne .+10 ; 0x18ae + OutParam[0] = COMMAND_CHAR_TRUE; + } else { + OutParam[0] = COMMAND_CHAR_FALSE; + 18a4: 80 e3 ldi r24, 0x30 ; 48 + 18a6: 80 83 st Z, r24 + } + + OutParam[1] = '\0'; + 18a8: 11 82 std Z+1, r1 ; 0x01 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 18aa: 85 e6 ldi r24, 0x65 ; 101 + 18ac: 08 95 ret +} + +CommandStatusIdType CommandGetReadOnly(char* OutParam) +{ + if (ActiveConfiguration.ReadOnly) { + OutParam[0] = COMMAND_CHAR_TRUE; + 18ae: 81 e3 ldi r24, 0x31 ; 49 + 18b0: 80 83 st Z, r24 + } else { + OutParam[0] = COMMAND_CHAR_FALSE; + } + + OutParam[1] = '\0'; + 18b2: 11 82 std Z+1, r1 ; 0x01 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 18b4: 85 e6 ldi r24, 0x65 ; 101 + 18b6: 08 95 ret + +000018b8 : + +CommandStatusIdType CommandSetReadOnly(const char* InParam) +{ + 18b8: fc 01 movw r30, r24 + if (InParam[1] == '\0') { + 18ba: 81 81 ldd r24, Z+1 ; 0x01 + 18bc: 88 23 and r24, r24 + 18be: 39 f4 brne .+14 ; 0x18ce + if (InParam[0] == COMMAND_CHAR_TRUE) { + 18c0: 80 81 ld r24, Z + 18c2: 81 33 cpi r24, 0x31 ; 49 + 18c4: 31 f0 breq .+12 ; 0x18d2 + ActiveConfiguration.ReadOnly = true; + return COMMAND_INFO_OK_ID; + } else if (InParam[0] == COMMAND_CHAR_FALSE) { + 18c6: 80 33 cpi r24, 0x30 ; 48 + 18c8: 49 f0 breq .+18 ; 0x18dc + ActiveConfiguration.ReadOnly = false; + return COMMAND_INFO_OK_ID; + } + } + + return COMMAND_ERR_INVALID_PARAM_ID; + 18ca: 8a ec ldi r24, 0xCA ; 202 +} + 18cc: 08 95 ret + ActiveConfiguration.ReadOnly = false; + return COMMAND_INFO_OK_ID; + } + } + + return COMMAND_ERR_INVALID_PARAM_ID; + 18ce: 8a ec ldi r24, 0xCA ; 202 + 18d0: 08 95 ret + +CommandStatusIdType CommandSetReadOnly(const char* InParam) +{ + if (InParam[1] == '\0') { + if (InParam[0] == COMMAND_CHAR_TRUE) { + ActiveConfiguration.ReadOnly = true; + 18d2: 81 e0 ldi r24, 0x01 ; 1 + 18d4: 80 93 0c 21 sts 0x210C, r24 + return COMMAND_INFO_OK_ID; + 18d8: 84 e6 ldi r24, 0x64 ; 100 + 18da: 08 95 ret + } else if (InParam[0] == COMMAND_CHAR_FALSE) { + ActiveConfiguration.ReadOnly = false; + 18dc: 10 92 0c 21 sts 0x210C, r1 + return COMMAND_INFO_OK_ID; + 18e0: 84 e6 ldi r24, 0x64 ; 100 + 18e2: 08 95 ret + +000018e4 : + return COMMAND_ERR_INVALID_PARAM_ID; +} + +CommandStatusIdType CommandExecUpload(char* OutMessage) +{ + XModemReceive(MemoryUploadBlock); + 18e4: 82 e6 ldi r24, 0x62 ; 98 + 18e6: 98 e0 ldi r25, 0x08 ; 8 + 18e8: 2c d1 rcall .+600 ; 0x1b42 + 18ea: 8e e6 ldi r24, 0x6E ; 110 + return COMMAND_INFO_XMODEM_WAIT_ID; +} + 18ec: 08 95 ret + +000018ee : + 18ee: 80 e9 ldi r24, 0x90 ; 144 + +CommandStatusIdType CommandExecDownload(char* OutMessage) +{ + XModemSend(MemoryDownloadBlock); + 18f0: 98 e0 ldi r25, 0x08 ; 8 + 18f2: 3f d1 rcall .+638 ; 0x1b72 + 18f4: 8e e6 ldi r24, 0x6E ; 110 + return COMMAND_INFO_XMODEM_WAIT_ID; +} + 18f6: 08 95 ret + +000018f8 : + 18f8: e0 ec ldi r30, 0xC0 ; 192 + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + USB.CTRLB &= ~USB_ATTACH_bm; + 18fa: f4 e0 ldi r31, 0x04 ; 4 + 18fc: 81 81 ldd r24, Z+1 ; 0x01 + 18fe: 8e 7f andi r24, 0xFE ; 254 + 1900: 81 83 std Z+1, r24 ; 0x01 + +CommandStatusIdType CommandExecReset(char* OutMessage) +{ + USB_Detach(); + USB_Disable(); + 1902: 0e 94 78 22 call 0x44f0 ; 0x44f0 + + SystemReset(); + 1906: 0e 94 f0 03 call 0x7e0 ; 0x7e0 + + return COMMAND_INFO_OK_ID; +} + 190a: 84 e6 ldi r24, 0x64 ; 100 + 190c: 08 95 ret + +0000190e : + 190e: e0 ec ldi r30, 0xC0 ; 192 + 1910: f4 e0 ldi r31, 0x04 ; 4 + 1912: 81 81 ldd r24, Z+1 ; 0x01 + 1914: 8e 7f andi r24, 0xFE ; 254 + 1916: 81 83 std Z+1, r24 ; 0x01 + +#ifdef SUPPORT_FIRMWARE_UPGRADE +CommandStatusIdType CommandExecUpgrade(char* OutMessage) +{ + USB_Detach(); + USB_Disable(); + 1918: 0e 94 78 22 call 0x44f0 ; 0x44f0 + + SystemEnterBootloader(); + 191c: 0e 94 f7 03 call 0x7ee ; 0x7ee + + return COMMAND_INFO_OK_ID; +} + 1920: 84 e6 ldi r24, 0x64 ; 100 + 1922: 08 95 ret + +00001924 : +#endif + +CommandStatusIdType CommandGetMemSize(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.MemorySize); + 1924: 2d b7 in r18, 0x3d ; 61 + 1926: 3e b7 in r19, 0x3e ; 62 + 1928: 28 50 subi r18, 0x08 ; 8 + 192a: 30 40 sbci r19, 0x00 ; 0 + 192c: 2d bf out 0x3d, r18 ; 61 + 192e: 3e bf out 0x3e, r19 ; 62 + 1930: ed b7 in r30, 0x3d ; 61 + 1932: fe b7 in r31, 0x3e ; 62 + 1934: 31 96 adiw r30, 0x01 ; 1 + 1936: ad b7 in r26, 0x3d ; 61 + 1938: be b7 in r27, 0x3e ; 62 + 193a: 11 96 adiw r26, 0x01 ; 1 + 193c: 8d 93 st X+, r24 + 193e: 9c 93 st X, r25 + 1940: 12 97 sbiw r26, 0x02 ; 2 + 1942: 80 e0 ldi r24, 0x00 ; 0 + 1944: 91 e0 ldi r25, 0x01 ; 1 + 1946: 82 83 std Z+2, r24 ; 0x02 + 1948: 93 83 std Z+3, r25 ; 0x03 + 194a: 8e e0 ldi r24, 0x0E ; 14 + 194c: 94 e0 ldi r25, 0x04 ; 4 + 194e: 84 83 std Z+4, r24 ; 0x04 + 1950: 95 83 std Z+5, r25 ; 0x05 + 1952: 80 91 09 21 lds r24, 0x2109 + 1956: 90 91 0a 21 lds r25, 0x210A + 195a: 86 83 std Z+6, r24 ; 0x06 + 195c: 97 83 std Z+7, r25 ; 0x07 + 195e: 0e 94 0c 26 call 0x4c18 ; 0x4c18 + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 1962: 2d b7 in r18, 0x3d ; 61 + 1964: 3e b7 in r19, 0x3e ; 62 + 1966: 28 5f subi r18, 0xF8 ; 248 + 1968: 3f 4f sbci r19, 0xFF ; 255 + 196a: 2d bf out 0x3d, r18 ; 61 + 196c: 3e bf out 0x3e, r19 ; 62 +} + 196e: 85 e6 ldi r24, 0x65 ; 101 + 1970: 08 95 ret + +00001972 : + +CommandStatusIdType CommandGetUidSize(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.UidSize); + 1972: 2d b7 in r18, 0x3d ; 61 + 1974: 3e b7 in r19, 0x3e ; 62 + 1976: 28 50 subi r18, 0x08 ; 8 + 1978: 30 40 sbci r19, 0x00 ; 0 + 197a: 2d bf out 0x3d, r18 ; 61 + 197c: 3e bf out 0x3e, r19 ; 62 + 197e: ed b7 in r30, 0x3d ; 61 + 1980: fe b7 in r31, 0x3e ; 62 + 1982: 31 96 adiw r30, 0x01 ; 1 + 1984: ad b7 in r26, 0x3d ; 61 + 1986: be b7 in r27, 0x3e ; 62 + 1988: 11 96 adiw r26, 0x01 ; 1 + 198a: 8d 93 st X+, r24 + 198c: 9c 93 st X, r25 + 198e: 12 97 sbiw r26, 0x02 ; 2 + 1990: 80 e0 ldi r24, 0x00 ; 0 + 1992: 91 e0 ldi r25, 0x01 ; 1 + 1994: 82 83 std Z+2, r24 ; 0x02 + 1996: 93 83 std Z+3, r25 ; 0x03 + 1998: 81 e1 ldi r24, 0x11 ; 17 + 199a: 94 e0 ldi r25, 0x04 ; 4 + 199c: 84 83 std Z+4, r24 ; 0x04 + 199e: 95 83 std Z+5, r25 ; 0x05 + 19a0: 80 91 0b 21 lds r24, 0x210B + 19a4: 86 83 std Z+6, r24 ; 0x06 + 19a6: 17 82 std Z+7, r1 ; 0x07 + 19a8: 0e 94 0c 26 call 0x4c18 ; 0x4c18 + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 19ac: 2d b7 in r18, 0x3d ; 61 + 19ae: 3e b7 in r19, 0x3e ; 62 + 19b0: 28 5f subi r18, 0xF8 ; 248 + 19b2: 3f 4f sbci r19, 0xFF ; 255 + 19b4: 2d bf out 0x3d, r18 ; 61 + 19b6: 3e bf out 0x3e, r19 ; 62 +} + 19b8: 85 e6 ldi r24, 0x65 ; 101 + 19ba: 08 95 ret + +000019bc : + +CommandStatusIdType CommandExecButton(char* OutMessage) +{ + ButtonGetActionList(OutMessage, TERMINAL_BUFFER_SIZE); + 19bc: 60 e0 ldi r22, 0x00 ; 0 + 19be: 71 e0 ldi r23, 0x01 ; 1 + 19c0: c2 dc rcall .-1660 ; 0x1346 + 19c2: 85 e6 ldi r24, 0x65 ; 101 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 19c4: 08 95 ret + +000019c6 : + 19c6: 60 e0 ldi r22, 0x00 ; 0 + +CommandStatusIdType CommandGetButton(char* OutParam) +{ + ButtonGetActionByName(OutParam, TERMINAL_BUFFER_SIZE); + 19c8: 71 e0 ldi r23, 0x01 ; 1 + 19ca: f3 dc rcall .-1562 ; 0x13b2 + 19cc: 85 e6 ldi r24, 0x65 ; 101 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 19ce: 08 95 ret + +000019d0 : + 19d0: 03 dd rcall .-1530 ; 0x13d8 + +CommandStatusIdType CommandSetButton(const char* InParam) +{ + if (ButtonSetActionByName(InParam)) { + 19d2: 88 23 and r24, r24 + 19d4: 11 f4 brne .+4 ; 0x19da + 19d6: 8a ec ldi r24, 0xCA ; 202 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 19d8: 08 95 ret + } +} + 19da: 4f dd rcall .-1378 ; 0x147a +} + +CommandStatusIdType CommandSetButton(const char* InParam) +{ + if (ButtonSetActionByName(InParam)) { + SettingsSave(); + 19dc: 84 e6 ldi r24, 0x64 ; 100 + 19de: 08 95 ret + +000019e0 : + return COMMAND_INFO_OK_ID; + 19e0: 60 e0 ldi r22, 0x00 ; 0 + 19e2: 71 e0 ldi r23, 0x01 ; 1 + } +} + +CommandStatusIdType CommandGetSetting(char* OutParam) +{ + SettingsGetActiveByName(OutParam, TERMINAL_BUFFER_SIZE); + 19e4: d1 dd rcall .-1118 ; 0x1588 + 19e6: 85 e6 ldi r24, 0x65 ; 101 + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 19e8: 08 95 ret + +000019ea : + 19ea: d8 dd rcall .-1104 ; 0x159c + +CommandStatusIdType CommandSetSetting(const char* InParam) +{ + if (SettingsSetActiveByName(InParam)) { + 19ec: 88 23 and r24, r24 + 19ee: 11 f4 brne .+4 ; 0x19f4 + 19f0: 8a ec ldi r24, 0xCA ; 202 + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + 19f2: 08 95 ret + } +} + 19f4: 42 dd rcall .-1404 ; 0x147a +} + +CommandStatusIdType CommandSetSetting(const char* InParam) +{ + if (SettingsSetActiveByName(InParam)) { + SettingsSave(); + 19f6: 84 e6 ldi r24, 0x64 ; 100 + 19f8: 08 95 ret + +000019fa : + return COMMAND_INFO_OK_ID; + 19fa: fe da rcall .-2564 ; 0xff8 + 19fc: 84 e6 ldi r24, 0x64 ; 100 + +CommandStatusIdType CommandExecClear(char* OutParam) +{ + MemoryClear(); + return COMMAND_INFO_OK_ID; +} + 19fe: 08 95 ret + +00001a00 : + 1a00: bf 92 push r11 + +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + 1a02: cf 92 push r12 + 1a04: df 92 push r13 + 1a06: ef 92 push r14 + 1a08: ff 92 push r15 + 1a0a: 0f 93 push r16 + 1a0c: 1f 93 push r17 + 1a0e: cf 93 push r28 + 1a10: df 93 push r29 + 1a12: 7c 01 movw r14, r24 + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + 1a14: cf ef ldi r28, 0xFF ; 255 + 1a16: d0 e0 ldi r29, 0x00 ; 0 + return COMMAND_INFO_OK_ID; +} + +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + 1a18: 2b e1 ldi r18, 0x1B ; 27 + 1a1a: c2 2e mov r12, r18 + 1a1c: 24 e0 ldi r18, 0x04 ; 4 + 1a1e: d2 2e mov r13, r18 + *OutMessage++ = c; + CommandName++; + ByteCount--; + } + + *OutMessage++ = ','; + 1a20: 3c e2 ldi r19, 0x2C ; 44 + 1a22: b3 2e mov r11, r19 +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + 1a24: 86 01 movw r16, r12 + 1a26: 8c e1 ldi r24, 0x1C ; 28 + 1a28: 90 e2 ldi r25, 0x20 ; 32 + 1a2a: b6 01 movw r22, r12 + 1a2c: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1a30: 00 97 sbiw r24, 0x00 ; 0 + 1a32: 29 f1 breq .+74 ; 0x1a7e + const char* CommandName = EntryPtr->Command; + char c; + + while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { + 1a34: f6 01 movw r30, r12 + 1a36: 84 91 lpm r24, Z + 1a38: 88 23 and r24, r24 + 1a3a: 89 f0 breq .+34 ; 0x1a5e + 1a3c: c1 32 cpi r28, 0x21 ; 33 + 1a3e: d1 05 cpc r29, r1 + 1a40: 70 f0 brcs .+28 ; 0x1a5e + 1a42: d7 01 movw r26, r14 + 1a44: 03 c0 rjmp .+6 ; 0x1a4c + 1a46: c0 32 cpi r28, 0x20 ; 32 + 1a48: d1 05 cpc r29, r1 + 1a4a: 49 f0 breq .+18 ; 0x1a5e + *OutMessage++ = c; + 1a4c: 8d 93 st X+, r24 + 1a4e: 7d 01 movw r14, r26 + CommandName++; + 1a50: 0f 5f subi r16, 0xFF ; 255 + 1a52: 1f 4f sbci r17, 0xFF ; 255 + ByteCount--; + 1a54: 21 97 sbiw r28, 0x01 ; 1 + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + const char* CommandName = EntryPtr->Command; + char c; + + while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { + 1a56: f8 01 movw r30, r16 + 1a58: 84 91 lpm r24, Z + 1a5a: 88 23 and r24, r24 + 1a5c: a1 f7 brne .-24 ; 0x1a46 + *OutMessage++ = c; + CommandName++; + ByteCount--; + } + + *OutMessage++ = ','; + 1a5e: f7 01 movw r30, r14 + 1a60: b1 92 st Z+, r11 + 1a62: 7f 01 movw r14, r30 + ByteCount--; + 1a64: 21 97 sbiw r28, 0x01 ; 1 + + EntryPtr++; + 1a66: 86 e1 ldi r24, 0x16 ; 22 + 1a68: 90 e0 ldi r25, 0x00 ; 0 + 1a6a: c8 0e add r12, r24 + 1a6c: d9 1e adc r13, r25 +CommandStatusIdType CommandExecHelp(char* OutMessage) +{ + const CommandEntryType* EntryPtr = CommandTable; + uint16_t ByteCount = TERMINAL_BUFFER_SIZE - 1; /* Account for '\0' */ + + while(strcmp_P(COMMAND_LIST_END, EntryPtr->Command) != 0) { + 1a6e: 86 01 movw r16, r12 + 1a70: 8c e1 ldi r24, 0x1C ; 28 + 1a72: 90 e2 ldi r25, 0x20 ; 32 + 1a74: b6 01 movw r22, r12 + 1a76: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1a7a: 00 97 sbiw r24, 0x00 ; 0 + 1a7c: d9 f6 brne .-74 ; 0x1a34 + ByteCount--; + + EntryPtr++; + } + + *--OutMessage = '\0'; + 1a7e: f7 01 movw r30, r14 + 1a80: 31 97 sbiw r30, 0x01 ; 1 + 1a82: 10 82 st Z, r1 + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + 1a84: 85 e6 ldi r24, 0x65 ; 101 + 1a86: df 91 pop r29 + 1a88: cf 91 pop r28 + 1a8a: 1f 91 pop r17 + 1a8c: 0f 91 pop r16 + 1a8e: ff 90 pop r15 + 1a90: ef 90 pop r14 + 1a92: df 90 pop r13 + 1a94: cf 90 pop r12 + 1a96: bf 90 pop r11 + 1a98: 08 95 ret + +00001a9a : + +CommandStatusIdType CommandGetRssi(char* OutParam) +{ + 1a9a: cf 93 push r28 + 1a9c: df 93 push r29 +} + +static inline +uint16_t AntennaLevelGet(void) +{ + ADCA.CH0.CTRL |= ADC_CH_START_bm; + 1a9e: 20 91 20 02 lds r18, 0x0220 + 1aa2: 20 68 ori r18, 0x80 ; 128 + 1aa4: e0 e0 ldi r30, 0x00 ; 0 + 1aa6: f2 e0 ldi r31, 0x02 ; 2 + 1aa8: 20 a3 lds r18, 0x50 + while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); + 1aaa: 20 91 23 02 lds r18, 0x0223 + 1aae: 20 ff sbrs r18, 0 + 1ab0: fc cf rjmp .-8 ; 0x1aaa + + ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; + 1ab2: 21 e0 ldi r18, 0x01 ; 1 + 1ab4: e0 e0 ldi r30, 0x00 ; 0 + 1ab6: f2 e0 ldi r31, 0x02 ; 2 + 1ab8: 23 a3 lds r18, 0x53 + + int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; + 1aba: 60 91 10 02 lds r22, 0x0210 + 1abe: 70 91 11 02 lds r23, 0x0211 + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + 1ac2: 2d b7 in r18, 0x3d ; 61 + 1ac4: 3e b7 in r19, 0x3e ; 62 + 1ac6: 28 50 subi r18, 0x08 ; 8 + 1ac8: 30 40 sbci r19, 0x00 ; 0 + 1aca: 2d bf out 0x3d, r18 ; 61 + 1acc: 3e bf out 0x3e, r19 ; 62 + 1ace: cd b7 in r28, 0x3d ; 61 + 1ad0: de b7 in r29, 0x3e ; 62 + 1ad2: 21 96 adiw r28, 0x01 ; 1 + 1ad4: ed b7 in r30, 0x3d ; 61 + 1ad6: fe b7 in r31, 0x3e ; 62 + 1ad8: 81 83 std Z+1, r24 ; 0x01 + 1ada: 92 83 std Z+2, r25 ; 0x02 + 1adc: 80 e0 ldi r24, 0x00 ; 0 + 1ade: 91 e0 ldi r25, 0x01 ; 1 + 1ae0: 8a 83 std Y+2, r24 ; 0x02 + 1ae2: 9b 83 std Y+3, r25 ; 0x03 + 1ae4: 84 e1 ldi r24, 0x14 ; 20 + 1ae6: 94 e0 ldi r25, 0x04 ; 4 + 1ae8: 8c 83 std Y+4, r24 ; 0x04 + 1aea: 9d 83 std Y+5, r25 ; 0x05 + if (Result < 0) Result = 0; + + return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); + 1aec: 6e 5b subi r22, 0xBE ; 190 + 1aee: 70 40 sbci r23, 0x00 ; 0 + 1af0: 77 fd sbrc r23, 7 + 1af2: 1a c0 rjmp .+52 ; 0x1b28 + 1af4: 88 27 eor r24, r24 + 1af6: 77 fd sbrc r23, 7 + 1af8: 80 95 com r24 + 1afa: 98 2f mov r25, r24 + 1afc: 29 e6 ldi r18, 0x69 ; 105 + 1afe: 37 e5 ldi r19, 0x57 ; 87 + 1b00: 4b e0 ldi r20, 0x0B ; 11 + 1b02: 50 e0 ldi r21, 0x00 ; 0 + 1b04: 0e 94 65 25 call 0x4aca ; 0x4aca <__mulsi3> + 1b08: dc 01 movw r26, r24 + 1b0a: cb 01 movw r24, r22 + 1b0c: ae 83 std Y+6, r26 ; 0x06 + 1b0e: bf 83 std Y+7, r27 ; 0x07 + 1b10: 0e 94 0c 26 call 0x4c18 ; 0x4c18 + PSTR("%5u mV"), AntennaLevelGet()); + + + return COMMAND_INFO_OK_WITH_TEXT_ID; + 1b14: 2d b7 in r18, 0x3d ; 61 + 1b16: 3e b7 in r19, 0x3e ; 62 + 1b18: 28 5f subi r18, 0xF8 ; 248 + 1b1a: 3f 4f sbci r19, 0xFF ; 255 + 1b1c: 2d bf out 0x3d, r18 ; 61 + 1b1e: 3e bf out 0x3e, r19 ; 62 +} + 1b20: 85 e6 ldi r24, 0x65 ; 101 + 1b22: df 91 pop r29 + 1b24: cf 91 pop r28 + 1b26: 08 95 ret + 1b28: 60 e0 ldi r22, 0x00 ; 0 + 1b2a: 70 e0 ldi r23, 0x00 ; 0 + 1b2c: e3 cf rjmp .-58 ; 0x1af4 + +00001b2e : +static uint32_t BlockAddress; + +static XModemCallbackType CallbackFunc; + +static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { + uint8_t Checksum = CHECKSUM_INIT_VALUE; + 1b2e: 80 e0 ldi r24, 0x00 ; 0 + uint8_t* DataPtr = (uint8_t*) Buffer; + 1b30: e0 e2 ldi r30, 0x20 ; 32 + 1b32: f1 e2 ldi r31, 0x21 ; 33 + + while(ByteCount--) { + Checksum += *DataPtr++; + 1b34: 91 91 ld r25, Z+ + 1b36: 89 0f add r24, r25 + +static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { + uint8_t Checksum = CHECKSUM_INIT_VALUE; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 1b38: 91 e2 ldi r25, 0x21 ; 33 + 1b3a: e0 3a cpi r30, 0xA0 ; 160 + 1b3c: f9 07 cpc r31, r25 + 1b3e: d1 f7 brne .-12 ; 0x1b34 + Checksum += *DataPtr++; + } + + return Checksum; +} + 1b40: 08 95 ret + +00001b42 : + +void XModemReceive(XModemCallbackType TheCallbackFunc) +{ + State = STATE_RECEIVE_INIT; + 1b42: 21 e0 ldi r18, 0x01 ; 1 + 1b44: 20 93 a5 20 sts 0x20A5, r18 + CurrentFrameNumber = FIRST_FRAME_NUMBER; + 1b48: 20 93 a6 20 sts 0x20A6, r18 + RetryCount = RECV_INIT_COUNT; + 1b4c: 24 e1 ldi r18, 0x14 ; 20 + 1b4e: 20 93 a7 20 sts 0x20A7, r18 + RetryTimeout = RECV_INIT_TIMEOUT; + 1b52: 25 e0 ldi r18, 0x05 ; 5 + 1b54: 20 93 a8 20 sts 0x20A8, r18 + BlockAddress = 0; + 1b58: 10 92 a9 20 sts 0x20A9, r1 + 1b5c: 10 92 aa 20 sts 0x20AA, r1 + 1b60: 10 92 ab 20 sts 0x20AB, r1 + 1b64: 10 92 ac 20 sts 0x20AC, r1 + + CallbackFunc = TheCallbackFunc; + 1b68: 80 93 ad 20 sts 0x20AD, r24 + 1b6c: 90 93 ae 20 sts 0x20AE, r25 +} + 1b70: 08 95 ret + +00001b72 : + +void XModemSend(XModemCallbackType TheCallbackFunc) +{ + State = STATE_SEND_INIT; + 1b72: 27 e0 ldi r18, 0x07 ; 7 + 1b74: 20 93 a5 20 sts 0x20A5, r18 + RetryTimeout = SEND_INIT_TIMEOUT; + 1b78: 24 e6 ldi r18, 0x64 ; 100 + 1b7a: 20 93 a8 20 sts 0x20A8, r18 + BlockAddress = 0; + 1b7e: 10 92 a9 20 sts 0x20A9, r1 + 1b82: 10 92 aa 20 sts 0x20AA, r1 + 1b86: 10 92 ab 20 sts 0x20AB, r1 + 1b8a: 10 92 ac 20 sts 0x20AC, r1 + + CallbackFunc = TheCallbackFunc; + 1b8e: 80 93 ad 20 sts 0x20AD, r24 + 1b92: 90 93 ae 20 sts 0x20AE, r25 +} + 1b96: 08 95 ret + +00001b98 : + +bool XModemProcessByte(uint8_t Byte) +{ + 1b98: cf 93 push r28 + 1b9a: c8 2f mov r28, r24 + switch(State) { + 1b9c: 80 91 a5 20 lds r24, 0x20A5 + 1ba0: 85 30 cpi r24, 0x05 ; 5 + 1ba2: 09 f4 brne .+2 ; 0x1ba6 + 1ba4: 84 c0 rjmp .+264 ; 0x1cae + 1ba6: 86 30 cpi r24, 0x06 ; 6 + 1ba8: e8 f0 brcs .+58 ; 0x1be4 + 1baa: 87 30 cpi r24, 0x07 ; 7 + 1bac: 09 f4 brne .+2 ; 0x1bb0 + 1bae: 4e c0 rjmp .+156 ; 0x1c4c + 1bb0: 87 30 cpi r24, 0x07 ; 7 + 1bb2: 70 f5 brcc .+92 ; 0x1c10 + } + + break; + + case STATE_RECEIVE_PROCESS: + if (ReceivedFrameNumber == CurrentFrameNumber) { + 1bb4: 20 91 b2 20 lds r18, 0x20B2 + 1bb8: 80 91 a6 20 lds r24, 0x20A6 + 1bbc: 28 17 cp r18, r24 + 1bbe: 09 f4 brne .+2 ; 0x1bc2 + 1bc0: e1 c0 rjmp .+450 ; 0x1d84 + } else { + /* Data seems to be damaged */ + TerminalSendByte(BYTE_NAK); + State = STATE_RECEIVE_WAIT; + } + } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { + 1bc2: 30 e0 ldi r19, 0x00 ; 0 + 1bc4: 90 e0 ldi r25, 0x00 ; 0 + 1bc6: 01 97 sbiw r24, 0x01 ; 1 + 1bc8: 28 17 cp r18, r24 + 1bca: 39 07 cpc r19, r25 + 1bcc: 09 f4 brne .+2 ; 0x1bd0 + 1bce: 0b c1 rjmp .+534 ; 0x1de6 +INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } + 1bd0: 80 e0 ldi r24, 0x00 ; 0 + 1bd2: 90 e2 ldi r25, 0x20 ; 32 + 1bd4: 68 e1 ldi r22, 0x18 ; 24 + 1bd6: 0e 94 71 24 call 0x48e2 ; 0x48e2 + TerminalSendByte(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + } else { + /* This frame is completely out of order. Just cancel */ + TerminalSendByte(BYTE_CAN); + State = STATE_OFF; + 1bda: 10 92 a5 20 sts 0x20A5, r1 + default: + return false; + break; + } + + return true; + 1bde: 81 e0 ldi r24, 0x01 ; 1 +} + 1be0: cf 91 pop r28 + 1be2: 08 95 ret + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 1be4: 83 30 cpi r24, 0x03 ; 3 + 1be6: 09 f4 brne .+2 ; 0x1bea + 1be8: 5a c0 rjmp .+180 ; 0x1c9e + 1bea: 84 30 cpi r24, 0x04 ; 4 + 1bec: c0 f0 brcs .+48 ; 0x1c1e + ReceivedFrameNumber = Byte; + State = STATE_RECEIVE_FRAMENUM2; + break; + + case STATE_RECEIVE_FRAMENUM2: + if (Byte == (255 - ReceivedFrameNumber)) { + 1bee: 8c 2f mov r24, r28 + 1bf0: 90 e0 ldi r25, 0x00 ; 0 + 1bf2: 40 91 b2 20 lds r20, 0x20B2 + 1bf6: 2f ef ldi r18, 0xFF ; 255 + 1bf8: 30 e0 ldi r19, 0x00 ; 0 + 1bfa: 24 1b sub r18, r20 + 1bfc: 31 09 sbc r19, r1 + 1bfe: 82 17 cp r24, r18 + 1c00: 93 07 cpc r25, r19 + 1c02: 09 f0 breq .+2 ; 0x1c06 + 1c04: 6b c0 rjmp .+214 ; 0x1cdc + /* frame-number check passed. */ + State = STATE_RECEIVE_DATA; + 1c06: 85 e0 ldi r24, 0x05 ; 5 + 1c08: 80 93 a5 20 sts 0x20A5, r24 + default: + return false; + break; + } + + return true; + 1c0c: 81 e0 ldi r24, 0x01 ; 1 + 1c0e: e8 cf rjmp .-48 ; 0x1be0 + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 1c10: 88 30 cpi r24, 0x08 ; 8 + 1c12: f9 f0 breq .+62 ; 0x1c52 + 1c14: 89 30 cpi r24, 0x09 ; 9 + 1c16: a9 f0 breq .+42 ; 0x1c42 + /* Receive Ack */ + State = STATE_OFF; + break; + + default: + return false; + 1c18: 80 e0 ldi r24, 0x00 ; 0 + break; + } + + return true; +} + 1c1a: cf 91 pop r28 + 1c1c: 08 95 ret + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + 1c1e: 81 30 cpi r24, 0x01 ; 1 + 1c20: d8 f3 brcs .-10 ; 0x1c18 + case STATE_RECEIVE_INIT: + case STATE_RECEIVE_WAIT: + if (Byte == BYTE_SOH) { + 1c22: c1 30 cpi r28, 0x01 ; 1 + 1c24: 09 f4 brne .+2 ; 0x1c28 + 1c26: e9 c0 rjmp .+466 ; 0x1dfa + /* Next frame incoming */ + BufferIdx = 0; + Checksum = CHECKSUM_INIT_VALUE; + State = STATE_RECEIVE_FRAMENUM1; + } else if (Byte == BYTE_EOT) { + 1c28: c4 30 cpi r28, 0x04 ; 4 + 1c2a: 09 f4 brne .+2 ; 0x1c2e + 1c2c: fb c0 rjmp .+502 ; 0x1e24 + /* Transmission finished */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_CAN) { + 1c2e: c8 31 cpi r28, 0x18 ; 24 + 1c30: 41 f0 breq .+16 ; 0x1c42 + default: + return false; + break; + } + + return true; + 1c32: 81 e0 ldi r24, 0x01 ; 1 +} + 1c34: cf 91 pop r28 + 1c36: 08 95 ret + 1c38: 80 e0 ldi r24, 0x00 ; 0 + 1c3a: 90 e2 ldi r25, 0x20 ; 32 + 1c3c: 66 e0 ldi r22, 0x06 ; 6 + 1c3e: 0e 94 71 24 call 0x48e2 ; 0x48e2 + + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + 1c42: 10 92 a5 20 sts 0x20A5, r1 + default: + return false; + break; + } + + return true; + 1c46: 81 e0 ldi r24, 0x01 ; 1 +} + 1c48: cf 91 pop r28 + 1c4a: 08 95 ret + + break; + + case STATE_SEND_INIT: + /* Start sending on NAK */ + if (Byte == BYTE_NAK) { + 1c4c: c5 31 cpi r28, 0x15 ; 21 + 1c4e: 09 f4 brne .+2 ; 0x1c52 + 1c50: 4f c0 rjmp .+158 ; 0x1cf0 + } + + /* Fallthrough */ + + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + 1c52: c8 31 cpi r28, 0x18 ; 24 + 1c54: 89 f3 breq .-30 ; 0x1c38 + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + 1c56: c6 30 cpi r28, 0x06 ; 6 + 1c58: 09 f4 brne .+2 ; 0x1c5c + 1c5a: f3 c0 rjmp .+486 ; 0x1e42 + BlockAddress += XMODEM_BLOCK_SIZE; + } else { + TerminalSendByte(BYTE_EOT); + State = STATE_SEND_EOT; + } + } else if (Byte == BYTE_NAK){ + 1c5c: c5 31 cpi r28, 0x15 ; 21 + 1c5e: 49 f7 brne .-46 ; 0x1c32 + 1c60: 80 e0 ldi r24, 0x00 ; 0 + 1c62: 90 e2 ldi r25, 0x20 ; 32 + 1c64: 61 e0 ldi r22, 0x01 ; 1 + 1c66: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1c6a: 80 e0 ldi r24, 0x00 ; 0 + 1c6c: 90 e2 ldi r25, 0x20 ; 32 + 1c6e: 60 91 a6 20 lds r22, 0x20A6 + 1c72: 0e 94 71 24 call 0x48e2 ; 0x48e2 + /* Resend frame */ + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + 1c76: 60 91 a6 20 lds r22, 0x20A6 + 1c7a: 60 95 com r22 + 1c7c: 80 e0 ldi r24, 0x00 ; 0 + 1c7e: 90 e2 ldi r25, 0x20 ; 32 + 1c80: 0e 94 71 24 call 0x48e2 ; 0x48e2 + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + 1c84: 80 e2 ldi r24, 0x20 ; 32 + 1c86: 91 e2 ldi r25, 0x21 ; 33 + 1c88: 60 e8 ldi r22, 0x80 ; 128 + 1c8a: 70 e0 ldi r23, 0x00 ; 0 + 1c8c: af dc rcall .-1698 ; 0x15ec + 1c8e: 4f df rcall .-354 ; 0x1b2e + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + 1c90: 68 2f mov r22, r24 + 1c92: 80 e0 ldi r24, 0x00 ; 0 + 1c94: 90 e2 ldi r25, 0x20 ; 32 + 1c96: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1c9a: 81 e0 ldi r24, 0x01 ; 1 + 1c9c: a1 cf rjmp .-190 ; 0x1be0 + default: + return false; + break; + } + + return true; + 1c9e: c0 93 b2 20 sts 0x20B2, r28 + + break; + + case STATE_RECEIVE_FRAMENUM1: + /* Store frame number */ + ReceivedFrameNumber = Byte; + 1ca2: 84 e0 ldi r24, 0x04 ; 4 + 1ca4: 80 93 a5 20 sts 0x20A5, r24 + State = STATE_RECEIVE_FRAMENUM2; + 1ca8: 81 e0 ldi r24, 0x01 ; 1 + 1caa: cf 91 pop r28 + default: + return false; + break; + } + + return true; + 1cac: 08 95 ret +} + 1cae: 20 91 af 20 lds r18, 0x20AF + + break; + + case STATE_RECEIVE_DATA: + /* Process byte and update checksum */ + TerminalBuffer[BufferIdx++] = Byte; + 1cb2: 30 91 b0 20 lds r19, 0x20B0 + 1cb6: f9 01 movw r30, r18 + 1cb8: e0 5e subi r30, 0xE0 ; 224 + 1cba: fe 4d sbci r31, 0xDE ; 222 + 1cbc: c0 83 st Z, r28 + 1cbe: c9 01 movw r24, r18 + 1cc0: 01 96 adiw r24, 0x01 ; 1 + 1cc2: 80 93 af 20 sts 0x20AF, r24 + 1cc6: 90 93 b0 20 sts 0x20B0, r25 + 1cca: 80 38 cpi r24, 0x80 ; 128 + 1ccc: 91 05 cpc r25, r1 + + if (BufferIdx == XMODEM_BLOCK_SIZE) { + 1cce: 09 f0 breq .+2 ; 0x1cd2 + 1cd0: b0 cf rjmp .-160 ; 0x1c32 + 1cd2: 86 e0 ldi r24, 0x06 ; 6 + 1cd4: 80 93 a5 20 sts 0x20A5, r24 + /* Block full */ + State = STATE_RECEIVE_PROCESS; + 1cd8: 81 e0 ldi r24, 0x01 ; 1 + 1cda: 82 cf rjmp .-252 ; 0x1be0 + default: + return false; + break; + } + + return true; + 1cdc: 80 e0 ldi r24, 0x00 ; 0 + 1cde: 90 e2 ldi r25, 0x20 ; 32 + 1ce0: 65 e1 ldi r22, 0x15 ; 21 + 1ce2: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1ce6: 82 e0 ldi r24, 0x02 ; 2 + 1ce8: 80 93 a5 20 sts 0x20A5, r24 + State = STATE_OFF; + } + } else { + /* Data seems to be damaged */ + TerminalSendByte(BYTE_NAK); + State = STATE_RECEIVE_WAIT; + 1cec: 81 e0 ldi r24, 0x01 ; 1 + 1cee: 78 cf rjmp .-272 ; 0x1be0 + default: + return false; + break; + } + + return true; + 1cf0: 81 e0 ldi r24, 0x01 ; 1 + 1cf2: 80 93 a6 20 sts 0x20A6, r24 + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + /* Acknowledge. Proceed to next frame, get data and calc checksum */ + CurrentFrameNumber++; + 1cf6: 40 91 a9 20 lds r20, 0x20A9 + + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + 1cfa: 50 91 aa 20 lds r21, 0x20AA + 1cfe: 60 91 ab 20 lds r22, 0x20AB + 1d02: 70 91 ac 20 lds r23, 0x20AC + 1d06: e0 91 ad 20 lds r30, 0x20AD + 1d0a: f0 91 ae 20 lds r31, 0x20AE + 1d0e: 80 e2 ldi r24, 0x20 ; 32 + 1d10: 91 e2 ldi r25, 0x21 ; 33 + 1d12: 20 e8 ldi r18, 0x80 ; 128 + 1d14: 30 e0 ldi r19, 0x00 ; 0 + 1d16: 09 95 icall + 1d18: 88 23 and r24, r24 + 1d1a: 09 f4 brne .+2 ; 0x1d1e + 1d1c: 79 c0 rjmp .+242 ; 0x1e10 + 1d1e: 80 e0 ldi r24, 0x00 ; 0 + 1d20: 90 e2 ldi r25, 0x20 ; 32 + 1d22: 61 e0 ldi r22, 0x01 ; 1 + 1d24: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1d28: 80 e0 ldi r24, 0x00 ; 0 + 1d2a: 90 e2 ldi r25, 0x20 ; 32 + 1d2c: 60 91 a6 20 lds r22, 0x20A6 + 1d30: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1d34: 60 91 a6 20 lds r22, 0x20A6 + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + 1d38: 60 95 com r22 + 1d3a: 80 e0 ldi r24, 0x00 ; 0 + 1d3c: 90 e2 ldi r25, 0x20 ; 32 + 1d3e: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1d42: 80 e2 ldi r24, 0x20 ; 32 + 1d44: 91 e2 ldi r25, 0x21 ; 33 + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + 1d46: 60 e8 ldi r22, 0x80 ; 128 + 1d48: 70 e0 ldi r23, 0x00 ; 0 + 1d4a: 50 dc rcall .-1888 ; 0x15ec + 1d4c: f0 de rcall .-544 ; 0x1b2e + 1d4e: 68 2f mov r22, r24 + 1d50: 80 e0 ldi r24, 0x00 ; 0 + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + 1d52: 90 e2 ldi r25, 0x20 ; 32 + 1d54: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1d58: 80 91 a9 20 lds r24, 0x20A9 + 1d5c: 90 91 aa 20 lds r25, 0x20AA + + BlockAddress += XMODEM_BLOCK_SIZE; + 1d60: a0 91 ab 20 lds r26, 0x20AB + 1d64: b0 91 ac 20 lds r27, 0x20AC + 1d68: 80 58 subi r24, 0x80 ; 128 + 1d6a: 9f 4f sbci r25, 0xFF ; 255 + 1d6c: af 4f sbci r26, 0xFF ; 255 + 1d6e: bf 4f sbci r27, 0xFF ; 255 + 1d70: 80 93 a9 20 sts 0x20A9, r24 + 1d74: 90 93 aa 20 sts 0x20AA, r25 + 1d78: a0 93 ab 20 sts 0x20AB, r26 + 1d7c: b0 93 ac 20 sts 0x20AC, r27 + 1d80: 81 e0 ldi r24, 0x01 ; 1 + 1d82: 2e cf rjmp .-420 ; 0x1be0 + 1d84: d4 de rcall .-600 ; 0x1b2e + 1d86: 8c 17 cp r24, r28 + default: + return false; + break; + } + + return true; + 1d88: 09 f0 breq .+2 ; 0x1d8c + 1d8a: a8 cf rjmp .-176 ; 0x1cdc + + case STATE_RECEIVE_PROCESS: + if (ReceivedFrameNumber == CurrentFrameNumber) { + /* This is the expected frame. Calculate and verify checksum */ + + if (CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE) == Byte) { + 1d8c: 40 91 a9 20 lds r20, 0x20A9 + 1d90: 50 91 aa 20 lds r21, 0x20AA + 1d94: 60 91 ab 20 lds r22, 0x20AB + /* Checksum is valid. Pass received data to callback function */ + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + 1d98: 70 91 ac 20 lds r23, 0x20AC + 1d9c: e0 91 ad 20 lds r30, 0x20AD + 1da0: f0 91 ae 20 lds r31, 0x20AE + 1da4: 80 e2 ldi r24, 0x20 ; 32 + 1da6: 91 e2 ldi r25, 0x21 ; 33 + 1da8: 20 e8 ldi r18, 0x80 ; 128 + 1daa: 30 e0 ldi r19, 0x00 ; 0 + 1dac: 09 95 icall + 1dae: 88 23 and r24, r24 + 1db0: 09 f4 brne .+2 ; 0x1db4 + 1db2: 41 c0 rjmp .+130 ; 0x1e36 + 1db4: 80 91 a6 20 lds r24, 0x20A6 + 1db8: 8f 5f subi r24, 0xFF ; 255 + 1dba: 80 93 a6 20 sts 0x20A6, r24 + /* Proceed to next frame and send ACK */ + CurrentFrameNumber++; + 1dbe: 80 91 a9 20 lds r24, 0x20A9 + 1dc2: 90 91 aa 20 lds r25, 0x20AA + 1dc6: a0 91 ab 20 lds r26, 0x20AB + BlockAddress += XMODEM_BLOCK_SIZE; + 1dca: b0 91 ac 20 lds r27, 0x20AC + 1dce: 80 58 subi r24, 0x80 ; 128 + 1dd0: 9f 4f sbci r25, 0xFF ; 255 + 1dd2: af 4f sbci r26, 0xFF ; 255 + 1dd4: bf 4f sbci r27, 0xFF ; 255 + 1dd6: 80 93 a9 20 sts 0x20A9, r24 + 1dda: 90 93 aa 20 sts 0x20AA, r25 + 1dde: a0 93 ab 20 sts 0x20AB, r26 + 1de2: b0 93 ac 20 sts 0x20AC, r27 + 1de6: 80 e0 ldi r24, 0x00 ; 0 + 1de8: 90 e2 ldi r25, 0x20 ; 32 + 1dea: 66 e0 ldi r22, 0x06 ; 6 + 1dec: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1df0: 82 e0 ldi r24, 0x02 ; 2 + 1df2: 80 93 a5 20 sts 0x20A5, r24 + 1df6: 81 e0 ldi r24, 0x01 ; 1 + 1df8: f3 ce rjmp .-538 ; 0x1be0 + State = STATE_RECEIVE_WAIT; + } + } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { + /* This is a retransmission */ + TerminalSendByte(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + 1dfa: 10 92 af 20 sts 0x20AF, r1 + 1dfe: 10 92 b0 20 sts 0x20B0, r1 + default: + return false; + break; + } + + return true; + 1e02: 10 92 b1 20 sts 0x20B1, r1 + switch(State) { + case STATE_RECEIVE_INIT: + case STATE_RECEIVE_WAIT: + if (Byte == BYTE_SOH) { + /* Next frame incoming */ + BufferIdx = 0; + 1e06: 83 e0 ldi r24, 0x03 ; 3 + 1e08: 80 93 a5 20 sts 0x20A5, r24 + Checksum = CHECKSUM_INIT_VALUE; + 1e0c: 81 e0 ldi r24, 0x01 ; 1 + 1e0e: e8 ce rjmp .-560 ; 0x1be0 + State = STATE_RECEIVE_FRAMENUM1; + 1e10: 80 e0 ldi r24, 0x00 ; 0 + 1e12: 90 e2 ldi r25, 0x20 ; 32 + 1e14: 64 e0 ldi r22, 0x04 ; 4 + default: + return false; + break; + } + + return true; + 1e16: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1e1a: 89 e0 ldi r24, 0x09 ; 9 + 1e1c: 80 93 a5 20 sts 0x20A5, r24 + 1e20: 81 e0 ldi r24, 0x01 ; 1 + 1e22: de ce rjmp .-580 ; 0x1be0 + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + + BlockAddress += XMODEM_BLOCK_SIZE; + } else { + TerminalSendByte(BYTE_EOT); + State = STATE_SEND_EOT; + 1e24: 80 e0 ldi r24, 0x00 ; 0 + 1e26: 90 e2 ldi r25, 0x20 ; 32 + 1e28: 66 e0 ldi r22, 0x06 ; 6 + default: + return false; + break; + } + + return true; + 1e2a: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1e2e: 10 92 a5 20 sts 0x20A5, r1 + 1e32: 81 e0 ldi r24, 0x01 ; 1 + 1e34: d5 ce rjmp .-598 ; 0x1be0 + 1e36: 80 e0 ldi r24, 0x00 ; 0 + Checksum = CHECKSUM_INIT_VALUE; + State = STATE_RECEIVE_FRAMENUM1; + } else if (Byte == BYTE_EOT) { + /* Transmission finished */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + 1e38: 90 e2 ldi r25, 0x20 ; 32 + 1e3a: 68 e1 ldi r22, 0x18 ; 24 + default: + return false; + break; + } + + return true; + 1e3c: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1e40: c7 ce rjmp .-626 ; 0x1bd0 + 1e42: 80 91 a6 20 lds r24, 0x20A6 + 1e46: 8f 5f subi r24, 0xFF ; 255 + 1e48: 54 cf rjmp .-344 ; 0x1cf2 + +00001e4a : + 1e4a: 80 91 a5 20 lds r24, 0x20A5 + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + 1e4e: 81 30 cpi r24, 0x01 ; 1 + 1e50: 71 f0 breq .+28 ; 0x1e6e + 1e52: 87 30 cpi r24, 0x07 ; 7 +} + +void XModemTick(void) +{ + /* Timeouts go here */ + switch(State) { + 1e54: 09 f0 breq .+2 ; 0x1e58 + 1e56: 08 95 ret + RetryTimeout = RECV_INIT_TIMEOUT; + } + break; + + case STATE_SEND_INIT: + if (RetryTimeout-- == 0) { + 1e58: 80 91 a8 20 lds r24, 0x20A8 + 1e5c: 98 2f mov r25, r24 + 1e5e: 91 50 subi r25, 0x01 ; 1 + 1e60: 90 93 a8 20 sts 0x20A8, r25 + 1e64: 88 23 and r24, r24 + 1e66: b9 f7 brne .-18 ; 0x1e56 + /* Abort */ + State = STATE_OFF; + 1e68: 10 92 a5 20 sts 0x20A5, r1 + 1e6c: 08 95 ret +void XModemTick(void) +{ + /* Timeouts go here */ + switch(State) { + case STATE_RECEIVE_INIT: + if (RetryTimeout-- == 0) { + 1e6e: 80 91 a8 20 lds r24, 0x20A8 + 1e72: 98 2f mov r25, r24 + 1e74: 91 50 subi r25, 0x01 ; 1 + 1e76: 90 93 a8 20 sts 0x20A8, r25 + 1e7a: 88 23 and r24, r24 + 1e7c: 61 f7 brne .-40 ; 0x1e56 + if (RetryCount-- > 0) { + 1e7e: 80 91 a7 20 lds r24, 0x20A7 + 1e82: 98 2f mov r25, r24 + 1e84: 91 50 subi r25, 0x01 ; 1 + 1e86: 90 93 a7 20 sts 0x20A7, r25 + 1e8a: 88 23 and r24, r24 + 1e8c: 31 f4 brne .+12 ; 0x1e9a + /* Put out communication request */ + TerminalSendChar(BYTE_NAK); + } else { + /* Just shut off after some time. */ + State = STATE_OFF; + 1e8e: 10 92 a5 20 sts 0x20A5, r1 + } + + RetryTimeout = RECV_INIT_TIMEOUT; + 1e92: 85 e0 ldi r24, 0x05 ; 5 + 1e94: 80 93 a8 20 sts 0x20A8, r24 + 1e98: 08 95 ret +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } + 1e9a: 80 e0 ldi r24, 0x00 ; 0 + 1e9c: 90 e2 ldi r25, 0x20 ; 32 + 1e9e: 65 e1 ldi r22, 0x15 ; 21 + 1ea0: 0e 94 71 24 call 0x48e2 ; 0x48e2 + 1ea4: f6 cf rjmp .-20 ; 0x1e92 + +00001ea6 : +void CommandLineInit(void) +{ + BufferIdx = 0; +} + +bool CommandLineProcessByte(uint8_t Byte) { + 1ea6: 1f 93 push r17 + 1ea8: cf 93 push r28 + 1eaa: df 93 push r29 + if (IS_CHARACTER(Byte)){ + 1eac: 98 2f mov r25, r24 + 1eae: 91 54 subi r25, 0x41 ; 65 + 1eb0: 9a 31 cpi r25, 0x1A ; 26 + 1eb2: 20 f0 brcs .+8 ; 0x1ebc + 1eb4: 90 52 subi r25, 0x20 ; 32 + 1eb6: 9a 31 cpi r25, 0x1A ; 26 + 1eb8: b8 f4 brcc .+46 ; 0x1ee8 + /* Store uppercase character */ + if (IS_LOWERCASE(Byte)) { + Byte = TO_UPPERCASE(Byte); + 1eba: 80 52 subi r24, 0x20 ; 32 + } + + /* Prevent buffer overflow and account for '\0' */ + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + 1ebc: 20 91 b3 20 lds r18, 0x20B3 + 1ec0: 30 91 b4 20 lds r19, 0x20B4 + 1ec4: 2f 3f cpi r18, 0xFF ; 255 + 1ec6: 31 05 cpc r19, r1 + 1ec8: 50 f4 brcc .+20 ; 0x1ede + TerminalBuffer[BufferIdx++] = Byte; + 1eca: f9 01 movw r30, r18 + 1ecc: e0 5e subi r30, 0xE0 ; 224 + 1ece: fe 4d sbci r31, 0xDE ; 222 + 1ed0: 80 83 st Z, r24 + 1ed2: 2f 5f subi r18, 0xFF ; 255 + 1ed4: 3f 4f sbci r19, 0xFF ; 255 + 1ed6: 20 93 b3 20 sts 0x20B3, r18 + 1eda: 30 93 b4 20 sts 0x20B4, r19 + } else { + /* Ignore other chars */ + } + + return true; +} + 1ede: 81 e0 ldi r24, 0x01 ; 1 + 1ee0: df 91 pop r29 + 1ee2: cf 91 pop r28 + 1ee4: 1f 91 pop r17 + 1ee6: 08 95 ret +{ + BufferIdx = 0; +} + +bool CommandLineProcessByte(uint8_t Byte) { + if (IS_CHARACTER(Byte)){ + 1ee8: 9f 5c subi r25, 0xCF ; 207 + 1eea: 9a 30 cpi r25, 0x0A ; 10 + 1eec: 38 f3 brcs .-50 ; 0x1ebc + 1eee: 8f 35 cpi r24, 0x5F ; 95 + 1ef0: 29 f3 breq .-54 ; 0x1ebc + 1ef2: 8f 33 cpi r24, 0x3F ; 63 + 1ef4: 19 f3 breq .-58 ; 0x1ebc + 1ef6: 8d 33 cpi r24, 0x3D ; 61 + 1ef8: 09 f3 breq .-62 ; 0x1ebc + + /* Prevent buffer overflow and account for '\0' */ + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + TerminalBuffer[BufferIdx++] = Byte; + } + }else if (Byte == '\r') { + 1efa: 8d 30 cpi r24, 0x0D ; 13 + 1efc: a9 f0 breq .+42 ; 0x1f28 + /* Process on \r. Terminate string and decode. */ + TerminalBuffer[BufferIdx] = '\0'; + BufferIdx = 0; + + DecodeCommand(); + }else if (Byte == '\b') { + 1efe: 88 30 cpi r24, 0x08 ; 8 + 1f00: 39 f0 breq .+14 ; 0x1f10 + /* Backspace. Delete last character in buffer. */ + if (BufferIdx > 0) { + BufferIdx--; + } + } else if (Byte == 0x1B){ + 1f02: 8b 31 cpi r24, 0x1B ; 27 + 1f04: 61 f7 brne .-40 ; 0x1ede + /* Drop buffer on escape */ + BufferIdx = 0; + 1f06: 10 92 b3 20 sts 0x20B3, r1 + 1f0a: 10 92 b4 20 sts 0x20B4, r1 + 1f0e: e7 cf rjmp .-50 ; 0x1ede + BufferIdx = 0; + + DecodeCommand(); + }else if (Byte == '\b') { + /* Backspace. Delete last character in buffer. */ + if (BufferIdx > 0) { + 1f10: 80 91 b3 20 lds r24, 0x20B3 + 1f14: 90 91 b4 20 lds r25, 0x20B4 + 1f18: 00 97 sbiw r24, 0x00 ; 0 + 1f1a: 09 f3 breq .-62 ; 0x1ede + BufferIdx--; + 1f1c: 01 97 sbiw r24, 0x01 ; 1 + 1f1e: 80 93 b3 20 sts 0x20B3, r24 + 1f22: 90 93 b4 20 sts 0x20B4, r25 + 1f26: db cf rjmp .-74 ; 0x1ede + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + TerminalBuffer[BufferIdx++] = Byte; + } + }else if (Byte == '\r') { + /* Process on \r. Terminate string and decode. */ + TerminalBuffer[BufferIdx] = '\0'; + 1f28: e0 91 b3 20 lds r30, 0x20B3 + 1f2c: f0 91 b4 20 lds r31, 0x20B4 + 1f30: e0 5e subi r30, 0xE0 ; 224 + 1f32: fe 4d sbci r31, 0xDE ; 222 + 1f34: 10 82 st Z, r1 + BufferIdx = 0; + 1f36: 10 92 b3 20 sts 0x20B3, r1 + 1f3a: 10 92 b4 20 sts 0x20B4, r1 + bool CommandFound = false; + CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Do some sanity check first */ + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + 1f3e: 80 91 20 21 lds r24, 0x2120 + 1f42: 88 23 and r24, r24 + 1f44: 09 f4 brne .+2 ; 0x1f48 + 1f46: a7 c0 rjmp .+334 ; 0x2096 + 1f48: 8f 33 cpi r24, 0x3F ; 63 + 1f4a: 09 f4 brne .+2 ; 0x1f4e + 1f4c: a4 c0 rjmp .+328 ; 0x2096 + 1f4e: 8d 33 cpi r24, 0x3D ; 61 + 1f50: 09 f4 brne .+2 ; 0x1f54 + 1f52: a1 c0 rjmp .+322 ; 0x2096 + 1f54: e1 e2 ldi r30, 0x21 ; 33 + 1f56: f1 e2 ldi r31, 0x21 ; 33 + 1f58: ef 01 movw r28, r30 + 1f5a: 21 97 sbiw r28, 0x01 ; 1 + 1f5c: 06 c0 rjmp .+12 ; 0x1f6a + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + 1f5e: 8f 33 cpi r24, 0x3F ; 63 + 1f60: 09 f4 brne .+2 ; 0x1f64 + 1f62: d3 c0 rjmp .+422 ; 0x210a + 1f64: 8d 33 cpi r24, 0x3D ; 61 + 1f66: 09 f4 brne .+2 ; 0x1f6a + 1f68: ce c0 rjmp .+412 ; 0x2106 + pCommandDelimiter++; + 1f6a: 21 96 adiw r28, 0x01 ; 1 + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + 1f6c: 81 91 ld r24, Z+ + 1f6e: 88 23 and r24, r24 + 1f70: b1 f7 brne .-20 ; 0x1f5e + 1f72: 10 e0 ldi r17, 0x00 ; 0 + pCommandDelimiter++; + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + 1f74: 18 82 st Y, r1 + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + 1f76: 80 e2 ldi r24, 0x20 ; 32 + 1f78: 91 e2 ldi r25, 0x21 ; 33 + 1f7a: 6b e1 ldi r22, 0x1B ; 27 + 1f7c: 74 e0 ldi r23, 0x04 ; 4 + 1f7e: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1f82: 00 97 sbiw r24, 0x00 ; 0 + 1f84: 09 f4 brne .+2 ; 0x1f88 + 1f86: 20 c1 rjmp .+576 ; 0x21c8 + 1f88: 80 e2 ldi r24, 0x20 ; 32 + 1f8a: 91 e2 ldi r25, 0x21 ; 33 + 1f8c: 61 e3 ldi r22, 0x31 ; 49 + 1f8e: 74 e0 ldi r23, 0x04 ; 4 + 1f90: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1f94: 00 97 sbiw r24, 0x00 ; 0 + 1f96: 09 f4 brne .+2 ; 0x1f9a + 1f98: 15 c1 rjmp .+554 ; 0x21c4 + 1f9a: 80 e2 ldi r24, 0x20 ; 32 + 1f9c: 91 e2 ldi r25, 0x21 ; 33 + 1f9e: 67 e4 ldi r22, 0x47 ; 71 + 1fa0: 74 e0 ldi r23, 0x04 ; 4 + 1fa2: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1fa6: 00 97 sbiw r24, 0x00 ; 0 + 1fa8: 09 f4 brne .+2 ; 0x1fac + 1faa: 06 c1 rjmp .+524 ; 0x21b8 + 1fac: 80 e2 ldi r24, 0x20 ; 32 + 1fae: 91 e2 ldi r25, 0x21 ; 33 + 1fb0: 6d e5 ldi r22, 0x5D ; 93 + 1fb2: 74 e0 ldi r23, 0x04 ; 4 + 1fb4: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1fb8: 00 97 sbiw r24, 0x00 ; 0 + 1fba: 09 f4 brne .+2 ; 0x1fbe + 1fbc: fb c0 rjmp .+502 ; 0x21b4 + 1fbe: 80 e2 ldi r24, 0x20 ; 32 + 1fc0: 91 e2 ldi r25, 0x21 ; 33 + 1fc2: 63 e7 ldi r22, 0x73 ; 115 + 1fc4: 74 e0 ldi r23, 0x04 ; 4 + 1fc6: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1fca: 00 97 sbiw r24, 0x00 ; 0 + 1fcc: 09 f4 brne .+2 ; 0x1fd0 + 1fce: f0 c0 rjmp .+480 ; 0x21b0 + 1fd0: 80 e2 ldi r24, 0x20 ; 32 + 1fd2: 91 e2 ldi r25, 0x21 ; 33 + 1fd4: 69 e8 ldi r22, 0x89 ; 137 + 1fd6: 74 e0 ldi r23, 0x04 ; 4 + 1fd8: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1fdc: 00 97 sbiw r24, 0x00 ; 0 + 1fde: 09 f4 brne .+2 ; 0x1fe2 + 1fe0: b5 c0 rjmp .+362 ; 0x214c + 1fe2: 80 e2 ldi r24, 0x20 ; 32 + 1fe4: 91 e2 ldi r25, 0x21 ; 33 + 1fe6: 6f e9 ldi r22, 0x9F ; 159 + 1fe8: 74 e0 ldi r23, 0x04 ; 4 + 1fea: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 1fee: 00 97 sbiw r24, 0x00 ; 0 + 1ff0: 09 f4 brne .+2 ; 0x1ff4 + 1ff2: fa c0 rjmp .+500 ; 0x21e8 + 1ff4: 80 e2 ldi r24, 0x20 ; 32 + 1ff6: 91 e2 ldi r25, 0x21 ; 33 + 1ff8: 65 eb ldi r22, 0xB5 ; 181 + 1ffa: 74 e0 ldi r23, 0x04 ; 4 + 1ffc: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2000: 00 97 sbiw r24, 0x00 ; 0 + 2002: 09 f4 brne .+2 ; 0x2006 + 2004: ef c0 rjmp .+478 ; 0x21e4 + 2006: 80 e2 ldi r24, 0x20 ; 32 + 2008: 91 e2 ldi r25, 0x21 ; 33 + 200a: 6b ec ldi r22, 0xCB ; 203 + 200c: 74 e0 ldi r23, 0x04 ; 4 + 200e: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2012: 00 97 sbiw r24, 0x00 ; 0 + 2014: 09 f4 brne .+2 ; 0x2018 + 2016: e4 c0 rjmp .+456 ; 0x21e0 + 2018: 80 e2 ldi r24, 0x20 ; 32 + 201a: 91 e2 ldi r25, 0x21 ; 33 + 201c: 61 ee ldi r22, 0xE1 ; 225 + 201e: 74 e0 ldi r23, 0x04 ; 4 + 2020: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2024: 00 97 sbiw r24, 0x00 ; 0 + 2026: 09 f4 brne .+2 ; 0x202a + 2028: d9 c0 rjmp .+434 ; 0x21dc + 202a: 80 e2 ldi r24, 0x20 ; 32 + 202c: 91 e2 ldi r25, 0x21 ; 33 + 202e: 67 ef ldi r22, 0xF7 ; 247 + 2030: 74 e0 ldi r23, 0x04 ; 4 + 2032: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2036: 00 97 sbiw r24, 0x00 ; 0 + 2038: 09 f4 brne .+2 ; 0x203c + 203a: ce c0 rjmp .+412 ; 0x21d8 + 203c: 80 e2 ldi r24, 0x20 ; 32 + 203e: 91 e2 ldi r25, 0x21 ; 33 + 2040: 6d e0 ldi r22, 0x0D ; 13 + 2042: 75 e0 ldi r23, 0x05 ; 5 + 2044: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2048: 00 97 sbiw r24, 0x00 ; 0 + 204a: 09 f4 brne .+2 ; 0x204e + 204c: c3 c0 rjmp .+390 ; 0x21d4 + 204e: 80 e2 ldi r24, 0x20 ; 32 + 2050: 91 e2 ldi r25, 0x21 ; 33 + 2052: 63 e2 ldi r22, 0x23 ; 35 + 2054: 75 e0 ldi r23, 0x05 ; 5 + 2056: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 205a: 00 97 sbiw r24, 0x00 ; 0 + 205c: 09 f4 brne .+2 ; 0x2060 + 205e: b8 c0 rjmp .+368 ; 0x21d0 + 2060: 80 e2 ldi r24, 0x20 ; 32 + 2062: 91 e2 ldi r25, 0x21 ; 33 + 2064: 69 e3 ldi r22, 0x39 ; 57 + 2066: 75 e0 ldi r23, 0x05 ; 5 + 2068: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 206c: 00 97 sbiw r24, 0x00 ; 0 + 206e: 09 f4 brne .+2 ; 0x2072 + 2070: ad c0 rjmp .+346 ; 0x21cc + 2072: 80 e2 ldi r24, 0x20 ; 32 + 2074: 91 e2 ldi r25, 0x21 ; 33 + 2076: 6f e4 ldi r22, 0x4F ; 79 + 2078: 75 e0 ldi r23, 0x05 ; 5 + 207a: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 207e: 00 97 sbiw r24, 0x00 ; 0 + 2080: 09 f4 brne .+2 ; 0x2084 + 2082: 9e c0 rjmp .+316 ; 0x21c0 + 2084: 80 e2 ldi r24, 0x20 ; 32 + 2086: 91 e2 ldi r25, 0x21 ; 33 + 2088: 65 e6 ldi r22, 0x65 ; 101 + 208a: 75 e0 ldi r23, 0x05 ; 5 + 208c: 0e 94 eb 25 call 0x4bd6 ; 0x4bd6 + 2090: 00 97 sbiw r24, 0x00 ; 0 + 2092: 09 f4 brne .+2 ; 0x2096 + 2094: 93 c0 rjmp .+294 ; 0x21bc + +static void DecodeCommand(void) +{ + uint8_t i; + bool CommandFound = false; + CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; + 2096: 88 ec ldi r24, 0xC8 ; 200 +} + +static void DecodeCommand(void) +{ + uint8_t i; + bool CommandFound = false; + 2098: c0 e0 ldi r28, 0x00 ; 0 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 209a: e1 e8 ldi r30, 0x81 ; 129 + 209c: f5 e0 ldi r31, 0x05 ; 5 + 209e: 94 91 lpm r25, Z + 20a0: 89 17 cp r24, r25 + 20a2: 09 f4 brne .+2 ; 0x20a6 + 20a4: 50 c0 rjmp .+160 ; 0x2146 + 20a6: b1 96 adiw r30, 0x21 ; 33 + 20a8: e4 91 lpm r30, Z + 20aa: 8e 17 cp r24, r30 + 20ac: 09 f4 brne .+2 ; 0x20b0 + 20ae: 48 c0 rjmp .+144 ; 0x2140 + 20b0: e3 ec ldi r30, 0xC3 ; 195 + 20b2: f5 e0 ldi r31, 0x05 ; 5 + 20b4: e4 91 lpm r30, Z + 20b6: 8e 17 cp r24, r30 + 20b8: 09 f4 brne .+2 ; 0x20bc + 20ba: 3f c0 rjmp .+126 ; 0x213a + 20bc: e4 ee ldi r30, 0xE4 ; 228 + 20be: f5 e0 ldi r31, 0x05 ; 5 + 20c0: e4 91 lpm r30, Z + 20c2: 8e 17 cp r24, r30 + 20c4: 09 f4 brne .+2 ; 0x20c8 + 20c6: 36 c0 rjmp .+108 ; 0x2134 + 20c8: e5 e0 ldi r30, 0x05 ; 5 + 20ca: f6 e0 ldi r31, 0x06 ; 6 + 20cc: e4 91 lpm r30, Z + 20ce: 8e 17 cp r24, r30 + 20d0: 71 f1 breq .+92 ; 0x212e + 20d2: e6 e2 ldi r30, 0x26 ; 38 + 20d4: f6 e0 ldi r31, 0x06 ; 6 + 20d6: e4 91 lpm r30, Z + 20d8: 8e 17 cp r24, r30 + 20da: c9 f0 breq .+50 ; 0x210e + return StatusTable[i].Message; + } + + return (void*) 0; + 20dc: 80 e0 ldi r24, 0x00 ; 0 + 20de: 90 e0 ldi r25, 0x00 ; 0 + } + } + } + + /* Send command status message */ + TerminalSendStringP(GetStatusMessageP(StatusId)); + 20e0: 71 da rcall .-2846 ; 0x15c4 + 20e2: 8b e7 ldi r24, 0x7B ; 123 + TerminalSendStringP(PSTR(STATUS_MESSAGE_TRAILER)); + 20e4: 95 e0 ldi r25, 0x05 ; 5 + 20e6: 6e da rcall .-2852 ; 0x15c4 + 20e8: cc 23 and r28, r28 + 20ea: 09 f4 brne .+2 ; 0x20ee + + if (CommandFound && (pTerminalBuffer[0] != '\0') ) { + 20ec: f8 ce rjmp .-528 ; 0x1ede + 20ee: 80 91 20 21 lds r24, 0x2120 + 20f2: 88 23 and r24, r24 + 20f4: 09 f4 brne .+2 ; 0x20f8 + 20f6: f3 ce rjmp .-538 ; 0x1ede + 20f8: 80 e2 ldi r24, 0x20 ; 32 + 20fa: 91 e2 ldi r25, 0x21 ; 33 + /* Send optional answer */ + TerminalSendString(pTerminalBuffer); + 20fc: 5e da rcall .-2884 ; 0x15ba + 20fe: 8e e7 ldi r24, 0x7E ; 126 + 2100: 95 e0 ldi r25, 0x05 ; 5 + 2102: 60 da rcall .-2880 ; 0x15c4 + TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER)); + 2104: ec ce rjmp .-552 ; 0x1ede + 2106: 1d e3 ldi r17, 0x3D ; 61 + 2108: 35 cf rjmp .-406 ; 0x1f74 + 210a: 1f e3 ldi r17, 0x3F ; 63 + 210c: 33 cf rjmp .-410 ; 0x1f74 + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + 210e: 25 e0 ldi r18, 0x05 ; 5 + 2110: 30 e0 ldi r19, 0x00 ; 0 + 2112: c9 01 movw r24, r18 + 2114: 88 0f add r24, r24 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 2116: 99 1f adc r25, r25 + 2118: 82 95 swap r24 + return StatusTable[i].Message; + 211a: 92 95 swap r25 + 211c: 90 7f andi r25, 0xF0 ; 240 + 211e: 98 27 eor r25, r24 + 2120: 80 7f andi r24, 0xF0 ; 240 + 2122: 98 27 eor r25, r24 + 2124: 82 0f add r24, r18 + 2126: 93 1f adc r25, r19 + 2128: 8e 57 subi r24, 0x7E ; 126 + 212a: 9a 4f sbci r25, 0xFA ; 250 + 212c: d9 cf rjmp .-78 ; 0x20e0 + 212e: 24 e0 ldi r18, 0x04 ; 4 + 2130: 30 e0 ldi r19, 0x00 ; 0 + 2132: ef cf rjmp .-34 ; 0x2112 + 2134: 23 e0 ldi r18, 0x03 ; 3 +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + 2136: 30 e0 ldi r19, 0x00 ; 0 + 2138: ec cf rjmp .-40 ; 0x2112 + 213a: 22 e0 ldi r18, 0x02 ; 2 + 213c: 30 e0 ldi r19, 0x00 ; 0 + 213e: e9 cf rjmp .-46 ; 0x2112 + 2140: 21 e0 ldi r18, 0x01 ; 1 + 2142: 30 e0 ldi r19, 0x00 ; 0 + 2144: e6 cf rjmp .-52 ; 0x2112 + 2146: 20 e0 ldi r18, 0x00 ; 0 + 2148: 30 e0 ldi r19, 0x00 ; 0 + 214a: e3 cf rjmp .-58 ; 0x2112 + 214c: 25 e0 ldi r18, 0x05 ; 5 + 214e: 10 92 20 21 sts 0x2120, r1 + 2152: 30 e0 ldi r19, 0x00 ; 0 + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + 2154: 46 e1 ldi r20, 0x16 ; 22 + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + 2156: 50 e0 ldi r21, 0x00 ; 0 + 2158: 24 9f mul r18, r20 + CommandFound = true; + + StatusId = CallCommandFunc(&CommandTable[i], CommandDelimiter, pParam); + 215a: c0 01 movw r24, r0 + 215c: 25 9f mul r18, r21 + 215e: 90 0d add r25, r0 + 2160: 34 9f mul r19, r20 + 2162: 90 0d add r25, r0 + 2164: 11 24 eor r1, r1 + 2166: 85 5e subi r24, 0xE5 ; 229 + 2168: 9b 4f sbci r25, 0xFB ; 251 + 216a: 1f 33 cpi r17, 0x3F ; 63 + 216c: f9 f0 breq .+62 ; 0x21ac + 216e: 1d 33 cpi r17, 0x3D ; 61 + 2170: 89 f0 breq .+34 ; 0x2194 +static CommandStatusIdType CallCommandFunc( + const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Call appropriate function depending on CommandDelimiter */ + if (CommandDelimiter == CHAR_GET_MODE) { + 2172: 11 23 and r17, r17 + 2174: 19 f0 breq .+6 ; 0x217c + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + if (GetFunc != NO_FUNCTION) { + return GetFunc(pTerminalBuffer); + } + } else if (CommandDelimiter == CHAR_SET_MODE) { + 2176: 89 ec ldi r24, 0xC9 ; 201 + 2178: c1 e0 ldi r28, 0x01 ; 1 + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + if (SetFunc != NO_FUNCTION) { + return SetFunc(pParam); + } + } else if (CommandDelimiter == CHAR_EXEC_MODE){ + 217a: 8f cf rjmp .-226 ; 0x209a + 217c: 40 96 adiw r24, 0x10 ; 16 + } else { + /* This should not happen (TM) */ + } + + /* This delimiter has not been registered with this command */ + return COMMAND_ERR_INVALID_USAGE_ID; + 217e: fc 01 movw r30, r24 + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 2180: 85 91 lpm r24, Z+ + 2182: 94 91 lpm r25, Z + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + if (SetFunc != NO_FUNCTION) { + return SetFunc(pParam); + } + } else if (CommandDelimiter == CHAR_EXEC_MODE){ + CommandExecFuncType ExecFunc = pgm_read_ptr(&CommandEntry->ExecFunc); + 2184: fc 01 movw r30, r24 + 2186: 00 97 sbiw r24, 0x00 ; 0 + 2188: b1 f3 breq .-20 ; 0x2176 + 218a: 80 e2 ldi r24, 0x20 ; 32 + 218c: 91 e2 ldi r25, 0x21 ; 33 + if (ExecFunc != NO_FUNCTION) { + 218e: 09 95 icall + 2190: c1 e0 ldi r28, 0x01 ; 1 + return ExecFunc(pTerminalBuffer); + 2192: 83 cf rjmp .-250 ; 0x209a + 2194: 42 96 adiw r24, 0x12 ; 18 + 2196: fc 01 movw r30, r24 + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 2198: 85 91 lpm r24, Z+ + 219a: 94 91 lpm r25, Z + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + if (GetFunc != NO_FUNCTION) { + return GetFunc(pTerminalBuffer); + } + } else if (CommandDelimiter == CHAR_SET_MODE) { + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + 219c: fc 01 movw r30, r24 + 219e: 00 97 sbiw r24, 0x00 ; 0 + 21a0: 51 f3 breq .-44 ; 0x2176 + 21a2: ce 01 movw r24, r28 + 21a4: 01 96 adiw r24, 0x01 ; 1 + if (SetFunc != NO_FUNCTION) { + 21a6: 09 95 icall + 21a8: c1 e0 ldi r28, 0x01 ; 1 + return SetFunc(pParam); + 21aa: 77 cf rjmp .-274 ; 0x209a + 21ac: 44 96 adiw r24, 0x14 ; 20 + 21ae: e7 cf rjmp .-50 ; 0x217e + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + 21b0: 24 e0 ldi r18, 0x04 ; 4 + 21b2: cd cf rjmp .-102 ; 0x214e + const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Call appropriate function depending on CommandDelimiter */ + if (CommandDelimiter == CHAR_GET_MODE) { + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + 21b4: 23 e0 ldi r18, 0x03 ; 3 + 21b6: cb cf rjmp .-106 ; 0x214e + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + 21b8: 22 e0 ldi r18, 0x02 ; 2 + 21ba: c9 cf rjmp .-110 ; 0x214e + 21bc: 2f e0 ldi r18, 0x0F ; 15 + 21be: c7 cf rjmp .-114 ; 0x214e + 21c0: 2e e0 ldi r18, 0x0E ; 14 + 21c2: c5 cf rjmp .-118 ; 0x214e + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + 21c4: 21 e0 ldi r18, 0x01 ; 1 + 21c6: c3 cf rjmp .-122 ; 0x214e + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + 21c8: 20 e0 ldi r18, 0x00 ; 0 + 21ca: c1 cf rjmp .-126 ; 0x214e + 21cc: 2d e0 ldi r18, 0x0D ; 13 + 21ce: bf cf rjmp .-130 ; 0x214e + 21d0: 2c e0 ldi r18, 0x0C ; 12 + 21d2: bd cf rjmp .-134 ; 0x214e + 21d4: 2b e0 ldi r18, 0x0B ; 11 + 21d6: bb cf rjmp .-138 ; 0x214e + 21d8: 2a e0 ldi r18, 0x0A ; 10 + 21da: b9 cf rjmp .-142 ; 0x214e + 21dc: 29 e0 ldi r18, 0x09 ; 9 + 21de: b7 cf rjmp .-146 ; 0x214e + 21e0: 28 e0 ldi r18, 0x08 ; 8 + 21e2: b5 cf rjmp .-150 ; 0x214e + 21e4: 27 e0 ldi r18, 0x07 ; 7 + 21e6: b3 cf rjmp .-154 ; 0x214e + 21e8: 26 e0 ldi r18, 0x06 ; 6 + 21ea: b1 cf rjmp .-158 ; 0x214e + +000021ec : + 21ec: 08 95 ret + +000021ee : +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); +} + +INLINE void CodecSetDemodPower(bool bOnOff) { + CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; + 21ee: a0 e2 ldi r26, 0x20 ; 32 + 21f0: b6 e0 ldi r27, 0x06 ; 6 + 21f2: 82 e0 ldi r24, 0x02 ; 2 + 21f4: 11 96 adiw r26, 0x01 ; 1 + 21f6: 8c 93 st X, r24 + 21f8: 11 97 sbiw r26, 0x01 ; 1 + + if (bOnOff) { + CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; + 21fa: 15 96 adiw r26, 0x05 ; 5 + 21fc: 8c 93 st X, r24 + 21fe: 15 97 sbiw r26, 0x05 ; 5 +static void StartDemod(void) { + /* Activate Power for demodulator */ + CodecSetDemodPower(true); + + /* Configure sampling-timer free running and sync to first modulation-pause. */ + CODEC_TIMER_SAMPLING.CNT = 0; + 2200: e0 e4 ldi r30, 0x40 ; 64 + 2202: f8 e0 ldi r31, 0x08 ; 8 + 2204: 10 a2 lds r17, 0x90 + 2206: 11 a2 lds r17, 0x91 + CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; + 2208: 8d e2 ldi r24, 0x2D ; 45 + 220a: 91 e0 ldi r25, 0x01 ; 1 + 220c: 86 a3 lds r24, 0x56 + 220e: 97 a3 lds r25, 0x57 + CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */ + 2210: 8f ef ldi r24, 0xFF ; 255 + 2212: 9f ef ldi r25, 0xFF ; 255 + 2214: 80 a7 lds r24, 0x70 + 2216: 91 a7 lds r25, 0x71 + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc; + 2218: 81 e0 ldi r24, 0x01 ; 1 + 221a: 80 83 st Z, r24 + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; + 221c: 98 e8 ldi r25, 0x88 ; 136 + 221e: 93 83 std Z+3, r25 ; 0x03 + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc; + 2220: 93 e0 ldi r25, 0x03 ; 3 + 2222: 97 83 std Z+7, r25 ; 0x07 + + /* Start looking out for modulation pause via interrupt. */ + CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; + 2224: 1a 96 adiw r26, 0x0a ; 10 + 2226: 8c 93 st X, r24 + 2228: 1a 97 sbiw r26, 0x0a ; 10 +} + 222a: 08 95 ret + +0000222c <__vector_34>: + +ISR(CODEC_DEMOD_IN_INT0_VECT) { + 222c: 1f 92 push r1 + 222e: 0f 92 push r0 + 2230: 0f b6 in r0, 0x3f ; 63 + 2232: 0f 92 push r0 + 2234: 11 24 eor r1, r1 + 2236: 8f 93 push r24 + 2238: 9f 93 push r25 + 223a: ef 93 push r30 + 223c: ff 93 push r31 + /* This is the first edge of the first modulation-pause after StartDemod. + * Now we have time to prepare our timers and variables to start + * demodulating beginning from one bit-width after this edge. */ + CodecBufferPtr = CodecBuffer; + 223e: 80 e2 ldi r24, 0x20 ; 32 + 2240: 92 e2 ldi r25, 0x22 ; 34 + 2242: 80 93 c1 20 sts 0x20C1, r24 + 2246: 90 93 c2 20 sts 0x20C2, r25 + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + 224a: 80 ea ldi r24, 0xA0 ; 160 + 224c: 92 e2 ldi r25, 0x22 ; 34 + 224e: 80 93 c3 20 sts 0x20C3, r24 + 2252: 90 93 c4 20 sts 0x20C4, r25 + DataRegister = 0; + 2256: 10 92 ba 20 sts 0x20BA, r1 + SampleRegister = 0; + 225a: 10 92 b9 20 sts 0x20B9, r1 + SamplePosition = 0; + 225e: 10 92 b5 20 sts 0x20B5, r1 + BitCount = 0; + 2262: 10 92 bd 20 sts 0x20BD, r1 + 2266: 10 92 be 20 sts 0x20BE, r1 + IsParityBit = false; + 226a: 10 92 b8 20 sts 0x20B8, r1 + * XYZBUF mechanism of the xmega to automatically double the sampling rate on the + * next overflow. For this we have to temporarily deactivate the automatical alignment + * in order to catch next overflow event for updating the BUF registers. + * We want to sample the demodulated data stream in the first quarter of the half-bit + * where the pulsed miller encoded is located. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; + 226e: e0 e4 ldi r30, 0x40 ; 64 + 2270: f8 e0 ldi r31, 0x08 ; 8 + 2272: 13 82 std Z+3, r1 ; 0x03 + CODEC_TIMER_SAMPLING.PERBUF = SAMPLE_RATE_SYSTEM_CYCLES/2 - 1; /* Half bit width */ + 2274: 86 e9 ldi r24, 0x96 ; 150 + 2276: 90 e0 ldi r25, 0x00 ; 0 + 2278: 86 ab sts 0x56, r24 + 227a: 97 ab sts 0x57, r25 + CODEC_TIMER_SAMPLING.CCABUF = SAMPLE_RATE_SYSTEM_CYCLES/8 - 10 - 1; /* Compensate for DIGFILT and ISR prolog */ + 227c: 8a e1 ldi r24, 0x1A ; 26 + 227e: 90 e0 ldi r25, 0x00 ; 0 + 2280: 80 af sts 0x70, r24 + 2282: 91 af sts 0x71, r25 + /* Setup Frame Delay Timer and wire to EVSYS. Frame delay time is + * measured from last change in RF field, therefore we use + * the event channel 1 (end of modulation pause) as the restart event. + * The preliminary frame delay time chosen here is irrelevant, because + * the correct FDT gets set automatically after demodulation. */ + CODEC_TIMER_LOADMOD.CNT = 0; + 2284: e0 e4 ldi r30, 0x40 ; 64 + 2286: f9 e0 ldi r31, 0x09 ; 9 + 2288: 10 a2 lds r17, 0x90 + 228a: 11 a2 lds r17, 0x91 + CODEC_TIMER_LOADMOD.PER = 0xFFFF; + 228c: 8f ef ldi r24, 0xFF ; 255 + 228e: 9f ef ldi r25, 0xFF ; 255 + 2290: 86 a3 lds r24, 0x56 + 2292: 97 a3 lds r25, 0x57 + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH1_gc; + 2294: 89 e8 ldi r24, 0x89 ; 137 + 2296: 83 83 std Z+3, r24 ; 0x03 + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; + 2298: 8e e0 ldi r24, 0x0E ; 14 + 229a: 80 83 st Z, r24 + + /* Disable this interrupt */ + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + 229c: e0 e2 ldi r30, 0x20 ; 32 + 229e: f6 e0 ldi r31, 0x06 ; 6 + 22a0: 12 86 std Z+10, r1 ; 0x0a +} + 22a2: ff 91 pop r31 + 22a4: ef 91 pop r30 + 22a6: 9f 91 pop r25 + 22a8: 8f 91 pop r24 + 22aa: 0f 90 pop r0 + 22ac: 0f be out 0x3f, r0 ; 63 + 22ae: 0f 90 pop r0 + 22b0: 1f 90 pop r1 + 22b2: 18 95 reti + +000022b4 <__vector_22>: + +ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { + 22b4: 1f 92 push r1 + 22b6: 0f 92 push r0 + 22b8: 0f b6 in r0, 0x3f ; 63 + 22ba: 0f 92 push r0 + 22bc: 11 24 eor r1, r1 + 22be: 2f 93 push r18 + 22c0: 8f 93 push r24 + 22c2: 9f 93 push r25 + 22c4: ef 93 push r30 + 22c6: ff 93 push r31 + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + 22c8: 90 91 28 06 lds r25, 0x0628 + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + 22cc: 80 91 b9 20 lds r24, 0x20B9 + 22d0: 88 0f add r24, r24 + CODEC_DEMOD_IN_PORT.INT0MASK = 0; +} + +ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + 22d2: 95 70 andi r25, 0x05 ; 5 + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); + 22d4: 21 e0 ldi r18, 0x01 ; 1 + 22d6: 09 f0 breq .+2 ; 0x22da <__vector_22+0x26> + 22d8: 20 e0 ldi r18, 0x00 ; 0 + 22da: 82 2b or r24, r18 + SampleRegister = NewSampleRegister; + 22dc: 80 93 b9 20 sts 0x20B9, r24 + + if (SamplePosition) { + 22e0: 90 91 b5 20 lds r25, 0x20B5 + 22e4: 99 23 and r25, r25 + 22e6: a1 f1 breq .+104 ; 0x2350 <__vector_22+0x9c> + /* Analyze the sampling register after 2 samples. */ + if ((NewSampleRegister & 0x07) == 0x07) { + 22e8: 98 2f mov r25, r24 + 22ea: 97 70 andi r25, 0x07 ; 7 + 22ec: 97 30 cpi r25, 0x07 ; 7 + 22ee: 09 f4 brne .+2 ; 0x22f2 <__vector_22+0x3e> + 22f0: 44 c0 rjmp .+136 ; 0x237a <__vector_22+0xc6> + + /* Signal, that we have finished sampling */ + Flags.DemodFinished = 1; + } else { + /* Otherwise, we check the two sample bits from the bit before. */ + uint8_t BitSample = NewSampleRegister & 0xC; + 22f2: 8c 70 andi r24, 0x0C ; 12 + uint8_t Bit = 0; + + if (BitSample != (0x0 << 2)) { + 22f4: 69 f1 breq .+90 ; 0x2350 <__vector_22+0x9c> + /* We have a valid bit. decode and process it. */ + if (BitSample & (0x1 << 2)) { + /* 01 sequence or 11 sequence -> This is a zero bit */ + Bit = 0; + 22f6: 91 e0 ldi r25, 0x01 ; 1 + 22f8: 82 fd sbrc r24, 2 + 22fa: 6e c0 rjmp .+220 ; 0x23d8 <__vector_22+0x124> + } else { + /* 10 sequence -> This is a one bit */ + Bit = 1; + } + + LastBit = Bit; + 22fc: 90 93 b7 20 sts 0x20B7, r25 + + if (!IsParityBit) { + 2300: 80 91 b8 20 lds r24, 0x20B8 + 2304: 88 23 and r24, r24 + 2306: 09 f0 breq .+2 ; 0x230a <__vector_22+0x56> + 2308: 6f c0 rjmp .+222 ; 0x23e8 <__vector_22+0x134> + /* This is a data bit, so shift it into the data register and + * hold a local copy of it. */ + uint8_t NewDataRegister = DataRegister >> 1; + 230a: 80 91 ba 20 lds r24, 0x20BA + 230e: 86 95 lsr r24 + NewDataRegister |= (Bit ? 0x80 : 0x00); + 2310: 99 23 and r25, r25 + 2312: 09 f4 brne .+2 ; 0x2316 <__vector_22+0x62> + 2314: 71 c0 rjmp .+226 ; 0x23f8 <__vector_22+0x144> + 2316: 20 e8 ldi r18, 0x80 ; 128 + 2318: 28 2b or r18, r24 + DataRegister = NewDataRegister; + 231a: 20 93 ba 20 sts 0x20BA, r18 + + /* Update bitcount */ + uint16_t NewBitCount = ++BitCount; + 231e: 80 91 bd 20 lds r24, 0x20BD + 2322: 90 91 be 20 lds r25, 0x20BE + 2326: 01 96 adiw r24, 0x01 ; 1 + 2328: 80 93 bd 20 sts 0x20BD, r24 + 232c: 90 93 be 20 sts 0x20BE, r25 + if ((NewBitCount & 0x07) == 0) { + 2330: 87 70 andi r24, 0x07 ; 7 + 2332: 90 70 andi r25, 0x00 ; 0 + 2334: 00 97 sbiw r24, 0x00 ; 0 + 2336: 61 f4 brne .+24 ; 0x2350 <__vector_22+0x9c> + /* We have reached a byte boundary! Store the data register. */ + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr++ = NewDataRegister; + 2338: e0 91 c1 20 lds r30, 0x20C1 + 233c: f0 91 c2 20 lds r31, 0x20C2 + 2340: 21 93 st Z+, r18 + 2342: e0 93 c1 20 sts 0x20C1, r30 + 2346: f0 93 c2 20 sts 0x20C2, r31 + + /* Store bit for determining FDT at EOC and enable parity + * handling on next bit. */ + IsParityBit = true; + 234a: 81 e0 ldi r24, 0x01 ; 1 + 234c: 80 93 b8 20 sts 0x20B8, r24 + } + } else { + /* On odd sample position just sample. */ + } + + SamplePosition = !SamplePosition; + 2350: 90 91 b5 20 lds r25, 0x20B5 + 2354: 81 e0 ldi r24, 0x01 ; 1 + 2356: 91 11 cpse r25, r1 + 2358: 80 e0 ldi r24, 0x00 ; 0 + 235a: 80 93 b5 20 sts 0x20B5, r24 + + /* Make sure the sampling timer gets automatically aligned to the + * modulation pauses by using the RESTART event. + * This can be understood as a "poor mans PLL" and makes sure that we are + * never too far out the bit-grid while sampling. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; + 235e: 88 e8 ldi r24, 0x88 ; 136 + 2360: e0 e4 ldi r30, 0x40 ; 64 + 2362: f8 e0 ldi r31, 0x08 ; 8 + 2364: 83 83 std Z+3, r24 ; 0x03 +} + 2366: ff 91 pop r31 + 2368: ef 91 pop r30 + 236a: 9f 91 pop r25 + 236c: 8f 91 pop r24 + 236e: 2f 91 pop r18 + 2370: 0f 90 pop r0 + 2372: 0f be out 0x3f, r0 ; 63 + 2374: 0f 90 pop r0 + 2376: 1f 90 pop r1 + 2378: 18 95 reti + + if (SamplePosition) { + /* Analyze the sampling register after 2 samples. */ + if ((NewSampleRegister & 0x07) == 0x07) { + /* No carrier modulation for 3 sample points. EOC! */ + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + 237a: 10 92 40 08 sts 0x0840, r1 + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm; + 237e: 80 e1 ldi r24, 0x10 ; 16 + 2380: e0 e4 ldi r30, 0x40 ; 64 + 2382: f8 e0 ldi r31, 0x08 ; 8 + 2384: 84 87 std Z+12, r24 ; 0x0c + + /* By this time, the FDT timer is aligned to the last modulation + * edge of the reader. So we disable the auto-synchronization and + * let it count the frame delay time in the background, and generate + * an interrupt once it has reached the FDT. */ + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + 2386: e0 e4 ldi r30, 0x40 ; 64 + 2388: f9 e0 ldi r31, 0x09 ; 9 + 238a: 13 82 std Z+3, r1 ; 0x03 + + if (LastBit) { + 238c: 80 91 b7 20 lds r24, 0x20B7 + 2390: 88 23 and r24, r24 + 2392: 69 f1 breq .+90 ; 0x23ee <__vector_22+0x13a> + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; + 2394: 8c eb ldi r24, 0xBC ; 188 + 2396: 94 e0 ldi r25, 0x04 ; 4 + 2398: 86 a3 lds r24, 0x56 + 239a: 97 a3 lds r25, 0x57 + } else { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; + } + + LoadModState = LOADMOD_FDT; + 239c: 10 92 b6 20 sts 0x20B6, r1 + + CODEC_TIMER_LOADMOD.INTFLAGS = TC1_OVFIF_bm; + 23a0: e0 e4 ldi r30, 0x40 ; 64 + 23a2: f9 e0 ldi r31, 0x09 ; 9 + 23a4: 81 e0 ldi r24, 0x01 ; 1 + 23a6: 84 87 std Z+12, r24 ; 0x0c + CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc; + 23a8: 83 e0 ldi r24, 0x03 ; 3 + 23aa: 86 83 std Z+6, r24 ; 0x06 + + /* Determine if we did not receive a multiple of 8 bits. + * If this is the case, right-align the remaining data and + * store it into the buffer. */ + uint8_t RemainingBits = BitCount % 8; + 23ac: 80 91 bd 20 lds r24, 0x20BD + 23b0: 90 91 be 20 lds r25, 0x20BE + 23b4: 87 70 andi r24, 0x07 ; 7 + if (RemainingBits != 0) { + 23b6: 61 f0 breq .+24 ; 0x23d0 <__vector_22+0x11c> + uint8_t NewDataRegister = DataRegister; + 23b8: 90 91 ba 20 lds r25, 0x20BA + + while (RemainingBits++ < 8) { + 23bc: 8f 5f subi r24, 0xFF ; 255 + /* Pad with zeroes to right-align. */ + NewDataRegister >>= 1; + 23be: 96 95 lsr r25 + * store it into the buffer. */ + uint8_t RemainingBits = BitCount % 8; + if (RemainingBits != 0) { + uint8_t NewDataRegister = DataRegister; + + while (RemainingBits++ < 8) { + 23c0: 8f 5f subi r24, 0xFF ; 255 + 23c2: 89 30 cpi r24, 0x09 ; 9 + 23c4: e1 f7 brne .-8 ; 0x23be <__vector_22+0x10a> + /* Pad with zeroes to right-align. */ + NewDataRegister >>= 1; + } + + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr = NewDataRegister; + 23c6: e0 91 c1 20 lds r30, 0x20C1 + 23ca: f0 91 c2 20 lds r31, 0x20C2 + 23ce: 90 83 st Z, r25 + } + + /* Signal, that we have finished sampling */ + Flags.DemodFinished = 1; + 23d0: 81 e0 ldi r24, 0x01 ; 1 + 23d2: 80 93 bf 20 sts 0x20BF, r24 + 23d6: bc cf rjmp .-136 ; 0x2350 <__vector_22+0x9c> + + if (BitSample != (0x0 << 2)) { + /* We have a valid bit. decode and process it. */ + if (BitSample & (0x1 << 2)) { + /* 01 sequence or 11 sequence -> This is a zero bit */ + Bit = 0; + 23d8: 90 e0 ldi r25, 0x00 ; 0 + } else { + /* 10 sequence -> This is a one bit */ + Bit = 1; + } + + LastBit = Bit; + 23da: 90 93 b7 20 sts 0x20B7, r25 + + if (!IsParityBit) { + 23de: 80 91 b8 20 lds r24, 0x20B8 + 23e2: 88 23 and r24, r24 + 23e4: 09 f4 brne .+2 ; 0x23e8 <__vector_22+0x134> + 23e6: 91 cf rjmp .-222 ; 0x230a <__vector_22+0x56> + + } else { + /* This is a parity bit. Store it */ + /* TODO: Store parity and prevent overflow */ + //*ParityBufferPtr++ = Bit; + IsParityBit = false; + 23e8: 10 92 b8 20 sts 0x20B8, r1 + 23ec: b1 cf rjmp .-158 ; 0x2350 <__vector_22+0x9c> + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + + if (LastBit) { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; + } else { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; + 23ee: 8c e7 ldi r24, 0x7C ; 124 + 23f0: 94 e0 ldi r25, 0x04 ; 4 + 23f2: 86 a3 lds r24, 0x56 + 23f4: 97 a3 lds r25, 0x57 + 23f6: d2 cf rjmp .-92 ; 0x239c <__vector_22+0xe8> + + if (!IsParityBit) { + /* This is a data bit, so shift it into the data register and + * hold a local copy of it. */ + uint8_t NewDataRegister = DataRegister >> 1; + NewDataRegister |= (Bit ? 0x80 : 0x00); + 23f8: 20 e0 ldi r18, 0x00 ; 0 + 23fa: 8e cf rjmp .-228 ; 0x2318 <__vector_22+0x64> + +000023fc <__vector_83>: + * This can be understood as a "poor mans PLL" and makes sure that we are + * never too far out the bit-grid while sampling. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; +} + +ISR(CODEC_TIMER_OVF_VECT) { + 23fc: 1f 92 push r1 + 23fe: 0f 92 push r0 + 2400: 0f b6 in r0, 0x3f ; 63 + 2402: 0f 92 push r0 + 2404: 11 24 eor r1, r1 + 2406: 2f 93 push r18 + 2408: 3f 93 push r19 + 240a: 8f 93 push r24 + 240c: 9f 93 push r25 + 240e: af 93 push r26 + 2410: bf 93 push r27 + 2412: ef 93 push r30 + 2414: ff 93 push r31 + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2416: 80 91 b6 20 lds r24, 0x20B6 + 241a: 85 30 cpi r24, 0x05 ; 5 + 241c: 09 f4 brne .+2 ; 0x2420 <__vector_83+0x24> + 241e: 55 c0 rjmp .+170 ; 0x24ca <__vector_83+0xce> + 2420: 86 30 cpi r24, 0x06 ; 6 + 2422: c0 f0 brcs .+48 ; 0x2454 <__vector_83+0x58> + 2424: 88 30 cpi r24, 0x08 ; 8 + 2426: 09 f4 brne .+2 ; 0x242a <__vector_83+0x2e> + 2428: 86 c0 rjmp .+268 ; 0x2536 <__vector_83+0x13a> + 242a: 89 30 cpi r24, 0x09 ; 9 + 242c: 40 f5 brcc .+80 ; 0x247e <__vector_83+0x82> + 242e: 86 30 cpi r24, 0x06 ; 6 + 2430: 09 f4 brne .+2 ; 0x2434 <__vector_83+0x38> + 2432: c7 c0 rjmp .+398 ; 0x25c2 <__vector_83+0x1c6> + 2434: 87 30 cpi r24, 0x07 ; 7 + 2436: 09 f4 brne .+2 ; 0x243a <__vector_83+0x3e> + 2438: 95 c0 rjmp .+298 ; 0x2564 <__vector_83+0x168> + break; + + default: + break; + } +} + 243a: ff 91 pop r31 + 243c: ef 91 pop r30 + 243e: bf 91 pop r27 + 2440: af 91 pop r26 + 2442: 9f 91 pop r25 + 2444: 8f 91 pop r24 + 2446: 3f 91 pop r19 + 2448: 2f 91 pop r18 + 244a: 0f 90 pop r0 + 244c: 0f be out 0x3f, r0 ; 63 + 244e: 0f 90 pop r0 + 2450: 1f 90 pop r1 + 2452: 18 95 reti +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 2454: 82 30 cpi r24, 0x02 ; 2 + 2456: 89 f1 breq .+98 ; 0x24ba <__vector_83+0xbe> + 2458: 83 30 cpi r24, 0x03 ; 3 + 245a: 08 f1 brcs .+66 ; 0x249e <__vector_83+0xa2> + 245c: 83 30 cpi r24, 0x03 ; 3 + 245e: 09 f4 brne .+2 ; 0x2462 <__vector_83+0x66> + 2460: 5b c0 rjmp .+182 ; 0x2518 <__vector_83+0x11c> + 2462: 84 30 cpi r24, 0x04 ; 4 + 2464: 51 f7 brne .-44 ; 0x243a <__vector_83+0x3e> + /* Fetch first byte */ + DataRegister = *CodecBufferPtr; + break; + + case LOADMOD_DATA0: + if (DataRegister & 1) { + 2466: 80 91 ba 20 lds r24, 0x20BA + 246a: 80 fd sbrc r24, 0 + 246c: c7 c0 rjmp .+398 ; 0x25fc <__vector_83+0x200> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 246e: 80 e4 ldi r24, 0x40 ; 64 + 2470: e0 e4 ldi r30, 0x40 ; 64 + 2472: f6 e0 ldi r31, 0x06 ; 6 + 2474: 86 83 std Z+6, r24 ; 0x06 + } + + LoadModState = LOADMOD_DATA1; + 2476: 85 e0 ldi r24, 0x05 ; 5 + 2478: 80 93 b6 20 sts 0x20B6, r24 + break; + 247c: de cf rjmp .-68 ; 0x243a <__vector_83+0x3e> +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 247e: 89 30 cpi r24, 0x09 ; 9 + 2480: 09 f4 brne .+2 ; 0x2484 <__vector_83+0x88> + 2482: 61 c0 rjmp .+194 ; 0x2546 <__vector_83+0x14a> + 2484: 8a 30 cpi r24, 0x0A ; 10 + 2486: c9 f6 brne .-78 ; 0x243a <__vector_83+0x3e> + + case LOADMOD_FINISHED: + /* We have written all of our bits. Deactivate the loadmod + * timer. Also disable the bit-rate interrupt again. And + * stop the subcarrier divider. */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + 2488: 10 92 40 09 sts 0x0940, r1 + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + 248c: e0 e4 ldi r30, 0x40 ; 64 + 248e: f9 e0 ldi r31, 0x09 ; 9 + 2490: 16 82 std Z+6, r1 ; 0x06 + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + 2492: 10 92 00 08 sts 0x0800, r1 + + /* Signal application that we have finished loadmod */ + Flags.LoadmodFinished = 1; + 2496: 81 e0 ldi r24, 0x01 ; 1 + 2498: 80 93 c0 20 sts 0x20C0, r24 + break; + 249c: ce cf rjmp .-100 ; 0x243a <__vector_83+0x3e> +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + 249e: 88 23 and r24, r24 + 24a0: 09 f4 brne .+2 ; 0x24a4 <__vector_83+0xa8> + 24a2: 59 c0 rjmp .+178 ; 0x2556 <__vector_83+0x15a> + 24a4: 81 30 cpi r24, 0x01 ; 1 + 24a6: 49 f6 brne .-110 ; 0x243a <__vector_83+0x3e> + break; + + case LOADMOD_START: + /* Application produced data. With this interrupt we are aligned to the bit-grid. + * Start subcarrier generation and align to bitrate. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_RATE_CYCLES / 2 - 1; + 24a8: 8f e3 ldi r24, 0x3F ; 63 + 24aa: 90 e0 ldi r25, 0x00 ; 0 + 24ac: e0 e4 ldi r30, 0x40 ; 64 + 24ae: f9 e0 ldi r31, 0x09 ; 9 + 24b0: 86 a3 lds r24, 0x56 + 24b2: 97 a3 lds r25, 0x57 + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_EVCH6_gc; + 24b4: 8e e0 ldi r24, 0x0E ; 14 + 24b6: 80 93 00 08 sts 0x0800, r24 + + /* Fallthrough to first bit */ + + case LOADMOD_START_BIT0: + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 24ba: 80 e4 ldi r24, 0x40 ; 64 + 24bc: e0 e4 ldi r30, 0x40 ; 64 + 24be: f6 e0 ldi r31, 0x06 ; 6 + 24c0: 85 83 std Z+5, r24 ; 0x05 + LoadModState = LOADMOD_START_BIT1; + 24c2: 83 e0 ldi r24, 0x03 ; 3 + 24c4: 80 93 b6 20 sts 0x20B6, r24 + break; + 24c8: b8 cf rjmp .-144 ; 0x243a <__vector_83+0x3e> + + LoadModState = LOADMOD_DATA1; + break; + + case LOADMOD_DATA1: + Temp8 = DataRegister; + 24ca: 80 91 ba 20 lds r24, 0x20BA + + if (Temp8 & 1) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 24ce: 90 e4 ldi r25, 0x40 ; 64 + 24d0: e0 e4 ldi r30, 0x40 ; 64 + 24d2: f6 e0 ldi r31, 0x06 ; 6 + break; + + case LOADMOD_DATA1: + Temp8 = DataRegister; + + if (Temp8 & 1) { + 24d4: 80 fd sbrc r24, 0 + 24d6: 90 c0 rjmp .+288 ; 0x25f8 <__vector_83+0x1fc> + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 24d8: 95 83 std Z+5, r25 ; 0x05 + } + + DataRegister = Temp8 >> 1; + 24da: 86 95 lsr r24 + 24dc: 80 93 ba 20 sts 0x20BA, r24 + + Temp16 = BitSent; + 24e0: 80 91 bb 20 lds r24, 0x20BB + 24e4: 90 91 bc 20 lds r25, 0x20BC + BitSent = ++Temp16; + 24e8: 01 96 adiw r24, 0x01 ; 1 + 24ea: 80 93 bb 20 sts 0x20BB, r24 + 24ee: 90 93 bc 20 sts 0x20BC, r25 + + if ((Temp16 & 0x07) == 0) { + 24f2: 9c 01 movw r18, r24 + 24f4: 27 70 andi r18, 0x07 ; 7 + 24f6: 30 70 andi r19, 0x00 ; 0 + 24f8: 21 15 cp r18, r1 + 24fa: 31 05 cpc r19, r1 + 24fc: 09 f4 brne .+2 ; 0x2500 <__vector_83+0x104> + 24fe: 83 c0 rjmp .+262 ; 0x2606 <__vector_83+0x20a> + /* Byte boundary. Load parity bit and output it later. */ + LoadModState = LOADMOD_PARITY0; + break; + } + + if (Temp16 == BitCount) { + 2500: 20 91 bd 20 lds r18, 0x20BD + 2504: 30 91 be 20 lds r19, 0x20BE + 2508: 82 17 cp r24, r18 + 250a: 93 07 cpc r25, r19 + 250c: 09 f0 breq .+2 ; 0x2510 <__vector_83+0x114> + 250e: 55 c0 rjmp .+170 ; 0x25ba <__vector_83+0x1be> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } + + if (BitSent == BitCount) { + /* No data left */ + LoadModState = LOADMOD_STOP_BIT0; + 2510: 88 e0 ldi r24, 0x08 ; 8 + 2512: 80 93 b6 20 sts 0x20B6, r24 + 2516: 91 cf rjmp .-222 ; 0x243a <__vector_83+0x3e> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_START_BIT1; + break; + + case LOADMOD_START_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 2518: 80 e4 ldi r24, 0x40 ; 64 + 251a: e0 e4 ldi r30, 0x40 ; 64 + 251c: f6 e0 ldi r31, 0x06 ; 6 + 251e: 86 83 std Z+6, r24 ; 0x06 + LoadModState = LOADMOD_DATA0; + 2520: 84 e0 ldi r24, 0x04 ; 4 + 2522: 80 93 b6 20 sts 0x20B6, r24 + + /* Fetch first byte */ + DataRegister = *CodecBufferPtr; + 2526: e0 91 c1 20 lds r30, 0x20C1 + 252a: f0 91 c2 20 lds r31, 0x20C2 + 252e: 80 81 ld r24, Z + 2530: 80 93 ba 20 sts 0x20BA, r24 + break; + 2534: 82 cf rjmp .-252 ; 0x243a <__vector_83+0x3e> + } + + break; + + case LOADMOD_STOP_BIT0: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 2536: 80 e4 ldi r24, 0x40 ; 64 + 2538: e0 e4 ldi r30, 0x40 ; 64 + 253a: f6 e0 ldi r31, 0x06 ; 6 + 253c: 86 83 std Z+6, r24 ; 0x06 + LoadModState = LOADMOD_STOP_BIT1; + 253e: 89 e0 ldi r24, 0x09 ; 9 + 2540: 80 93 b6 20 sts 0x20B6, r24 + break; + 2544: 7a cf rjmp .-268 ; 0x243a <__vector_83+0x3e> + + case LOADMOD_STOP_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 2546: 80 e4 ldi r24, 0x40 ; 64 + 2548: e0 e4 ldi r30, 0x40 ; 64 + 254a: f6 e0 ldi r31, 0x06 ; 6 + 254c: 86 83 std Z+6, r24 ; 0x06 + LoadModState = LOADMOD_FINISHED; + 254e: 8a e0 ldi r24, 0x0A ; 10 + 2550: 80 93 b6 20 sts 0x20B6, r24 + break; + 2554: 72 cf rjmp .-284 ; 0x243a <__vector_83+0x3e> + uint16_t Temp16; + + switch (LoadModState) { + case LOADMOD_FDT: + /* No data has been produced, but FDT has ended. Switch over to bit-grid aligning. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_GRID_CYCLES - 1; + 2556: 8f e7 ldi r24, 0x7F ; 127 + 2558: 90 e0 ldi r25, 0x00 ; 0 + 255a: e0 e4 ldi r30, 0x40 ; 64 + 255c: f9 e0 ldi r31, 0x09 ; 9 + 255e: 86 a3 lds r24, 0x56 + 2560: 97 a3 lds r25, 0x57 + break; + 2562: 6b cf rjmp .-298 ; 0x243a <__vector_83+0x3e> + + LoadModState = LOADMOD_PARITY1; + break; + + case LOADMOD_PARITY1: + if (*ParityBufferPtr) { + 2564: e0 91 c3 20 lds r30, 0x20C3 + 2568: f0 91 c4 20 lds r31, 0x20C4 + 256c: 80 81 ld r24, Z + 256e: 88 23 and r24, r24 + 2570: e1 f5 brne .+120 ; 0x25ea <__vector_83+0x1ee> + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 2572: 80 e4 ldi r24, 0x40 ; 64 + 2574: a0 e4 ldi r26, 0x40 ; 64 + 2576: b6 e0 ldi r27, 0x06 ; 6 + 2578: 15 96 adiw r26, 0x05 ; 5 + 257a: 8c 93 st X, r24 + 257c: 15 97 sbiw r26, 0x05 ; 5 + } + + if (BitSent == BitCount) { + 257e: 20 91 bb 20 lds r18, 0x20BB + 2582: 30 91 bc 20 lds r19, 0x20BC + 2586: 80 91 bd 20 lds r24, 0x20BD + 258a: 90 91 be 20 lds r25, 0x20BE + 258e: 28 17 cp r18, r24 + 2590: 39 07 cpc r19, r25 + 2592: 09 f4 brne .+2 ; 0x2596 <__vector_83+0x19a> + 2594: bd cf rjmp .-134 ; 0x2510 <__vector_83+0x114> + /* No data left */ + LoadModState = LOADMOD_STOP_BIT0; + } else { + /* Fetch next data and continue sending bits. */ + ParityBufferPtr++; + 2596: 31 96 adiw r30, 0x01 ; 1 + 2598: e0 93 c3 20 sts 0x20C3, r30 + 259c: f0 93 c4 20 sts 0x20C4, r31 + DataRegister = *++CodecBufferPtr; + 25a0: e0 91 c1 20 lds r30, 0x20C1 + 25a4: f0 91 c2 20 lds r31, 0x20C2 + 25a8: cf 01 movw r24, r30 + 25aa: 01 96 adiw r24, 0x01 ; 1 + 25ac: 80 93 c1 20 sts 0x20C1, r24 + 25b0: 90 93 c2 20 sts 0x20C2, r25 + 25b4: 81 81 ldd r24, Z+1 ; 0x01 + 25b6: 80 93 ba 20 sts 0x20BA, r24 + LoadModState = LOADMOD_DATA0; + 25ba: 84 e0 ldi r24, 0x04 ; 4 + 25bc: 80 93 b6 20 sts 0x20B6, r24 + 25c0: 3c cf rjmp .-392 ; 0x243a <__vector_83+0x3e> + LoadModState = LOADMOD_DATA0; + + break; + + case LOADMOD_PARITY0: + if (*ParityBufferPtr) { + 25c2: e0 91 c3 20 lds r30, 0x20C3 + 25c6: f0 91 c4 20 lds r31, 0x20C4 + 25ca: 80 81 ld r24, Z + 25cc: 88 23 and r24, r24 + 25ce: 41 f4 brne .+16 ; 0x25e0 <__vector_83+0x1e4> + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 25d0: 80 e4 ldi r24, 0x40 ; 64 + 25d2: e0 e4 ldi r30, 0x40 ; 64 + 25d4: f6 e0 ldi r31, 0x06 ; 6 + 25d6: 86 83 std Z+6, r24 ; 0x06 + } + + LoadModState = LOADMOD_PARITY1; + 25d8: 87 e0 ldi r24, 0x07 ; 7 + 25da: 80 93 b6 20 sts 0x20B6, r24 + break; + 25de: 2d cf rjmp .-422 ; 0x243a <__vector_83+0x3e> + + break; + + case LOADMOD_PARITY0: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 25e0: 80 e4 ldi r24, 0x40 ; 64 + 25e2: e0 e4 ldi r30, 0x40 ; 64 + 25e4: f6 e0 ldi r31, 0x06 ; 6 + 25e6: 85 83 std Z+5, r24 ; 0x05 + 25e8: f7 cf rjmp .-18 ; 0x25d8 <__vector_83+0x1dc> + LoadModState = LOADMOD_PARITY1; + break; + + case LOADMOD_PARITY1: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 25ea: 80 e4 ldi r24, 0x40 ; 64 + 25ec: a0 e4 ldi r26, 0x40 ; 64 + 25ee: b6 e0 ldi r27, 0x06 ; 6 + 25f0: 16 96 adiw r26, 0x06 ; 6 + 25f2: 8c 93 st X, r24 + 25f4: 16 97 sbiw r26, 0x06 ; 6 + 25f6: c3 cf rjmp .-122 ; 0x257e <__vector_83+0x182> + + case LOADMOD_DATA1: + Temp8 = DataRegister; + + if (Temp8 & 1) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 25f8: 96 83 std Z+6, r25 ; 0x06 + 25fa: 6f cf rjmp .-290 ; 0x24da <__vector_83+0xde> + DataRegister = *CodecBufferPtr; + break; + + case LOADMOD_DATA0: + if (DataRegister & 1) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + 25fc: 80 e4 ldi r24, 0x40 ; 64 + 25fe: e0 e4 ldi r30, 0x40 ; 64 + 2600: f6 e0 ldi r31, 0x06 ; 6 + 2602: 85 83 std Z+5, r24 ; 0x05 + 2604: 38 cf rjmp .-400 ; 0x2476 <__vector_83+0x7a> + Temp16 = BitSent; + BitSent = ++Temp16; + + if ((Temp16 & 0x07) == 0) { + /* Byte boundary. Load parity bit and output it later. */ + LoadModState = LOADMOD_PARITY0; + 2606: 86 e0 ldi r24, 0x06 ; 6 + 2608: 80 93 b6 20 sts 0x20B6, r24 + break; + 260c: 16 cf rjmp .-468 ; 0x243a <__vector_83+0x3e> + +0000260e : + default: + break; + } +} + +void ISO14443ACodecInit(void) { + 260e: cf 93 push r28 + 2610: df 93 push r29 +static volatile LoadModStateType LoadModState; +static volatile bool SamplePosition; + +static void Initialize(void) { + /* Configure CARRIER input pin and route it to EVSYS */ + CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK; + 2612: e0 e4 ldi r30, 0x40 ; 64 + 2614: f6 e0 ldi r31, 0x06 ; 6 + 2616: 84 e0 ldi r24, 0x04 ; 4 + 2618: 82 83 std Z+2, r24 ; 0x02 + CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc; + 261a: 12 8a std Z+18, r1 ; 0x12 + EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX; + 261c: c0 e8 ldi r28, 0x80 ; 128 + 261e: d1 e0 ldi r29, 0x01 ; 1 + 2620: 82 e6 ldi r24, 0x62 ; 98 + 2622: 8e 83 std Y+6, r24 ; 0x06 + + /* Configure two DEMOD pins for input. + * Configure event channel 0 for rising edge (begin of modulation pause) + * Configure event channel 1 for falling edge (end of modulation pause) */ + CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK; + 2624: a0 e2 ldi r26, 0x20 ; 32 + 2626: b6 e0 ldi r27, 0x06 ; 6 + 2628: 85 e0 ldi r24, 0x05 ; 5 + 262a: 12 96 adiw r26, 0x02 ; 2 + 262c: 8c 93 st X, r24 + 262e: 12 97 sbiw r26, 0x02 ; 2 + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc; + 2630: 81 e0 ldi r24, 0x01 ; 1 + 2632: 50 96 adiw r26, 0x10 ; 16 + 2634: 8c 93 st X, r24 + 2636: 50 97 sbiw r26, 0x10 ; 16 + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc; + 2638: 82 e0 ldi r24, 0x02 ; 2 + 263a: 52 96 adiw r26, 0x12 ; 18 + 263c: 8c 93 st X, r24 + 263e: 52 97 sbiw r26, 0x12 ; 18 + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + 2640: 1a 96 adiw r26, 0x0a ; 10 + 2642: 1c 92 st X, r1 + 2644: 1a 97 sbiw r26, 0x0a ; 10 + CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc; + 2646: 83 e0 ldi r24, 0x03 ; 3 + 2648: 19 96 adiw r26, 0x09 ; 9 + 264a: 8c 93 st X, r24 + EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0; + 264c: 98 e5 ldi r25, 0x58 ; 88 + 264e: 98 83 st Y, r25 + EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1; + 2650: 9a e5 ldi r25, 0x5A ; 90 + 2652: 99 83 std Y+1, r25 ; 0x01 + + /* Configure LOADMOD and SUBCARRIER output pins. + * Disable PSK modulation by setting pin to low. */ + CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK; + 2654: 90 e4 ldi r25, 0x40 ; 64 + 2656: 91 83 std Z+1, r25 ; 0x01 + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + 2658: 96 83 std Z+6, r25 ; 0x06 + CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK; + 265a: 81 83 std Z+1, r24 ; 0x01 + CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK; + 265c: 86 83 std Z+6, r24 ; 0x06 + + /* Configure subcarrier generation with 50% DC output using OOK */ + CODEC_SUBCARRIER_TIMER.PER = ISO14443A_SUBCARRIER_DIVIDER - 1; + 265e: e0 e0 ldi r30, 0x00 ; 0 + 2660: f8 e0 ldi r31, 0x08 ; 8 + 2662: 8f e0 ldi r24, 0x0F ; 15 + 2664: 90 e0 ldi r25, 0x00 ; 0 + 2666: 86 a3 lds r24, 0x56 + 2668: 97 a3 lds r25, 0x57 + CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = ISO14443A_SUBCARRIER_DIVIDER/2; + 266a: 88 e0 ldi r24, 0x08 ; 8 + 266c: 90 e0 ldi r25, 0x00 ; 0 + 266e: 82 a7 lds r24, 0x72 + 2670: 93 a7 lds r25, 0x73 + CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc; + 2672: 83 e2 ldi r24, 0x23 ; 35 + 2674: 81 83 std Z+1, r24 ; 0x01 + +void ISO14443ACodecInit(void) { + /* Initialize common peripherals and start listening + * for incoming data. */ + Initialize(); + StartDemod(); + 2676: bb dd rcall .-1162 ; 0x21ee + 2678: df 91 pop r29 +} + 267a: cf 91 pop r28 + 267c: 08 95 ret + +0000267e : + 267e: 80 91 bf 20 lds r24, 0x20BF + +void ISO14443ACodecTask(void) { + if (Flags.DemodFinished) { + 2682: 88 23 and r24, r24 + 2684: c9 f0 breq .+50 ; 0x26b8 + Flags.DemodFinished = 0; + 2686: 10 92 bf 20 sts 0x20BF, r1 +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); +} + +INLINE void CodecSetDemodPower(bool bOnOff) { + CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; + 268a: e0 e2 ldi r30, 0x20 ; 32 + 268c: f6 e0 ldi r31, 0x06 ; 6 + 268e: 82 e0 ldi r24, 0x02 ; 2 + 2690: 81 83 std Z+1, r24 ; 0x01 + + if (bOnOff) { + CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; + } else { + CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK; + 2692: 86 83 std Z+6, r24 ; 0x06 + /* Reception finished. Process the received bytes */ + CodecSetDemodPower(false); + + uint16_t DemodBitCount = BitCount; + 2694: 60 91 bd 20 lds r22, 0x20BD + 2698: 70 91 be 20 lds r23, 0x20BE + uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; + + if (DemodBitCount > 0) { + 269c: 61 15 cp r22, r1 + 269e: 71 05 cpc r23, r1 + 26a0: 99 f4 brne .+38 ; 0x26c8 +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); +} + +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); + 26a2: e0 91 ff 20 lds r30, 0x20FF + 26a6: f0 91 00 21 lds r31, 0x2100 + 26aa: 09 95 icall + CodecBufferPtr = CodecBuffer; + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + LoadModState = LOADMOD_START; + } else { + /* No data to be processed. Disable loadmodding and start listening again */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + 26ac: 10 92 40 09 sts 0x0940, r1 + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + 26b0: e0 e4 ldi r30, 0x40 ; 64 + 26b2: f9 e0 ldi r31, 0x09 ; 9 + 26b4: 16 82 std Z+6, r1 ; 0x06 + + StartDemod(); + 26b6: 9b dd rcall .-1226 ; 0x21ee + 26b8: 80 91 c0 20 lds r24, 0x20C0 + } + } + + if (Flags.LoadmodFinished) { + 26bc: 88 23 and r24, r24 + 26be: 09 f4 brne .+2 ; 0x26c2 + 26c0: 08 95 ret + 26c2: 10 92 c0 20 sts 0x20C0, r1 + Flags.LoadmodFinished = 0; + 26c6: 93 cd rjmp .-1242 ; 0x21ee + /* Load modulation has been finished. Stop it and start to listen + * for incoming data again. */ + StartDemod(); + 26c8: e0 91 03 21 lds r30, 0x2103 + 26cc: f0 91 04 21 lds r31, 0x2104 +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); +} + +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); + 26d0: 80 e2 ldi r24, 0x20 ; 32 + 26d2: 92 e2 ldi r25, 0x22 ; 34 + 26d4: 09 95 icall + 26d6: 9c 01 movw r18, r24 + 26d8: 94 fd sbrc r25, 4 + 26da: 28 c0 rjmp .+80 ; 0x272c + 26dc: ac 01 movw r20, r24 + + if (DemodBitCount > 0) { + /* Call application if we received data */ + AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); + + if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) { + 26de: 56 95 lsr r21 + 26e0: 47 95 ror r20 + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + 26e2: 56 95 lsr r21 + 26e4: 47 95 ror r20 + 26e6: 56 95 lsr r21 + 26e8: 47 95 ror r20 + 26ea: 41 15 cp r20, r1 + 26ec: 51 05 cpc r21, r1 + 26ee: f9 f0 breq .+62 ; 0x272e + 26f0: 60 e0 ldi r22, 0x00 ; 0 + 26f2: e0 e0 ldi r30, 0x00 ; 0 + 26f4: f0 e0 ldi r31, 0x00 ; 0 + 26f6: e0 5e subi r30, 0xE0 ; 224 + 26f8: fd 4d sbci r31, 0xDD ; 221 + 26fa: 80 81 ld r24, Z + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + ODD_PARITY(CodecBuffer[i]); + 26fc: 08 2e mov r0, r24 + 26fe: 82 95 swap r24 + 2700: 80 25 eor r24, r0 + 2702: 08 2e mov r0, r24 + 2704: 86 95 lsr r24 + 2706: 86 95 lsr r24 + 2708: 80 25 eor r24, r0 + 270a: e0 58 subi r30, 0x80 ; 128 + 270c: ff 4f sbci r31, 0xFF ; 255 + 270e: 90 e0 ldi r25, 0x00 ; 0 + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + 2710: 01 96 adiw r24, 0x01 ; 1 + 2712: 95 95 asr r25 + ODD_PARITY(CodecBuffer[i]); + 2714: 87 95 ror r24 + 2716: 91 e0 ldi r25, 0x01 ; 1 + 2718: 80 fd sbrc r24, 0 + 271a: 90 e0 ldi r25, 0x00 ; 0 + 271c: 90 83 st Z, r25 + 271e: 6f 5f subi r22, 0xFF ; 255 + 2720: e6 2f mov r30, r22 + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + 2722: f0 e0 ldi r31, 0x00 ; 0 + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + 2724: e4 17 cp r30, r20 + 2726: f5 07 cpc r31, r21 + 2728: 30 f3 brcs .-52 ; 0x26f6 + 272a: 01 c0 rjmp .+2 ; 0x272e + 272c: 3f 7e andi r19, 0xEF ; 239 + 272e: 21 15 cp r18, r1 + 2730: 31 05 cpc r19, r1 + AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); + + if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) { + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + 2732: 09 f4 brne .+2 ; 0x2736 + } + } else { + ApplicationReset(); + } + + if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) { + 2734: bb cf rjmp .-138 ; 0x26ac + 2736: 20 93 bd 20 sts 0x20BD, r18 + 273a: 30 93 be 20 sts 0x20BE, r19 + BitCount = AnswerBitCount; + 273e: 10 92 bb 20 sts 0x20BB, r1 + 2742: 10 92 bc 20 sts 0x20BC, r1 + BitSent = 0; + 2746: 80 e2 ldi r24, 0x20 ; 32 + 2748: 92 e2 ldi r25, 0x22 ; 34 + 274a: 80 93 c1 20 sts 0x20C1, r24 + CodecBufferPtr = CodecBuffer; + 274e: 90 93 c2 20 sts 0x20C2, r25 + 2752: 80 ea ldi r24, 0xA0 ; 160 + 2754: 92 e2 ldi r25, 0x22 ; 34 + 2756: 80 93 c3 20 sts 0x20C3, r24 + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + 275a: 90 93 c4 20 sts 0x20C4, r25 + 275e: 81 e0 ldi r24, 0x01 ; 1 + 2760: 80 93 b6 20 sts 0x20B6, r24 + LoadModState = LOADMOD_START; + 2764: 80 91 c0 20 lds r24, 0x20C0 + 2768: 88 23 and r24, r24 + + StartDemod(); + } + } + + if (Flags.LoadmodFinished) { + 276a: 09 f4 brne .+2 ; 0x276e + 276c: a9 cf rjmp .-174 ; 0x26c0 + 276e: a9 cf rjmp .-174 ; 0x26c2 + +00002770 : + Block[11] = Block[3]; +} + +void MifareClassicAppInit1K(void) +{ + State = STATE_IDLE; + 2770: 81 e0 ldi r24, 0x01 ; 1 + 2772: 80 93 c5 20 sts 0x20C5, r24 + CardATQAValue = MFCLASSIC_1K_ATQA_VALUE; + 2776: 84 e0 ldi r24, 0x04 ; 4 + 2778: 90 e0 ldi r25, 0x00 ; 0 + 277a: 80 93 c6 20 sts 0x20C6, r24 + 277e: 90 93 c7 20 sts 0x20C7, r25 + CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE; + 2782: 88 e0 ldi r24, 0x08 ; 8 + 2784: 80 93 c8 20 sts 0x20C8, r24 +} + 2788: 08 95 ret + +0000278a : + +void MifareClassicAppInit4K(void) +{ + State = STATE_IDLE; + 278a: 81 e0 ldi r24, 0x01 ; 1 + 278c: 80 93 c5 20 sts 0x20C5, r24 + CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; + 2790: 82 e0 ldi r24, 0x02 ; 2 + 2792: 90 e0 ldi r25, 0x00 ; 0 + 2794: 80 93 c6 20 sts 0x20C6, r24 + 2798: 90 93 c7 20 sts 0x20C7, r25 + CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE; + 279c: 88 e1 ldi r24, 0x18 ; 24 + 279e: 80 93 c8 20 sts 0x20C8, r24 +} + 27a2: 08 95 ret + +000027a4 : + +void MifareClassicAppReset(void) +{ + State = STATE_IDLE; + 27a4: 81 e0 ldi r24, 0x01 ; 1 + 27a6: 80 93 c5 20 sts 0x20C5, r24 +} + 27aa: 08 95 ret + +000027ac : + +void MifareClassicAppTask(void) +{ + +} + 27ac: 08 95 ret + +000027ae : + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + 27ae: 8f 92 push r8 + 27b0: 9f 92 push r9 + 27b2: af 92 push r10 + 27b4: bf 92 push r11 + 27b6: cf 92 push r12 + 27b8: df 92 push r13 + 27ba: ef 92 push r14 + 27bc: ff 92 push r15 + 27be: 0f 93 push r16 + 27c0: 1f 93 push r17 + 27c2: cf 93 push r28 + 27c4: df 93 push r29 + 27c6: cd b7 in r28, 0x3d ; 61 + 27c8: de b7 in r29, 0x3e ; 62 + 27ca: 2e 97 sbiw r28, 0x0e ; 14 + 27cc: cd bf out 0x3d, r28 ; 61 + 27ce: de bf out 0x3e, r29 ; 62 + 27d0: 7c 01 movw r14, r24 + switch(State) { + 27d2: 80 91 c5 20 lds r24, 0x20C5 + 27d6: 84 30 cpi r24, 0x04 ; 4 + 27d8: 09 f4 brne .+2 ; 0x27dc + 27da: f9 c0 rjmp .+498 ; 0x29ce + 27dc: 85 30 cpi r24, 0x05 ; 5 + 27de: 08 f4 brcc .+2 ; 0x27e2 + 27e0: 3f c0 rjmp .+126 ; 0x2860 + 27e2: 86 30 cpi r24, 0x06 ; 6 + 27e4: 09 f4 brne .+2 ; 0x27e8 + 27e6: c0 c0 rjmp .+384 ; 0x2968 + 27e8: 86 30 cpi r24, 0x06 ; 6 + 27ea: 08 f0 brcs .+2 ; 0x27ee + 27ec: 64 c0 rjmp .+200 ; 0x28b6 + + case STATE_AUTHED_IDLE: + /* In this state, all communication is encrypted. Thus we first have to encrypt + * the incoming data. */ + for (uint8_t i=0; i<4; i++) + Buffer[i] ^= Crypto1Byte(); + 27ee: f7 01 movw r30, r14 + 27f0: 00 81 ld r16, Z + 27f2: 0e 94 08 1c call 0x3810 ; 0x3810 + 27f6: 80 27 eor r24, r16 + 27f8: d7 01 movw r26, r14 + 27fa: 8c 93 st X, r24 + 27fc: 11 96 adiw r26, 0x01 ; 1 + 27fe: 0c 91 ld r16, X + 2800: 0e 94 08 1c call 0x3810 ; 0x3810 + 2804: 80 27 eor r24, r16 + 2806: f7 01 movw r30, r14 + 2808: 81 83 std Z+1, r24 ; 0x01 + 280a: 02 81 ldd r16, Z+2 ; 0x02 + 280c: 0e 94 08 1c call 0x3810 ; 0x3810 + 2810: 80 27 eor r24, r16 + 2812: d7 01 movw r26, r14 + 2814: 12 96 adiw r26, 0x02 ; 2 + 2816: 8c 93 st X, r24 + 2818: 12 97 sbiw r26, 0x02 ; 2 + 281a: 13 96 adiw r26, 0x03 ; 3 + 281c: 0c 91 ld r16, X + 281e: f8 d7 rcall .+4080 ; 0x3810 + 2820: 80 27 eor r24, r16 + 2822: f7 01 movw r30, r14 + 2824: 83 83 std Z+3, r24 ; 0x03 + 2826: 80 81 ld r24, Z + + if (Buffer[0] == CMD_READ) { + 2828: 80 33 cpi r24, 0x30 ; 48 + 282a: 09 f4 brne .+2 ; 0x282e + 282c: bd c2 rjmp .+1402 ; 0x2da8 + 282e: 80 3a cpi r24, 0xA0 ; 160 + * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + 2830: 09 f4 brne .+2 ; 0x2834 + 2832: 39 c3 rjmp .+1650 ; 0x2ea6 + 2834: 80 3c cpi r24, 0xC0 ; 192 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_DECREMENT) { + 2836: 09 f4 brne .+2 ; 0x283a + 2838: 53 c3 rjmp .+1702 ; 0x2ee0 + 283a: 81 3c cpi r24, 0xC1 ; 193 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_INCREMENT) { + 283c: 09 f4 brne .+2 ; 0x2840 + 283e: 35 c4 rjmp .+2154 ; 0x30aa <__stack+0xab> + 2840: 82 3c cpi r24, 0xC2 ; 194 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_RESTORE) { + 2842: 09 f4 brne .+2 ; 0x2846 + 2844: 3f c4 rjmp .+2174 ; 0x30c4 <__stack+0xc5> + 2846: 80 3b cpi r24, 0xB0 ; 176 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + }else if (Buffer[0] == CMD_TRANSFER) { + 2848: 09 f4 brne .+2 ; 0x284c + 284a: 4b c4 rjmp .+2198 ; 0x30e2 <__stack+0xe3> + 284c: 80 56 subi r24, 0x60 ; 96 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + + return ACK_NAK_FRAME_SIZE; + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { + 284e: 82 30 cpi r24, 0x02 ; 2 + 2850: 08 f4 brcc .+2 ; 0x2854 + 2852: 96 c1 rjmp .+812 ; 0x2b80 + 2854: 81 e0 ldi r24, 0x01 ; 1 + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else { + /* Unknown command. Enter HALT state */ + State = STATE_IDLE; + 2856: 80 93 c5 20 sts 0x20C5, r24 + 285a: 80 e0 ldi r24, 0x00 ; 0 + /* Unknown state? Should never happen. */ + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; + 285c: 90 e0 ldi r25, 0x00 ; 0 + 285e: 65 c0 rjmp .+202 ; 0x292a + } else { + /* Unknown command. Enter HALT state */ + State = STATE_IDLE; + } + + break; + 2860: 82 30 cpi r24, 0x02 ; 2 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 2862: 09 f4 brne .+2 ; 0x2866 + 2864: a0 c0 rjmp .+320 ; 0x29a6 + 2866: 83 30 cpi r24, 0x03 ; 3 + 2868: 08 f4 brcc .+2 ; 0x286c + 286a: 6f c0 rjmp .+222 ; 0x294a + 286c: f7 01 movw r30, r14 +INLINE +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + 286e: 80 81 ld r24, Z + 2870: 86 32 cpi r24, 0x26 ; 38 + 2872: 09 f4 brne .+2 ; 0x2876 + 2874: 6f c1 rjmp .+734 ; 0x2b54 + 2876: 82 35 cpi r24, 0x52 ; 82 + 2878: 09 f4 brne .+2 ; 0x287c + 287a: 6c c1 rjmp .+728 ; 0x2b54 + 287c: 80 35 cpi r24, 0x50 ; 80 + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { + State = STATE_READY; + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + 287e: 09 f4 brne .+2 ; 0x2882 + 2880: 75 c1 rjmp .+746 ; 0x2b6c + 2882: 98 2f mov r25, r24 + } + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + 2884: 90 56 subi r25, 0x60 ; 96 + 2886: 92 30 cpi r25, 0x02 ; 2 + 2888: 08 f4 brcc .+2 ; 0x288c + 288a: e7 c1 rjmp .+974 ; 0x2c5a + 288c: 80 33 cpi r24, 0x30 ; 48 + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_READ) || (Buffer[0] == CMD_WRITE) || (Buffer[0] == CMD_DECREMENT) + 288e: 51 f0 breq .+20 ; 0x28a4 + 2890: 80 3a cpi r24, 0xA0 ; 160 + 2892: 41 f0 breq .+16 ; 0x28a4 + 2894: 80 3c cpi r24, 0xC0 ; 192 + 2896: 31 f0 breq .+12 ; 0x28a4 + 2898: 81 3c cpi r24, 0xC1 ; 193 + || (Buffer[0] == CMD_INCREMENT) || (Buffer[0] == CMD_RESTORE) || (Buffer[0] == CMD_TRANSFER) ) { + 289a: 21 f0 breq .+8 ; 0x28a4 + 289c: 82 3c cpi r24, 0xC2 ; 194 + 289e: 11 f0 breq .+4 ; 0x28a4 + 28a0: 80 3b cpi r24, 0xB0 ; 176 + 28a2: c1 f6 brne .-80 ; 0x2854 + 28a4: 81 e0 ldi r24, 0x01 ; 1 + State = STATE_IDLE; + 28a6: 80 93 c5 20 sts 0x20C5, r24 + 28aa: 84 e0 ldi r24, 0x04 ; 4 + Buffer[0] = NAK_NOT_AUTHED; + 28ac: f7 01 movw r30, r14 + 28ae: 80 83 st Z, r24 + 28b0: 84 e0 ldi r24, 0x04 ; 4 + return ACK_NAK_FRAME_SIZE; + 28b2: 90 e0 ldi r25, 0x00 ; 0 + 28b4: 3a c0 rjmp .+116 ; 0x292a + 28b6: 8a 30 cpi r24, 0x0A ; 10 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 28b8: 08 f0 brcs .+2 ; 0x28bc + 28ba: 53 c0 rjmp .+166 ; 0x2962 + 28bc: f7 01 movw r30, r14 + * decrypt the data and check CRC. Read data from the requested block + * address into the global block buffer and check for integrity. Then + * add or subtract according to issued command if necessary and store + * the block back into the global block buffer. */ + for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + 28be: 00 81 ld r16, Z + 28c0: a7 d7 rcall .+3918 ; 0x3810 + 28c2: 80 27 eor r24, r16 + 28c4: d7 01 movw r26, r14 + 28c6: 8c 93 st X, r24 + 28c8: 11 96 adiw r26, 0x01 ; 1 + 28ca: 0c 91 ld r16, X + 28cc: a1 d7 rcall .+3906 ; 0x3810 + 28ce: 80 27 eor r24, r16 + 28d0: f7 01 movw r30, r14 + 28d2: 81 83 std Z+1, r24 ; 0x01 + 28d4: 02 81 ldd r16, Z+2 ; 0x02 + 28d6: 9c d7 rcall .+3896 ; 0x3810 + 28d8: 80 27 eor r24, r16 + 28da: d7 01 movw r26, r14 + 28dc: 12 96 adiw r26, 0x02 ; 2 + 28de: 8c 93 st X, r24 + 28e0: 12 97 sbiw r26, 0x02 ; 2 + 28e2: 13 96 adiw r26, 0x03 ; 3 + 28e4: 0c 91 ld r16, X + 28e6: 94 d7 rcall .+3880 ; 0x3810 + 28e8: 80 27 eor r24, r16 + 28ea: f7 01 movw r30, r14 + 28ec: 83 83 std Z+3, r24 ; 0x03 + 28ee: 04 81 ldd r16, Z+4 ; 0x04 + 28f0: 8f d7 rcall .+3870 ; 0x3810 + 28f2: 80 27 eor r24, r16 + 28f4: d7 01 movw r26, r14 + 28f6: 14 96 adiw r26, 0x04 ; 4 + 28f8: 8c 93 st X, r24 + 28fa: 14 97 sbiw r26, 0x04 ; 4 + 28fc: 15 96 adiw r26, 0x05 ; 5 + 28fe: 0c 91 ld r16, X + 2900: 87 d7 rcall .+3854 ; 0x3810 + 2902: 80 27 eor r24, r16 + 2904: f7 01 movw r30, r14 + 2906: 85 83 std Z+5, r24 ; 0x05 + 2908: c7 01 movw r24, r14 + 290a: 64 e0 ldi r22, 0x04 ; 4 + 290c: 70 e0 ldi r23, 0x00 ; 0 + 290e: 92 d4 rcall .+2340 ; 0x3234 + 2910: 88 23 and r24, r24 + 2912: 09 f0 breq .+2 ; 0x2916 + 2914: 0f c2 rjmp .+1054 ; 0x2d34 + + if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { + 2916: bd d7 rcall .+3962 ; 0x3892 + 2918: 91 e0 ldi r25, 0x01 ; 1 + 291a: 98 27 eor r25, r24 + 291c: f7 01 movw r30, r14 + 291e: 90 83 st Z, r25 + 2920: 85 e0 ldi r24, 0x05 ; 5 + 2922: 80 93 c5 20 sts 0x20C5, r24 + /* Not sure if this is the correct error code.. */ + Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); + } + } else { + /* CRC Error. */ + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 2926: 84 e0 ldi r24, 0x04 ; 4 + 2928: 90 e0 ldi r25, 0x00 ; 0 + 292a: 2e 96 adiw r28, 0x0e ; 14 + 292c: cd bf out 0x3d, r28 ; 61 + 292e: de bf out 0x3e, r29 ; 62 + 2930: df 91 pop r29 + } + + State = STATE_AUTHED_IDLE; + 2932: cf 91 pop r28 + 2934: 1f 91 pop r17 + 2936: 0f 91 pop r16 + return ACK_NAK_FRAME_SIZE; + 2938: ff 90 pop r15 + 293a: ef 90 pop r14 + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; +} + 293c: df 90 pop r13 + 293e: cf 90 pop r12 + 2940: bf 90 pop r11 + 2942: af 90 pop r10 + 2944: 9f 90 pop r9 + 2946: 8f 90 pop r8 + 2948: 08 95 ret + 294a: 20 91 c6 20 lds r18, 0x20C6 + 294e: 90 91 c7 20 lds r25, 0x20C7 + 2952: d7 01 movw r26, r14 + 2954: 8c 91 ld r24, X + 2956: 86 32 cpi r24, 0x26 ; 38 + 2958: 09 f4 brne .+2 ; 0x295c + 295a: f3 c0 rjmp .+486 ; 0x2b42 +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + case STATE_IDLE: + case STATE_HALT: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 295c: 82 35 cpi r24, 0x52 ; 82 + 295e: 09 f4 brne .+2 ; 0x2962 + 2960: f0 c0 rjmp .+480 ; 0x2b42 + 2962: 80 e0 ldi r24, 0x00 ; 0 + 2964: 90 e0 ldi r25, 0x00 ; 0 + 2966: e1 cf rjmp .-62 ; 0x292a + 2968: 87 01 movw r16, r14 + 296a: cc 24 eor r12, r12 + 296c: f8 01 movw r30, r16 + 296e: 80 80 ld r8, Z + 2970: 4f d7 rcall .+3742 ; 0x3810 + 2972: 88 25 eor r24, r8 + /* Unknown state? Should never happen. */ + break; + } + + /* No response has been sent, when we reach here */ + return ISO14443A_APP_NO_RESPONSE; + 2974: d8 01 movw r26, r16 + 2976: 8d 93 st X+, r24 + 2978: 8d 01 movw r16, r26 + } else { + /* Unknown command. Enter HALT state */ + State = STATE_IDLE; + } + + break; + 297a: c3 94 inc r12 + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) +{ + switch(State) { + 297c: b2 e1 ldi r27, 0x12 ; 18 + * check for CRC. Then write the data when ReadOnly mode is not + * activated. */ + + /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + 297e: cb 16 cp r12, r27 + 2980: a9 f7 brne .-22 ; 0x296c + 2982: c7 01 movw r24, r14 + 2984: 60 e1 ldi r22, 0x10 ; 16 + 2986: 70 e0 ldi r23, 0x00 ; 0 + 2988: 55 d4 rcall .+2218 ; 0x3234 + 298a: 88 23 and r24, r24 + 298c: 09 f4 brne .+2 ; 0x2990 + * sending the data to be written. Decrypt the data first and + * check for CRC. Then write the data when ReadOnly mode is not + * activated. */ + + /* We receive 16 bytes of data to be written and 2 bytes CRCA. Decrypt */ + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + 298e: ef c1 rjmp .+990 ; 0x2d6e + 2990: 80 91 0c 21 lds r24, 0x210C + 2994: 88 23 and r24, r24 + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + 2996: 09 f4 brne .+2 ; 0x299a + 2998: f0 c1 rjmp .+992 ; 0x2d7a + 299a: 7b d7 rcall .+3830 ; 0x3892 + 299c: 9a e0 ldi r25, 0x0A ; 10 + 299e: 98 27 eor r25, r24 + 29a0: f7 01 movw r30, r14 + 29a2: 90 83 st Z, r25 + 29a4: bd cf rjmp .-134 ; 0x2920 + if (!ActiveConfiguration.ReadOnly) { + 29a6: 20 91 c6 20 lds r18, 0x20C6 + 29aa: 90 91 c7 20 lds r25, 0x20C7 + 29ae: d7 01 movw r26, r14 + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + } else { + /* Silently ignore in ReadOnly mode */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 29b0: 8c 91 ld r24, X + 29b2: 86 32 cpi r24, 0x26 ; 38 + 29b4: 09 f4 brne .+2 ; 0x29b8 + 29b6: c5 c0 rjmp .+394 ; 0x2b42 + 29b8: 82 35 cpi r24, 0x52 ; 82 + 29ba: 09 f4 brne .+2 ; 0x29be + 29bc: c2 c0 rjmp .+388 ; 0x2b42 + return BitCount; + } + break; + + case STATE_READY: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + 29be: 83 39 cpi r24, 0x93 ; 147 + 29c0: 09 f4 brne .+2 ; 0x29c4 + 29c2: 35 c2 rjmp .+1130 ; 0x2e2e + 29c4: 10 92 c5 20 sts 0x20C5, r1 + 29c8: 80 e0 ldi r24, 0x00 ; 0 + 29ca: 90 e0 ldi r25, 0x00 ; 0 + 29cc: ae cf rjmp .-164 ; 0x292a + 29ce: c7 01 movw r24, r14 + 29d0: e0 d6 rcall .+3520 ; 0x3792 + 29d2: d7 01 movw r26, r14 + 29d4: 14 96 adiw r26, 0x04 ; 4 + State = STATE_READY; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { + 29d6: 0c 91 ld r16, X + 29d8: 1b d7 rcall .+3638 ; 0x3810 + 29da: 80 27 eor r24, r16 + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + /* According to ISO14443, we must not send anything + * in order to acknowledge the HALT command. */ + State = STATE_HALT; + 29dc: f7 01 movw r30, r14 + 29de: 84 83 std Z+4, r24 ; 0x04 + return ISO14443A_APP_NO_RESPONSE; + 29e0: 05 81 ldd r16, Z+5 ; 0x05 + 29e2: 16 d7 rcall .+3628 ; 0x3810 + 29e4: 80 27 eor r24, r16 + + case STATE_AUTHING: + /* Reader delivers an encrypted nonce. We use it + * to setup the crypto1 LFSR in nonlinear feedback mode. + * Furthermore it delivers an encrypted answer. Decrypt and check it */ + Crypto1Auth(&Buffer[0]); + 29e6: d7 01 movw r26, r14 + 29e8: 15 96 adiw r26, 0x05 ; 5 + 29ea: 8c 93 st X, r24 + + for (uint8_t i=0; i<4; i++) + Buffer[i+4] ^= Crypto1Byte(); + 29ec: 15 97 sbiw r26, 0x05 ; 5 + 29ee: 16 96 adiw r26, 0x06 ; 6 + 29f0: 0c 91 ld r16, X + 29f2: 0e d7 rcall .+3612 ; 0x3810 + 29f4: 80 27 eor r24, r16 + 29f6: f7 01 movw r30, r14 + 29f8: 86 83 std Z+6, r24 ; 0x06 + 29fa: 07 81 ldd r16, Z+7 ; 0x07 + 29fc: 09 d7 rcall .+3602 ; 0x3810 + 29fe: 80 27 eor r24, r16 + 2a00: d7 01 movw r26, r14 + 2a02: 17 96 adiw r26, 0x07 ; 7 + 2a04: 8c 93 st X, r24 + 2a06: 17 97 sbiw r26, 0x07 ; 7 + 2a08: 14 96 adiw r26, 0x04 ; 4 + 2a0a: 2c 91 ld r18, X + 2a0c: 14 97 sbiw r26, 0x04 ; 4 + 2a0e: 90 91 c9 20 lds r25, 0x20C9 + 2a12: 29 17 cp r18, r25 + 2a14: 09 f0 breq .+2 ; 0x2a18 + 2a16: 1e cf rjmp .-452 ; 0x2854 + 2a18: 15 96 adiw r26, 0x05 ; 5 + 2a1a: 2c 91 ld r18, X + 2a1c: 15 97 sbiw r26, 0x05 ; 5 + 2a1e: 90 91 ca 20 lds r25, 0x20CA + 2a22: 29 17 cp r18, r25 + 2a24: 09 f0 breq .+2 ; 0x2a28 + 2a26: 16 cf rjmp .-468 ; 0x2854 + 2a28: 16 96 adiw r26, 0x06 ; 6 + + if ((Buffer[4] == ReaderResponse[0]) && + 2a2a: 2c 91 ld r18, X + 2a2c: 16 97 sbiw r26, 0x06 ; 6 + 2a2e: 90 91 cb 20 lds r25, 0x20CB + 2a32: 29 17 cp r18, r25 + 2a34: 09 f0 breq .+2 ; 0x2a38 + 2a36: 0e cf rjmp .-484 ; 0x2854 + 2a38: 90 91 cc 20 lds r25, 0x20CC + 2a3c: 89 17 cp r24, r25 + 2a3e: 09 f0 breq .+2 ; 0x2a42 + 2a40: 09 cf rjmp .-494 ; 0x2854 + 2a42: 00 91 cd 20 lds r16, 0x20CD + 2a46: e4 d6 rcall .+3528 ; 0x3810 + 2a48: 80 27 eor r24, r16 + (Buffer[5] == ReaderResponse[1]) && + 2a4a: f7 01 movw r30, r14 + 2a4c: 80 83 st Z, r24 + 2a4e: 00 91 cd 20 lds r16, 0x20CD + 2a52: 00 2e mov r0, r16 + 2a54: 02 95 swap r16 + 2a56: 00 25 eor r16, r0 + 2a58: 00 2e mov r0, r16 + (Buffer[6] == ReaderResponse[2]) && + 2a5a: 06 95 lsr r16 + 2a5c: 06 95 lsr r16 + 2a5e: 00 25 eor r16, r0 + 2a60: 9e d4 rcall .+2364 ; 0x339e + 2a62: f7 01 movw r30, r14 + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 2a84: 80 27 eor r24, r16 + 2a86: d7 01 movw r26, r14 + 2a88: 11 96 adiw r26, 0x01 ; 1 + 2a8a: 8c 93 st X, r24 + 2a8c: 00 91 ce 20 lds r16, 0x20CE + 2a90: 00 2e mov r0, r16 + 2a92: 02 95 swap r16 + 2a94: 00 25 eor r16, r0 + 2a96: 00 2e mov r0, r16 + 2a98: 06 95 lsr r16 + 2a9a: 06 95 lsr r16 + 2a9c: 00 25 eor r16, r0 + 2a9e: 7f d4 rcall .+2302 ; 0x339e + 2aa0: f7 01 movw r30, r14 + 2aa2: ef 57 subi r30, 0x7F ; 127 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 2ac2: 80 27 eor r24, r16 + 2ac4: f7 01 movw r30, r14 + 2ac6: 82 83 std Z+2, r24 ; 0x02 + 2ac8: 00 91 cf 20 lds r16, 0x20CF + 2acc: 00 2e mov r0, r16 + 2ace: 02 95 swap r16 + 2ad0: 00 25 eor r16, r0 + 2ad2: 00 2e mov r0, r16 + 2ad4: 06 95 lsr r16 + 2ad6: 06 95 lsr r16 + 2ad8: 00 25 eor r16, r0 + 2ada: 61 d4 rcall .+2242 ; 0x339e + 2adc: f7 01 movw r30, r14 + 2ade: ee 57 subi r30, 0x7E ; 126 + 2ae0: ff 4f sbci r31, 0xFF ; 255 + 2ae2: 20 2f mov r18, r16 + 2ae4: 30 e0 ldi r19, 0x00 ; 0 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 2afe: 80 27 eor r24, r16 + 2b00: d7 01 movw r26, r14 + 2b02: 13 96 adiw r26, 0x03 ; 3 + 2b04: 8c 93 st X, r24 + 2b06: 00 91 d0 20 lds r16, 0x20D0 + 2b0a: 00 2e mov r0, r16 + 2b0c: 02 95 swap r16 + 2b0e: 00 25 eor r16, r0 + 2b10: 00 2e mov r0, r16 + 2b12: 06 95 lsr r16 + 2b14: 06 95 lsr r16 + 2b16: 00 25 eor r16, r0 + 2b18: 42 d4 rcall .+2180 ; 0x339e + 2b1a: f7 01 movw r30, r14 + 2b1c: ed 57 subi r30, 0x7D ; 125 + 2b1e: ff 4f sbci r31, 0xFF ; 255 + 2b20: 20 2f mov r18, r16 + 2b22: 30 e0 ldi r19, 0x00 ; 0 + 2b24: 2f 5f subi r18, 0xFF ; 255 + (Buffer[6] == ReaderResponse[2]) && + (Buffer[7] == ReaderResponse[3])) { + /* Reader is authenticated. Encrypt the precalculated card response + * and generate the parity bits. */ + for (uint8_t i=0; i + 2b42: f7 01 movw r30, r14 + 2b44: 20 83 st Z, r18 + 2b46: 91 83 std Z+1, r25 ; 0x01 + 2b48: 82 e0 ldi r24, 0x02 ; 2 + 2b4a: 80 93 c5 20 sts 0x20C5, r24 + 2b4e: 80 e1 ldi r24, 0x10 ; 16 + 2b50: 90 e0 ldi r25, 0x00 ; 0 + 2b52: eb ce rjmp .-554 ; 0x292a + 2b54: 84 e0 ldi r24, 0x04 ; 4 + 2b56: d7 01 movw r26, r14 + 2b58: 8c 93 st X, r24 + 2b5a: 11 96 adiw r26, 0x01 ; 1 + 2b5c: 1c 92 st X, r1 + 2b5e: 11 97 sbiw r26, 0x01 ; 1 + 2b60: 82 e0 ldi r24, 0x02 ; 2 + 2b62: 80 93 c5 20 sts 0x20C5, r24 + 2b66: 80 e1 ldi r24, 0x10 ; 16 + } + + State = STATE_AUTHED_IDLE; + 2b68: 90 e0 ldi r25, 0x00 ; 0 + 2b6a: df ce rjmp .-578 ; 0x292a + 2b6c: f7 01 movw r30, r14 + + return (CMD_AUTH_BA_FRAME_SIZE * BITS_PER_BYTE) | ISO14443A_APP_CUSTOM_PARITY; + 2b6e: 81 81 ldd r24, Z+1 ; 0x01 + 2b70: 88 23 and r24, r24 + 2b72: 09 f4 brne .+2 ; 0x2b76 + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + 2b74: d7 c2 rjmp .+1454 ; 0x3124 <__stack+0x125> + 2b76: f7 01 movw r30, r14 + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + 2b78: 10 82 st Z, r1 + } + break; + + case STATE_READY: + if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) { + State = STATE_READY; + 2b7a: 84 e0 ldi r24, 0x04 ; 4 + 2b7c: 90 e0 ldi r25, 0x00 ; 0 + 2b7e: d5 ce rjmp .-598 ; 0x292a + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + 2b80: c7 01 movw r24, r14 + 2b82: 62 e0 ldi r22, 0x02 ; 2 + return BitCount; + 2b84: 70 e0 ldi r23, 0x00 ; 0 +bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue) +{ + uint8_t* DataPtr = (uint8_t*) Buffer; + + if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){ + DataPtr[0] = (ATQAValue >> 0) & 0x00FF; + 2b86: 56 d3 rcall .+1708 ; 0x3234 + 2b88: 88 23 and r24, r24 + 2b8a: 09 f4 brne .+2 ; 0x2b8e + DataPtr[1] = (ATQAValue >> 8) & 0x00FF; + 2b8c: 05 c1 rjmp .+522 ; 0x2d98 + 2b8e: d7 01 movw r26, r14 + 2b90: 11 96 adiw r26, 0x01 ; 1 + } + break; + + case STATE_ACTIVE: + if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) { + State = STATE_READY; + 2b92: 0c 91 ld r16, X + 2b94: 11 97 sbiw r26, 0x01 ; 1 + 2b96: 0c 73 andi r16, 0x3C ; 60 + + *BitCount = ISO14443A_ATQA_FRAME_SIZE; + 2b98: 8c 91 ld r24, X + 2b9a: 80 36 cpi r24, 0x60 ; 96 + return BitCount; + 2b9c: 09 f4 brne .+2 ; 0x2ba0 + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + 2b9e: df c2 rjmp .+1470 ; 0x315e <__stack+0x15f> + 2ba0: 8a e3 ldi r24, 0x3A ; 58 + 2ba2: 90 e0 ldi r25, 0x00 ; 0 + 2ba4: 10 e0 ldi r17, 0x00 ; 0 + 2ba6: 02 95 swap r16 + } else { + Buffer[0] = NAK_CRC_ERROR; + return ACK_NAK_FRAME_SIZE; + } + } else { + Buffer[0] = NAK_INVALID_ARG; + 2ba8: 12 95 swap r17 + 2baa: 10 7f andi r17, 0xF0 ; 240 + return ACK_NAK_FRAME_SIZE; + 2bac: 10 27 eor r17, r16 + 2bae: 00 7f andi r16, 0xF0 ; 240 + 2bb0: 10 27 eor r17, r16 + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + + return ACK_NAK_FRAME_SIZE; + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + 2bb2: 08 0f add r16, r24 + 2bb4: 19 1f adc r17, r25 + 2bb6: ce 01 movw r24, r28 + 2bb8: 05 96 adiw r24, 0x05 ; 5 + 2bba: 64 e0 ldi r22, 0x04 ; 4 + 2bbc: 0e 94 eb 04 call 0x9d6 ; 0x9d6 + 2bc0: ce 01 movw r24, r28 + /* Nested authentication. */ + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + 2bc2: 01 96 adiw r24, 0x01 ; 1 + 2bc4: 60 e0 ldi r22, 0x00 ; 0 + 2bc6: 70 e0 ldi r23, 0x00 ; 0 + 2bc8: 44 e0 ldi r20, 0x04 ; 4 + 2bca: 50 e0 ldi r21, 0x00 ; 0 + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 2bcc: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2bd0: ce 01 movw r24, r28 + 2bd2: 09 96 adiw r24, 0x09 ; 9 + 2bd4: b8 01 movw r22, r16 + 2bd6: 46 e0 ldi r20, 0x06 ; 6 + uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; + 2bd8: 50 e0 ldi r21, 0x00 ; 0 + 2bda: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2bde: 8d 81 ldd r24, Y+5 ; 0x05 + 2be0: 80 93 c9 20 sts 0x20C9, r24 + 2be4: 8e 81 ldd r24, Y+6 ; 0x06 + 2be6: 80 93 ca 20 sts 0x20CA, r24 + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + 2bea: 8f 81 ldd r24, Y+7 ; 0x07 + 2bec: 80 93 cb 20 sts 0x20CB, r24 + 2bf0: 88 85 ldd r24, Y+8 ; 0x08 + 2bf2: 80 93 cc 20 sts 0x20CC, r24 + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 2bf6: 89 ec ldi r24, 0xC9 ; 201 + 2bf8: 90 e2 ldi r25, 0x20 ; 32 + 2bfa: 60 e4 ldi r22, 0x40 ; 64 + 2bfc: 70 e0 ldi r23, 0x00 ; 0 + 2bfe: 6d d6 rcall .+3290 ; 0x38da + 2c00: 80 91 c9 20 lds r24, 0x20C9 + MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); + 2c04: 80 93 cd 20 sts 0x20CD, r24 + 2c08: 80 91 ca 20 lds r24, 0x20CA + 2c0c: 80 93 ce 20 sts 0x20CE, r24 + 2c10: 80 91 cb 20 lds r24, 0x20CB + + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; i + + Crypto1PRNG(ReaderResponse, 64); + 2c2a: ce 01 movw r24, r28 + 2c2c: 09 96 adiw r24, 0x09 ; 9 + 2c2e: be 01 movw r22, r28 + 2c30: 6f 5f subi r22, 0xFF ; 255 + 2c32: 7f 4f sbci r23, 0xFF ; 255 + 2c34: ae 01 movw r20, r28 + + /* Precalculate our response from the reader response */ + for (uint8_t i=0; i + 2c3c: 8d 81 ldd r24, Y+5 ; 0x05 + 2c3e: f7 01 movw r30, r14 + 2c40: 80 83 st Z, r24 + 2c42: 8e 81 ldd r24, Y+6 ; 0x06 + 2c44: 81 83 std Z+1, r24 ; 0x01 + 2c46: 8f 81 ldd r24, Y+7 ; 0x07 + 2c48: 82 83 std Z+2, r24 ; 0x02 + 2c4a: 88 85 ldd r24, Y+8 ; 0x08 + 2c4c: 83 83 std Z+3, r24 ; 0x03 + 2c4e: 84 e0 ldi r24, 0x04 ; 4 + 2c50: 80 93 c5 20 sts 0x20C5, r24 + 2c54: 80 e2 ldi r24, 0x20 ; 32 + + Crypto1PRNG(CardResponse, 32); + 2c56: 90 e0 ldi r25, 0x00 ; 0 + 2c58: 68 ce rjmp .-816 ; 0x292a + 2c5a: c7 01 movw r24, r14 + 2c5c: 62 e0 ldi r22, 0x02 ; 2 + 2c5e: 70 e0 ldi r23, 0x00 ; 0 + 2c60: e9 d2 rcall .+1490 ; 0x3234 + + /* Setup crypto1 cipher. */ + Crypto1Setup(Key, Uid, CardNonce); + 2c62: 88 23 and r24, r24 + 2c64: 09 f4 brne .+2 ; 0x2c68 + 2c66: 65 c2 rjmp .+1226 ; 0x3132 <__stack+0x133> + 2c68: d7 01 movw r26, r14 + 2c6a: 11 96 adiw r26, 0x01 ; 1 + 2c6c: 0c 91 ld r16, X + 2c6e: 11 97 sbiw r26, 0x01 ; 1 + 2c70: 0c 73 andi r16, 0x3C ; 60 + 2c72: 8c 91 ld r24, X + 2c74: 80 36 cpi r24, 0x60 ; 96 + + for (uint8_t i=0; i + 2c78: 75 c2 rjmp .+1258 ; 0x3164 <__stack+0x165> + 2c7a: 8a e3 ldi r24, 0x3A ; 58 + 2c7c: 90 e0 ldi r25, 0x00 ; 0 + 2c7e: 10 e0 ldi r17, 0x00 ; 0 + 2c80: 02 95 swap r16 + 2c82: 12 95 swap r17 + 2c84: 10 7f andi r17, 0xF0 ; 240 + 2c86: 10 27 eor r17, r16 + + /* Respond with the encrypted random card nonce and expect further authentication + * form the reader in the next frame. */ + State = STATE_AUTHING; + 2c88: 00 7f andi r16, 0xF0 ; 240 + 2c8a: 10 27 eor r17, r16 + 2c8c: 08 0f add r16, r24 + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + 2c8e: 19 1f adc r17, r25 + 2c90: ce 01 movw r24, r28 + 2c92: 01 96 adiw r24, 0x01 ; 1 + } else { + Buffer[0] = NAK_INVALID_ARG; + return ACK_NAK_FRAME_SIZE; + } + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + 2c94: 64 e0 ldi r22, 0x04 ; 4 + 2c96: 0e 94 eb 04 call 0x9d6 ; 0x9d6 + 2c9a: ce 01 movw r24, r28 + 2c9c: 05 96 adiw r24, 0x05 ; 5 + 2c9e: 60 e0 ldi r22, 0x00 ; 0 + 2ca0: 70 e0 ldi r23, 0x00 ; 0 + 2ca2: 44 e0 ldi r20, 0x04 ; 4 + uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + 2ca4: 50 e0 ldi r21, 0x00 ; 0 + 2ca6: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2caa: ce 01 movw r24, r28 + 2cac: 09 96 adiw r24, 0x09 ; 9 + uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + 2cae: b8 01 movw r22, r16 + 2cb0: 46 e0 ldi r20, 0x06 ; 6 + 2cb2: 50 e0 ldi r21, 0x00 ; 0 + 2cb4: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2cb8: 89 81 ldd r24, Y+1 ; 0x01 + uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset; + 2cba: 80 93 c9 20 sts 0x20C9, r24 + 2cbe: 8a 81 ldd r24, Y+2 ; 0x02 + 2cc0: 80 93 ca 20 sts 0x20CA, r24 + 2cc4: 8b 81 ldd r24, Y+3 ; 0x03 + 2cc6: 80 93 cb 20 sts 0x20CB, r24 + 2cca: 8c 81 ldd r24, Y+4 ; 0x04 + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[4]; + + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + 2ccc: 80 93 cc 20 sts 0x20CC, r24 + 2cd0: 89 ec ldi r24, 0xC9 ; 201 + 2cd2: 90 e2 ldi r25, 0x20 ; 32 + 2cd4: 60 e4 ldi r22, 0x40 ; 64 + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 2cd6: 70 e0 ldi r23, 0x00 ; 0 + 2cd8: 00 d6 rcall .+3072 ; 0x38da + 2cda: 80 91 c9 20 lds r24, 0x20C9 + 2cde: 80 93 cd 20 sts 0x20CD, r24 + 2ce2: 80 91 ca 20 lds r24, 0x20CA + MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE); + 2ce6: 80 93 ce 20 sts 0x20CE, r24 + 2cea: 80 91 cb 20 lds r24, 0x20CB + 2cee: 80 93 cf 20 sts 0x20CF, r24 + 2cf2: 80 91 cc 20 lds r24, 0x20CC + + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; i + 2d04: 84 e0 ldi r24, 0x04 ; 4 + 2d06: 80 93 c5 20 sts 0x20C5, r24 + 2d0a: 89 81 ldd r24, Y+1 ; 0x01 + + Crypto1PRNG(ReaderResponse, 64); + 2d0c: f7 01 movw r30, r14 + 2d0e: 80 83 st Z, r24 + 2d10: 8a 81 ldd r24, Y+2 ; 0x02 + 2d12: 81 83 std Z+1, r24 ; 0x01 + 2d14: 8b 81 ldd r24, Y+3 ; 0x03 + 2d16: 82 83 std Z+2, r24 ; 0x02 + + /* Precalculate our response from the reader response */ + for (uint8_t i=0; i + 2d2e: 80 e2 ldi r24, 0x20 ; 32 + 2d30: 90 e0 ldi r25, 0x00 ; 0 + 2d32: fb cd rjmp .-1034 ; 0x292a + 2d34: 60 91 d1 20 lds r22, 0x20D1 + + Crypto1PRNG(CardResponse, 32); + 2d38: 70 e0 ldi r23, 0x00 ; 0 + 2d3a: 62 95 swap r22 + 2d3c: 72 95 swap r23 + 2d3e: 70 7f andi r23, 0xF0 ; 240 + 2d40: 76 27 eor r23, r22 + 2d42: 60 7f andi r22, 0xF0 ; 240 + + /* Respond with the random card nonce and expect further authentication + * form the reader in the next frame. */ + State = STATE_AUTHING; + 2d44: 76 27 eor r23, r22 + 2d46: 82 ed ldi r24, 0xD2 ; 210 + 2d48: 90 e2 ldi r25, 0x20 ; 32 + + for (uint8_t i=0; i + 2d52: 20 91 d2 20 lds r18, 0x20D2 + 2d56: 80 91 d6 20 lds r24, 0x20D6 + 2d5a: 80 95 com r24 + + /* Setup crypto1 cipher. Discard in-place encrypted CardNonce. */ + Crypto1Setup(Key, Uid, CardNonce); + 2d5c: 28 17 cp r18, r24 + 2d5e: 09 f4 brne .+2 ; 0x2d62 + 2d60: d6 c0 rjmp .+428 ; 0x2f0e + 2d62: 97 d5 rcall .+2862 ; 0x3892 + 2d64: 96 e0 ldi r25, 0x06 ; 6 + 2d66: 98 27 eor r25, r24 + 2d68: d7 01 movw r26, r14 + 2d6a: 9c 93 st X, r25 + 2d6c: d9 cd rjmp .-1102 ; 0x2920 + 2d6e: 91 d5 rcall .+2850 ; 0x3892 + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + 2d70: 91 e0 ldi r25, 0x01 ; 1 + 2d72: 98 27 eor r25, r24 + 2d74: d7 01 movw r26, r14 + * the block back into the global block buffer. */ + for (uint8_t i=0; i<(MEM_VALUE_SIZE + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_VALUE_SIZE )) { + MemoryReadBlock(BlockBuffer, (uint16_t) CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 2d76: 9c 93 st X, r25 + 2d78: d3 cd rjmp .-1114 ; 0x2920 + 2d7a: 60 91 d1 20 lds r22, 0x20D1 + 2d7e: 70 e0 ldi r23, 0x00 ; 0 + 2d80: 62 95 swap r22 + 2d82: 72 95 swap r23 + 2d84: 70 7f andi r23, 0xF0 ; 240 + 2d86: 76 27 eor r23, r22 + 2d88: 60 7f andi r22, 0xF0 ; 240 + 2d8a: 76 27 eor r23, r22 + 2d8c: c7 01 movw r24, r14 + 2d8e: 40 e1 ldi r20, 0x10 ; 16 + 2d90: 50 e0 ldi r21, 0x00 ; 0 + 2d92: 0e 94 a8 06 call 0xd50 ; 0xd50 + +INLINE bool CheckValueIntegrity(uint8_t* Block) +{ + /* Value Blocks contain a value stored three times, with + * the middle portion inverted. */ + if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) + 2d96: 01 ce rjmp .-1022 ; 0x299a + 2d98: 7c d5 rcall .+2808 ; 0x3892 + 2d9a: 91 e0 ldi r25, 0x01 ; 1 + 2d9c: 98 27 eor r25, r24 + 2d9e: d7 01 movw r26, r14 + 2da0: 9c 93 st X, r25 + 2da2: 84 e0 ldi r24, 0x04 ; 4 + State = STATE_AUTHED_IDLE; + /* No ACK response on value commands part 2 */ + return ISO14443A_APP_NO_RESPONSE; + } else { + /* Not sure if this is the correct error code.. */ + Buffer[0] = NAK_OTHER_ERROR ^ Crypto1Nibble(); + 2da4: 90 e0 ldi r25, 0x00 ; 0 + 2da6: c1 cd rjmp .-1150 ; 0x292a + 2da8: c7 01 movw r24, r14 + 2daa: 62 e0 ldi r22, 0x02 ; 2 + 2dac: 70 e0 ldi r23, 0x00 ; 0 + 2dae: 42 d2 rcall .+1156 ; 0x3234 + 2db0: 88 23 and r24, r24 + /* Silently ignore in ReadOnly mode */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 2db2: 91 f3 breq .-28 ; 0x2d98 + 2db4: d7 01 movw r26, r14 + 2db6: 11 96 adiw r26, 0x01 ; 1 + 2db8: 6c 91 ld r22, X + 2dba: 70 e0 ldi r23, 0x00 ; 0 + 2dbc: 62 95 swap r22 + 2dbe: 72 95 swap r23 + for (uint8_t i=0; i<(MEM_BYTES_PER_BLOCK + ISO14443A_CRCA_SIZE); i++) + Buffer[i] ^= Crypto1Byte(); + + if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) { + if (!ActiveConfiguration.ReadOnly) { + MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 2dc0: 70 7f andi r23, 0xF0 ; 240 + 2dc2: 76 27 eor r23, r22 + 2dc4: 60 7f andi r22, 0xF0 ; 240 + 2dc6: 76 27 eor r23, r22 + 2dc8: c7 01 movw r24, r14 + 2dca: 40 e1 ldi r20, 0x10 ; 16 + 2dcc: 50 e0 ldi r21, 0x00 ; 0 + 2dce: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2dd2: c7 01 movw r24, r14 + 2dd4: 60 e1 ldi r22, 0x10 ; 16 + 2dd6: 70 e0 ldi r23, 0x00 ; 0 + 2dd8: ef d1 rcall .+990 ; 0x31b8 + 2dda: 87 01 movw r16, r14 + 2ddc: 30 e8 ldi r19, 0x80 ; 128 + * form the reader in the next frame. */ + State = STATE_AUTHING; + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 2dde: e3 2e mov r14, r19 + 2de0: f1 2c mov r15, r1 + 2de2: e0 0e add r14, r16 + 2de4: f1 1e adc r15, r17 + 2de6: 88 24 eor r8, r8 + 2de8: f8 01 movw r30, r16 + return ACK_NAK_FRAME_SIZE; + 2dea: c0 80 ld r12, Z + 2dec: 11 d5 rcall .+2594 ; 0x3810 + 2dee: 8c 25 eor r24, r12 + * the incoming data. */ + for (uint8_t i=0; i<4; i++) + Buffer[i] ^= Crypto1Byte(); + + if (Buffer[0] == CMD_READ) { + if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) { + 2df0: d8 01 movw r26, r16 + 2df2: 8d 93 st X+, r24 + 2df4: 8d 01 movw r16, r26 + 2df6: 0c 2c mov r0, r12 + 2df8: c2 94 swap r12 + 2dfa: c0 24 eor r12, r0 + 2dfc: 0c 2c mov r0, r12 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + 2dfe: c6 94 lsr r12 + 2e00: c6 94 lsr r12 + 2e02: c0 24 eor r12, r0 + 2e04: cc d2 rcall .+1432 ; 0x339e + 2e06: 2c 2d mov r18, r12 + 2e08: 30 e0 ldi r19, 0x00 ; 0 + 2e0a: 2f 5f subi r18, 0xFF ; 255 + 2e0c: 3f 4f sbci r19, 0xFF ; 255 + 2e0e: 35 95 asr r19 + 2e10: 27 95 ror r18 + 2e12: 91 e0 ldi r25, 0x01 ; 1 + 2e14: 20 fd sbrc r18, 0 + 2e16: 90 e0 ldi r25, 0x00 ; 0 + 2e18: 98 27 eor r25, r24 + 2e1a: f7 01 movw r30, r14 + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + 2e1c: 91 93 st Z+, r25 + 2e1e: 7f 01 movw r14, r30 + 2e20: 83 94 inc r8 + 2e22: f2 e1 ldi r31, 0x12 ; 18 + 2e24: 8f 16 cp r8, r31 + 2e26: 01 f7 brne .-64 ; 0x2de8 +void MifareClassicAppTask(void) +{ + +} + +uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) + 2e28: 80 e9 ldi r24, 0x90 ; 144 + 2e2a: 90 e1 ldi r25, 0x10 ; 16 + 2e2c: 7e cd rjmp .-1284 ; 0x292a + 2e2e: ce 01 movw r24, r28 + 2e30: 05 96 adiw r24, 0x05 ; 5 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + + /* Encrypt and calculate parity bits. */ + for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { + 2e32: 60 e0 ldi r22, 0x00 ; 0 + uint8_t Plain = Buffer[i]; + 2e34: 70 e0 ldi r23, 0x00 ; 0 + 2e36: 44 e0 ldi r20, 0x04 ; 4 + Buffer[i] = Plain ^ Crypto1Byte(); + 2e38: 50 e0 ldi r21, 0x00 ; 0 + 2e3a: 0e 94 1d 06 call 0xc3a ; 0xc3a + 2e3e: 90 91 c8 20 lds r25, 0x20C8 + 2e42: d7 01 movw r26, r14 + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); + 2e44: 11 96 adiw r26, 0x01 ; 1 + 2e46: 8c 91 ld r24, X + 2e48: 11 97 sbiw r26, 0x01 ; 1 + 2e4a: 80 32 cpi r24, 0x20 ; 32 + 2e4c: 09 f4 brne .+2 ; 0x2e50 + 2e4e: 77 c1 rjmp .+750 ; 0x313e <__stack+0x13f> + 2e50: 80 37 cpi r24, 0x70 ; 112 + 2e52: 09 f0 breq .+2 ; 0x2e56 + 2e54: 86 cd rjmp .-1268 ; 0x2962 + 2e56: d7 01 movw r26, r14 + 2e58: 12 96 adiw r26, 0x02 ; 2 + 2e5a: 2c 91 ld r18, X + 2e5c: 12 97 sbiw r26, 0x02 ; 2 + 2e5e: 8d 81 ldd r24, Y+5 ; 0x05 + 2e60: 28 17 cp r18, r24 + 2e62: 09 f0 breq .+2 ; 0x2e66 + 2e64: 7e cd rjmp .-1284 ; 0x2962 + 2e66: 13 96 adiw r26, 0x03 ; 3 + 2e68: 2c 91 ld r18, X + 2e6a: 13 97 sbiw r26, 0x03 ; 3 + 2e6c: 8e 81 ldd r24, Y+6 ; 0x06 + 2e6e: 28 17 cp r18, r24 + /* Read command. Read data from memory and append CRCA. */ + MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK); + ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK); + + /* Encrypt and calculate parity bits. */ + for (uint8_t i=0; i<(ISO14443A_CRCA_SIZE + MEM_BYTES_PER_BLOCK); i++) { + 2e70: 09 f0 breq .+2 ; 0x2e74 + 2e72: 77 cd rjmp .-1298 ; 0x2962 + 2e74: 14 96 adiw r26, 0x04 ; 4 + 2e76: 2c 91 ld r18, X + uint8_t Plain = Buffer[i]; + Buffer[i] = Plain ^ Crypto1Byte(); + Buffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = ODD_PARITY(Plain) ^ Crypto1FilterOutput(); + } + + return ( (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE ) + 2e78: 14 97 sbiw r26, 0x04 ; 4 + 2e7a: 8f 81 ldd r24, Y+7 ; 0x07 + 2e7c: 28 17 cp r18, r24 + State = STATE_READY; + return BitCount; + } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) { + /* Load UID CL1 and perform anticollision */ + uint8_t UidCL1[4]; + MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + 2e7e: 09 f0 breq .+2 ; 0x2e82 + 2e80: 70 cd rjmp .-1312 ; 0x2962 + 2e82: 15 96 adiw r26, 0x05 ; 5 + 2e84: 2c 91 ld r18, X + 2e86: 15 97 sbiw r26, 0x05 ; 5 + 2e88: 88 85 ldd r24, Y+8 ; 0x08 + 2e8a: 28 17 cp r18, r24 + 2e8c: 09 f0 breq .+2 ; 0x2e90 + + if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) { + 2e8e: 69 cd rjmp .-1326 ; 0x2962 + 2e90: 9c 93 st X, r25 + uint8_t* DataPtr = (uint8_t*) Buffer; + uint8_t NVB = DataPtr[1]; + //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F; + //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F; + + switch (NVB) { + 2e92: c7 01 movw r24, r14 + 2e94: 61 e0 ldi r22, 0x01 ; 1 + 2e96: 70 e0 ldi r23, 0x00 ; 0 + 2e98: 8f d1 rcall .+798 ; 0x31b8 + 2e9a: 83 e0 ldi r24, 0x03 ; 3 + 2e9c: 80 93 c5 20 sts 0x20C5, r24 + 2ea0: 88 e1 ldi r24, 0x18 ; 24 + 2ea2: 90 e0 ldi r25, 0x00 ; 0 + 2ea4: 42 cd rjmp .-1404 ; 0x292a + return false; + + case ISO14443A_NVB_AC_END: + /* End of anticollision procedure. + * Send SAK CLn if we are selected. */ + if ( (DataPtr[2] == UidCL[0]) && + 2ea6: c7 01 movw r24, r14 + 2ea8: 62 e0 ldi r22, 0x02 ; 2 + 2eaa: 70 e0 ldi r23, 0x00 ; 0 + 2eac: c3 d1 rcall .+902 ; 0x3234 + 2eae: 88 23 and r24, r24 + 2eb0: 79 f0 breq .+30 ; 0x2ed0 + 2eb2: f7 01 movw r30, r14 + 2eb4: 81 81 ldd r24, Z+1 ; 0x01 + 2eb6: 80 93 d1 20 sts 0x20D1, r24 + 2eba: 86 e0 ldi r24, 0x06 ; 6 + 2ebc: 80 93 c5 20 sts 0x20C5, r24 + 2ec0: e8 d4 rcall .+2512 ; 0x3892 + 2ec2: 9a e0 ldi r25, 0x0A ; 10 + (DataPtr[3] == UidCL[1]) && + 2ec4: 98 27 eor r25, r24 + 2ec6: d7 01 movw r26, r14 + 2ec8: 9c 93 st X, r25 + 2eca: 84 e0 ldi r24, 0x04 ; 4 + 2ecc: 90 e0 ldi r25, 0x00 ; 0 + 2ece: 2d cd rjmp .-1446 ; 0x292a + 2ed0: e0 d4 rcall .+2496 ; 0x3892 + (DataPtr[4] == UidCL[2]) && + 2ed2: 91 e0 ldi r25, 0x01 ; 1 + 2ed4: 98 27 eor r25, r24 + 2ed6: f7 01 movw r30, r14 + 2ed8: 90 83 st Z, r25 + 2eda: 84 e0 ldi r24, 0x04 ; 4 + 2edc: 90 e0 ldi r25, 0x00 ; 0 + 2ede: 25 cd rjmp .-1462 ; 0x292a + (DataPtr[5] == UidCL[3]) ) { + + DataPtr[0] = SAKValue; + 2ee0: c7 01 movw r24, r14 + ISO14443AAppendCRCA(Buffer, 1); + 2ee2: 62 e0 ldi r22, 0x02 ; 2 + 2ee4: 70 e0 ldi r23, 0x00 ; 0 + 2ee6: a6 d1 rcall .+844 ; 0x3234 + 2ee8: 88 23 and r24, r24 + 2eea: 09 f4 brne .+2 ; 0x2eee + State = STATE_ACTIVE; + 2eec: 55 cf rjmp .-342 ; 0x2d98 + 2eee: d7 01 movw r26, r14 + 2ef0: 11 96 adiw r26, 0x01 ; 1 + + *BitCount = ISO14443A_SAK_FRAME_SIZE; + 2ef2: 8c 91 ld r24, X + 2ef4: 80 93 d1 20 sts 0x20D1, r24 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + return ACK_NAK_FRAME_SIZE; + } + } else if (Buffer[0] == CMD_WRITE) { + if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) { + 2ef8: 88 e0 ldi r24, 0x08 ; 8 + 2efa: 80 93 c5 20 sts 0x20C5, r24 + 2efe: c9 d4 rcall .+2450 ; 0x3892 + 2f00: 9a e0 ldi r25, 0x0A ; 10 + 2f02: 98 27 eor r25, r24 + 2f04: f7 01 movw r30, r14 + /* Write command. Store the address and prepare for the upcoming data. + * Respond with ACK. */ + CurrentAddress = Buffer[1]; + 2f06: 90 83 st Z, r25 + 2f08: 84 e0 ldi r24, 0x04 ; 4 + 2f0a: 90 e0 ldi r25, 0x00 ; 0 + 2f0c: 0e cd rjmp .-1508 ; 0x292a + State = STATE_WRITE; + 2f0e: 80 91 da 20 lds r24, 0x20DA + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_INCREMENT) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + CurrentAddress = Buffer[1]; + State = STATE_INCREMENT; + 2f12: 28 17 cp r18, r24 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 2f14: 09 f0 breq .+2 ; 0x2f18 + 2f16: 25 cf rjmp .-438 ; 0x2d62 + 2f18: 30 91 d3 20 lds r19, 0x20D3 + 2f1c: 80 91 d7 20 lds r24, 0x20D7 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + 2f20: 80 95 com r24 + 2f22: 38 17 cp r19, r24 + 2f24: 09 f0 breq .+2 ; 0x2f28 + /* In read only mode, silently ignore the write */ + } + + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + 2f26: 1d cf rjmp .-454 ; 0x2d62 + 2f28: 80 91 db 20 lds r24, 0x20DB + 2f2c: 38 17 cp r19, r24 + 2f2e: 09 f0 breq .+2 ; 0x2f32 + 2f30: 18 cf rjmp .-464 ; 0x2d62 + } + + return ACK_NAK_FRAME_SIZE; + 2f32: 40 91 d4 20 lds r20, 0x20D4 + 2f36: 80 91 d8 20 lds r24, 0x20D8 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_DECREMENT) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 2f3a: 80 95 com r24 + 2f3c: 48 17 cp r20, r24 + 2f3e: 09 f0 breq .+2 ; 0x2f42 + 2f40: 10 cf rjmp .-480 ; 0x2d62 + 2f42: 80 91 dc 20 lds r24, 0x20DC + 2f46: 48 17 cp r20, r24 + CurrentAddress = Buffer[1]; + 2f48: 09 f0 breq .+2 ; 0x2f4c + 2f4a: 0b cf rjmp .-490 ; 0x2d62 + 2f4c: e0 91 d5 20 lds r30, 0x20D5 + 2f50: 80 91 d9 20 lds r24, 0x20D9 + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_RESTORE) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + CurrentAddress = Buffer[1]; + State = STATE_RESTORE; + 2f54: 80 95 com r24 + 2f56: e8 17 cp r30, r24 + Buffer[0] = ACK_VALUE ^ Crypto1Nibble(); + 2f58: 09 f0 breq .+2 ; 0x2f5c + 2f5a: 03 cf rjmp .-506 ; 0x2d62 + 2f5c: 80 91 dd 20 lds r24, 0x20DD + 2f60: e8 17 cp r30, r24 + 2f62: 09 f0 breq .+2 ; 0x2f66 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + 2f64: fe ce rjmp .-516 ; 0x2d62 + 2f66: 90 91 de 20 lds r25, 0x20DE + +INLINE bool CheckValueIntegrity(uint8_t* Block) +{ + /* Value Blocks contain a value stored three times, with + * the middle portion inverted. */ + if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8]) + 2f6a: 80 91 df 20 lds r24, 0x20DF + 2f6e: 80 95 com r24 + 2f70: 98 17 cp r25, r24 + 2f72: 09 f0 breq .+2 ; 0x2f76 + && (Block[1] == (uint8_t) ~Block[5]) && (Block[1] == Block[9]) + 2f74: f6 ce rjmp .-532 ; 0x2d62 + 2f76: 80 91 e0 20 lds r24, 0x20E0 + 2f7a: 98 17 cp r25, r24 + 2f7c: 09 f0 breq .+2 ; 0x2f80 + 2f7e: f1 ce rjmp .-542 ; 0x2d62 + 2f80: 80 91 e1 20 lds r24, 0x20E1 + 2f84: 80 95 com r24 + 2f86: 98 17 cp r25, r24 + 2f88: 09 f0 breq .+2 ; 0x2f8c + 2f8a: eb ce rjmp .-554 ; 0x2d62 + 2f8c: d7 01 movw r26, r14 + && (Block[2] == (uint8_t) ~Block[6]) && (Block[2] == Block[10]) + 2f8e: 11 96 adiw r26, 0x01 ; 1 + 2f90: 8c 90 ld r8, X + 2f92: 11 97 sbiw r26, 0x01 ; 1 + 2f94: 99 24 eor r9, r9 + 2f96: aa 24 eor r10, r10 + 2f98: bb 24 eor r11, r11 + 2f9a: ba 2c mov r11, r10 + 2f9c: a9 2c mov r10, r9 + 2f9e: 98 2c mov r9, r8 + 2fa0: 88 24 eor r8, r8 + 2fa2: 12 96 adiw r26, 0x02 ; 2 + 2fa4: 8c 91 ld r24, X + 2fa6: 90 e0 ldi r25, 0x00 ; 0 + && (Block[3] == (uint8_t) ~Block[7]) && (Block[3] == Block[11]) + 2fa8: a0 e0 ldi r26, 0x00 ; 0 + 2faa: b0 e0 ldi r27, 0x00 ; 0 + 2fac: dc 01 movw r26, r24 + 2fae: 99 27 eor r25, r25 + 2fb0: 88 27 eor r24, r24 + 2fb2: 88 2a or r8, r24 + 2fb4: 99 2a or r9, r25 + 2fb6: aa 2a or r10, r26 + 2fb8: bb 2a or r11, r27 + 2fba: d7 01 movw r26, r14 + 2fbc: 8c 91 ld r24, X + 2fbe: 90 e0 ldi r25, 0x00 ; 0 + 2fc0: a0 e0 ldi r26, 0x00 ; 0 + && (Block[12] == (uint8_t) ~Block[13]) + 2fc2: b0 e0 ldi r27, 0x00 ; 0 + 2fc4: 88 2a or r8, r24 + 2fc6: 99 2a or r9, r25 + 2fc8: aa 2a or r10, r26 + 2fca: bb 2a or r11, r27 + 2fcc: d7 01 movw r26, r14 + 2fce: 13 96 adiw r26, 0x03 ; 3 + 2fd0: cc 90 ld r12, X + && (Block[12] == Block[14]) + 2fd2: dd 24 eor r13, r13 + 2fd4: ee 24 eor r14, r14 + 2fd6: ff 24 eor r15, r15 + 2fd8: fc 2c mov r15, r12 + 2fda: ee 24 eor r14, r14 + && (Block[14] == (uint8_t) ~Block[15])) { + 2fdc: dd 24 eor r13, r13 + 2fde: cc 24 eor r12, r12 + 2fe0: 8c 28 or r8, r12 + 2fe2: 9d 28 or r9, r13 + 2fe4: ae 28 or r10, r14 + 2fe6: bf 28 or r11, r15 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 2fe8: 83 2f mov r24, r19 + 2fea: 90 e0 ldi r25, 0x00 ; 0 + 2fec: a0 e0 ldi r26, 0x00 ; 0 + 2fee: b0 e0 ldi r27, 0x00 ; 0 + 2ff0: ba 2f mov r27, r26 + 2ff2: a9 2f mov r26, r25 + 2ff4: 98 2f mov r25, r24 + 2ff6: 88 27 eor r24, r24 + 2ff8: 50 e0 ldi r21, 0x00 ; 0 + 2ffa: 60 e0 ldi r22, 0x00 ; 0 + 2ffc: 70 e0 ldi r23, 0x00 ; 0 + *Value |= ((uint32_t) Block[2] << 16); + 2ffe: ba 01 movw r22, r20 + 3000: 55 27 eor r21, r21 + 3002: 44 27 eor r20, r20 + 3004: 84 2b or r24, r20 + 3006: 95 2b or r25, r21 + 3008: a6 2b or r26, r22 + 300a: b7 2b or r27, r23 + 300c: 30 e0 ldi r19, 0x00 ; 0 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 300e: 40 e0 ldi r20, 0x00 ; 0 + 3010: 50 e0 ldi r21, 0x00 ; 0 + 3012: 82 2b or r24, r18 + 3014: 93 2b or r25, r19 +} + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + 3016: a4 2b or r26, r20 + 3018: b5 2b or r27, r21 + 301a: 4e 2f mov r20, r30 + 301c: 50 e0 ldi r21, 0x00 ; 0 + 301e: 60 e0 ldi r22, 0x00 ; 0 + *Value |= ((uint32_t) Block[1] << 8); + *Value |= ((uint32_t) Block[2] << 16); + 3020: 70 e0 ldi r23, 0x00 ; 0 + 3022: 74 2f mov r23, r20 + 3024: 66 27 eor r22, r22 + 3026: 55 27 eor r21, r21 + *Value |= ((uint32_t) Block[3] << 24); + 3028: 44 27 eor r20, r20 + 302a: 84 2b or r24, r20 + 302c: 95 2b or r25, r21 + 302e: a6 2b or r26, r22 + 3030: b7 2b or r27, r23 + 3032: 20 91 c5 20 lds r18, 0x20C5 + 3036: 28 30 cpi r18, 0x08 ; 8 + 3038: 09 f4 brne .+2 ; 0x303c <__stack+0x3d> + 303a: 6f c0 rjmp .+222 ; 0x311a <__stack+0x11b> + 303c: 27 30 cpi r18, 0x07 ; 7 + 303e: 21 f4 brne .+8 ; 0x3048 <__stack+0x49> + 3040: 88 0d add r24, r8 + 3042: 99 1d adc r25, r9 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 3044: aa 1d adc r26, r10 + 3046: bb 1d adc r27, r11 + 3048: 80 93 d2 20 sts 0x20D2, r24 + 304c: 09 2f mov r16, r25 + 304e: 1a 2f mov r17, r26 + 3050: 2b 2f mov r18, r27 + 3052: 33 27 eor r19, r19 + *Value |= ((uint32_t) Block[2] << 16); + 3054: 00 93 d3 20 sts 0x20D3, r16 + 3058: ad 01 movw r20, r26 + 305a: 66 27 eor r22, r22 + 305c: 77 27 eor r23, r23 + 305e: 40 93 d4 20 sts 0x20D4, r20 + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + *Value |= ((uint32_t) Block[1] << 8); + 3062: cb 2e mov r12, r27 + 3064: dd 24 eor r13, r13 + 3066: ee 24 eor r14, r14 +} + +INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block) +{ + *Value = 0; + *Value |= ((uint32_t) Block[0] << 0); + 3068: ff 24 eor r15, r15 + 306a: c0 92 d5 20 sts 0x20D5, r12 + *Value |= ((uint32_t) Block[1] << 8); + *Value |= ((uint32_t) Block[2] << 16); + 306e: e8 2f mov r30, r24 + 3070: e0 95 com r30 + 3072: e0 93 d6 20 sts 0x20D6, r30 + *Value |= ((uint32_t) Block[3] << 24); + 3076: e0 2f mov r30, r16 + 3078: e0 95 com r30 + 307a: e0 93 d7 20 sts 0x20D7, r30 + 307e: e4 2f mov r30, r20 + 3080: e0 95 com r30 + 3082: e0 93 d8 20 sts 0x20D8, r30 + 3086: ec 2d mov r30, r12 + 3088: e0 95 com r30 + 308a: e0 93 d9 20 sts 0x20D9, r30 + uint32_t BlockValue; + + ValueFromBlock(&ParamValue, Buffer); + ValueFromBlock(&BlockValue, BlockBuffer); + + if (State == STATE_DECREMENT) { + 308e: 80 93 da 20 sts 0x20DA, r24 + 3092: 00 93 db 20 sts 0x20DB, r16 + 3096: 40 93 dc 20 sts 0x20DC, r20 + BlockValue -= ParamValue; + } else if (State == STATE_INCREMENT) { + 309a: c0 92 dd 20 sts 0x20DD, r12 + BlockValue += ParamValue; + 309e: 85 e0 ldi r24, 0x05 ; 5 + 30a0: 80 93 c5 20 sts 0x20C5, r24 + *Value |= ((uint32_t) Block[3] << 24); +} + +INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) +{ + Block[0] = (uint8_t) (Value >> 0); + 30a4: 80 e0 ldi r24, 0x00 ; 0 + 30a6: 90 e0 ldi r25, 0x00 ; 0 + Block[1] = (uint8_t) (Value >> 8); + 30a8: 40 cc rjmp .-1920 ; 0x292a + 30aa: c7 01 movw r24, r14 + 30ac: 62 e0 ldi r22, 0x02 ; 2 + 30ae: 70 e0 ldi r23, 0x00 ; 0 + 30b0: c1 d0 rcall .+386 ; 0x3234 + 30b2: 88 23 and r24, r24 + Block[2] = (uint8_t) (Value >> 16); + 30b4: 09 f4 brne .+2 ; 0x30b8 <__stack+0xb9> + 30b6: 0c cf rjmp .-488 ; 0x2ed0 + 30b8: f7 01 movw r30, r14 + 30ba: 81 81 ldd r24, Z+1 ; 0x01 + 30bc: 80 93 d1 20 sts 0x20D1, r24 + Block[3] = (uint8_t) (Value >> 24); + 30c0: 87 e0 ldi r24, 0x07 ; 7 + 30c2: fc ce rjmp .-520 ; 0x2ebc + 30c4: c7 01 movw r24, r14 + 30c6: 62 e0 ldi r22, 0x02 ; 2 + 30c8: 70 e0 ldi r23, 0x00 ; 0 + Block[4] = ~Block[0]; + 30ca: b4 d0 rcall .+360 ; 0x3234 + 30cc: 88 23 and r24, r24 + 30ce: 09 f4 brne .+2 ; 0x30d2 <__stack+0xd3> + 30d0: 63 ce rjmp .-826 ; 0x2d98 + Block[5] = ~Block[1]; + 30d2: d7 01 movw r26, r14 + 30d4: 11 96 adiw r26, 0x01 ; 1 + 30d6: 8c 91 ld r24, X + 30d8: 11 97 sbiw r26, 0x01 ; 1 + Block[6] = ~Block[2]; + 30da: 80 93 d1 20 sts 0x20D1, r24 + 30de: 89 e0 ldi r24, 0x09 ; 9 + 30e0: 0c cf rjmp .-488 ; 0x2efa + Block[7] = ~Block[3]; + 30e2: c7 01 movw r24, r14 + 30e4: 62 e0 ldi r22, 0x02 ; 2 + 30e6: 70 e0 ldi r23, 0x00 ; 0 + 30e8: a5 d0 rcall .+330 ; 0x3234 + Block[8] = Block[0]; + 30ea: 88 23 and r24, r24 + 30ec: 09 f4 brne .+2 ; 0x30f0 <__stack+0xf1> + Block[9] = Block[1]; + 30ee: f0 ce rjmp .-544 ; 0x2ed0 + 30f0: 80 91 0c 21 lds r24, 0x210C + Block[10] = Block[2]; + 30f4: 88 23 and r24, r24 + Block[11] = Block[3]; + 30f6: 09 f0 breq .+2 ; 0x30fa <__stack+0xfb> + 30f8: e3 ce rjmp .-570 ; 0x2ec0 + /* Do nothing */ + } + + ValueToBlock(BlockBuffer, BlockValue); + + State = STATE_AUTHED_IDLE; + 30fa: f7 01 movw r30, r14 + 30fc: 61 81 ldd r22, Z+1 ; 0x01 + 30fe: 70 e0 ldi r23, 0x00 ; 0 + /* No ACK response on value commands part 2 */ + return ISO14443A_APP_NO_RESPONSE; + 3100: 62 95 swap r22 + 3102: 72 95 swap r23 + 3104: 70 7f andi r23, 0xF0 ; 240 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_INCREMENT) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 3106: 76 27 eor r23, r22 + 3108: 60 7f andi r22, 0xF0 ; 240 + 310a: 76 27 eor r23, r22 + 310c: 82 ed ldi r24, 0xD2 ; 210 + 310e: 90 e2 ldi r25, 0x20 ; 32 + 3110: 40 e1 ldi r20, 0x10 ; 16 + 3112: 50 e0 ldi r21, 0x00 ; 0 + 3114: 0e 94 a8 06 call 0xd50 ; 0xd50 + CurrentAddress = Buffer[1]; + 3118: d3 ce rjmp .-602 ; 0x2ec0 + 311a: 88 19 sub r24, r8 + 311c: 99 09 sbc r25, r9 + State = STATE_INCREMENT; + 311e: aa 09 sbc r26, r10 + 3120: bb 09 sbc r27, r11 + } else { + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + } else if (Buffer[0] == CMD_RESTORE) { + if (ISO14443ACheckCRCA(Buffer, CMD_DECREMENT_FRAME_SIZE)) { + 3122: 92 cf rjmp .-220 ; 0x3048 <__stack+0x49> + 3124: c7 01 movw r24, r14 + 3126: 62 e0 ldi r22, 0x02 ; 2 + 3128: 70 e0 ldi r23, 0x00 ; 0 + 312a: 84 d0 rcall .+264 ; 0x3234 + 312c: 88 23 and r24, r24 + 312e: 09 f0 breq .+2 ; 0x3132 <__stack+0x133> + 3130: 49 cc rjmp .-1902 ; 0x29c4 + CurrentAddress = Buffer[1]; + 3132: 81 e0 ldi r24, 0x01 ; 1 + 3134: d7 01 movw r26, r14 + 3136: 8c 93 st X, r24 + 3138: 84 e0 ldi r24, 0x04 ; 4 + 313a: 90 e0 ldi r25, 0x00 ; 0 + 313c: f6 cb rjmp .-2068 ; 0x292a + State = STATE_RESTORE; + 313e: 8d 81 ldd r24, Y+5 ; 0x05 + 3140: f7 01 movw r30, r14 + Buffer[0] = NAK_CRC_ERROR ^ Crypto1Nibble(); + } + return ACK_NAK_FRAME_SIZE; + }else if (Buffer[0] == CMD_TRANSFER) { + /* Write back the global block buffer to the desired block address */ + if (ISO14443ACheckCRCA(Buffer, CMD_TRANSFER_FRAME_SIZE)) { + 3142: 80 83 st Z, r24 + 3144: 3e 81 ldd r19, Y+6 ; 0x06 + 3146: 31 83 std Z+1, r19 ; 0x01 + 3148: 2f 81 ldd r18, Y+7 ; 0x07 + 314a: 22 83 std Z+2, r18 ; 0x02 + 314c: 98 85 ldd r25, Y+8 ; 0x08 + 314e: 93 83 std Z+3, r25 ; 0x03 + 3150: 83 27 eor r24, r19 + if (!ActiveConfiguration.ReadOnly) { + 3152: 82 27 eor r24, r18 + 3154: 89 27 eor r24, r25 + 3156: 84 83 std Z+4, r24 ; 0x04 + 3158: 88 e2 ldi r24, 0x28 ; 40 + 315a: 90 e0 ldi r25, 0x00 ; 0 + MemoryWriteBlock(BlockBuffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK ); + 315c: e6 cb rjmp .-2100 ; 0x292a + 315e: 80 e3 ldi r24, 0x30 ; 48 + 3160: 90 e0 ldi r25, 0x00 ; 0 + 3162: 20 cd rjmp .-1472 ; 0x2ba4 + 3164: 80 e3 ldi r24, 0x30 ; 48 + 3166: 90 e0 ldi r25, 0x00 ; 0 + 3168: 8a cd rjmp .-1260 ; 0x2c7e + +0000316a : + 316a: 60 e0 ldi r22, 0x00 ; 0 + 316c: 70 e0 ldi r23, 0x00 ; 0 + 316e: 44 e0 ldi r20, 0x04 ; 4 + 3170: 50 e0 ldi r21, 0x00 ; 0 + 3172: 0c 94 1d 06 jmp 0xc3a ; 0xc3a + +00003176 : + 3176: cf 93 push r28 + 3178: df 93 push r29 + 317a: 0f 92 push r0 + + ValueFromBlock(&ParamValue, Buffer); + ValueFromBlock(&BlockValue, BlockBuffer); + + if (State == STATE_DECREMENT) { + BlockValue -= ParamValue; + 317c: cd b7 in r28, 0x3d ; 61 + 317e: de b7 in r29, 0x3e ; 62 + 3180: fc 01 movw r30, r24 + 3182: 81 81 ldd r24, Z+1 ; 0x01 + 3184: 90 81 ld r25, Z + return BitCount; + } else if (Buffer[0] == CMD_HALT) { + /* Halts the tag. According to the ISO14443, the second + * byte is supposed to be 0. */ + if (Buffer[1] == 0) { + if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) { + 3186: 89 27 eor r24, r25 + 3188: 92 81 ldd r25, Z+2 ; 0x02 + 318a: 89 27 eor r24, r25 + 318c: 93 81 ldd r25, Z+3 ; 0x03 + 318e: 89 27 eor r24, r25 + 3190: 89 83 std Y+1, r24 ; 0x01 + 3192: cf 01 movw r24, r30 + 3194: 60 e0 ldi r22, 0x00 ; 0 + /* Setup crypto1 cipher. Discard in-place encrypted CardNonce. */ + Crypto1Setup(Key, Uid, CardNonce); + + return CMD_AUTH_RB_FRAME_SIZE * BITS_PER_BYTE; + } else { + Buffer[0] = NAK_CRC_ERROR; + 3196: 70 e0 ldi r23, 0x00 ; 0 + 3198: 44 e0 ldi r20, 0x04 ; 4 + 319a: 50 e0 ldi r21, 0x00 ; 0 + return ACK_NAK_FRAME_SIZE; + 319c: 0e 94 a8 06 call 0xd50 ; 0xd50 + 31a0: ce 01 movw r24, r28 + + switch (NVB) { + case ISO14443A_NVB_AC_START: + /* Start of anticollision procedure. + * Send whole UID CLn + BCC */ + DataPtr[0] = UidCL[0]; + 31a2: 01 96 adiw r24, 0x01 ; 1 + 31a4: 64 e0 ldi r22, 0x04 ; 4 + 31a6: 70 e0 ldi r23, 0x00 ; 0 + DataPtr[1] = UidCL[1]; + 31a8: 41 e0 ldi r20, 0x01 ; 1 + 31aa: 50 e0 ldi r21, 0x00 ; 0 + DataPtr[2] = UidCL[2]; + 31ac: 0e 94 a8 06 call 0xd50 ; 0xd50 + DataPtr[3] = UidCL[3]; + 31b0: 0f 90 pop r0 + 31b2: df 91 pop r29 + DataPtr[4] = ISO14443A_CALC_BCC(DataPtr); + 31b4: cf 91 pop r28 + 31b6: 08 95 ret + +000031b8 : + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + 31b8: ef 92 push r14 + 31ba: ff 92 push r15 + 31bc: 0f 93 push r16 + 31be: 1f 93 push r17 + 31c0: cf 93 push r28 + 31c2: 7c 01 movw r14, r24 + 31c4: 8b 01 movw r16, r22 + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 31c6: 61 15 cp r22, r1 + 31c8: 71 05 cpc r23, r1 + 31ca: 81 f1 breq .+96 ; 0x322c + 31cc: fb 01 movw r30, r22 + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 31ce: dc 01 movw r26, r24 + */ + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + 31d0: 43 e6 ldi r20, 0x63 ; 99 + 31d2: 53 e6 ldi r21, 0x63 ; 99 + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + 31d4: 8d 91 ld r24, X+ + + Byte ^= (uint8_t) (Checksum & 0x00FF); + 31d6: 84 27 eor r24, r20 + Byte ^= Byte << 4; + 31d8: c8 2f mov r28, r24 + 31da: c2 95 swap r28 + 31dc: c0 7f andi r28, 0xF0 ; 240 + 31de: c8 27 eor r28, r24 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 31e0: 8c 2f mov r24, r28 + 31e2: 90 e0 ldi r25, 0x00 ; 0 + 31e4: 78 2f mov r23, r24 + 31e6: 66 27 eor r22, r22 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 31e8: 9c 01 movw r18, r24 + 31ea: 22 0f add r18, r18 + 31ec: 33 1f adc r19, r19 + 31ee: 22 0f add r18, r18 + 31f0: 33 1f adc r19, r19 + 31f2: 22 0f add r18, r18 + 31f4: 33 1f adc r19, r19 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 31f6: 62 27 eor r22, r18 + 31f8: 73 27 eor r23, r19 + 31fa: 45 2f mov r20, r21 + 31fc: 55 27 eor r21, r21 + 31fe: 46 27 eor r20, r22 + 3200: 57 27 eor r21, r23 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 3202: c2 95 swap r28 + 3204: cf 70 andi r28, 0x0F ; 15 + 3206: 8c 2f mov r24, r28 + 3208: 90 e0 ldi r25, 0x00 ; 0 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 320a: 48 27 eor r20, r24 + 320c: 59 27 eor r21, r25 + 320e: 31 97 sbiw r30, 0x01 ; 1 + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 3210: 09 f7 brne .-62 ; 0x31d4 + 3212: f7 01 movw r30, r14 + 3214: e0 0f add r30, r16 + 3216: f1 1f adc r31, r17 + 3218: 94 2f mov r25, r20 + 321a: 85 2f mov r24, r21 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + *DataPtr++ = (Checksum >> 0) & 0x00FF; + 321c: 90 83 st Z, r25 + *DataPtr = (Checksum >> 8) & 0x00FF; + 321e: 81 83 std Z+1, r24 ; 0x01 +} + 3220: cf 91 pop r28 + 3222: 1f 91 pop r17 + 3224: 0f 91 pop r16 + 3226: ff 90 pop r15 + 3228: ef 90 pop r14 + 322a: 08 95 ret + +#include "ISO14443-3A.h" + +void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) { + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 322c: fc 01 movw r30, r24 + + while(ByteCount--) { + 322e: 83 e6 ldi r24, 0x63 ; 99 + 3230: 93 e6 ldi r25, 0x63 ; 99 + 3232: f4 cf rjmp .-24 ; 0x321c + +00003234 : + *DataPtr++ = (Checksum >> 0) & 0x00FF; + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + 3234: ef 92 push r14 + 3236: ff 92 push r15 + 3238: 0f 93 push r16 + 323a: 1f 93 push r17 + 323c: cf 93 push r28 + 323e: 7c 01 movw r14, r24 + 3240: 8b 01 movw r16, r22 + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 3242: 61 15 cp r22, r1 + 3244: 71 05 cpc r23, r1 + 3246: 09 f4 brne .+2 ; 0x324a + 3248: 3d c0 rjmp .+122 ; 0x32c4 + 324a: fb 01 movw r30, r22 +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 324c: dc 01 movw r26, r24 + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + 324e: 43 e6 ldi r20, 0x63 ; 99 + 3250: 53 e6 ldi r21, 0x63 ; 99 + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + uint8_t Byte = *DataPtr++; + 3252: 8d 91 ld r24, X+ + + Byte ^= (uint8_t) (Checksum & 0x00FF); + 3254: 84 27 eor r24, r20 + Byte ^= Byte << 4; + 3256: c8 2f mov r28, r24 + 3258: c2 95 swap r28 + 325a: c0 7f andi r28, 0xF0 ; 240 + 325c: c8 27 eor r28, r24 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 325e: 8c 2f mov r24, r28 + 3260: 90 e0 ldi r25, 0x00 ; 0 + 3262: 78 2f mov r23, r24 + 3264: 66 27 eor r22, r22 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 3266: 9c 01 movw r18, r24 + 3268: 22 0f add r18, r18 + 326a: 33 1f adc r19, r19 + 326c: 22 0f add r18, r18 + 326e: 33 1f adc r19, r19 + 3270: 22 0f add r18, r18 + 3272: 33 1f adc r19, r19 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 3274: 62 27 eor r22, r18 + 3276: 73 27 eor r23, r19 + 3278: 45 2f mov r20, r21 + 327a: 55 27 eor r21, r21 + 327c: 46 27 eor r20, r22 + 327e: 57 27 eor r21, r23 + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + 3280: c2 95 swap r28 + 3282: cf 70 andi r28, 0x0F ; 15 + 3284: 8c 2f mov r24, r28 + 3286: 90 e0 ldi r25, 0x00 ; 0 + uint8_t Byte = *DataPtr++; + + Byte ^= (uint8_t) (Checksum & 0x00FF); + Byte ^= Byte << 4; + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + 3288: 48 27 eor r20, r24 + 328a: 59 27 eor r21, r25 + 328c: 31 97 sbiw r30, 0x01 ; 1 +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + 328e: 09 f7 brne .-62 ; 0x3252 + 3290: f7 01 movw r30, r14 + 3292: e0 0f add r30, r16 + 3294: f1 1f adc r31, r17 + 3296: 9a 01 movw r18, r20 + 3298: 30 70 andi r19, 0x00 ; 0 + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); + 329a: 80 81 ld r24, Z + 329c: 90 e0 ldi r25, 0x00 ; 0 + 329e: 82 17 cp r24, r18 + 32a0: 93 07 cpc r25, r19 + 32a2: 39 f0 breq .+14 ; 0x32b2 + 32a4: 80 e0 ldi r24, 0x00 ; 0 +} + 32a6: cf 91 pop r28 + 32a8: 1f 91 pop r17 + 32aa: 0f 91 pop r16 + 32ac: ff 90 pop r15 + 32ae: ef 90 pop r14 + 32b0: 08 95 ret + + Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^ + ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 ); + } + + return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF)); + 32b2: 21 81 ldd r18, Z+1 ; 0x01 + 32b4: 30 e0 ldi r19, 0x00 ; 0 + 32b6: 45 2f mov r20, r21 + 32b8: 55 27 eor r21, r21 + + *DataPtr++ = (Checksum >> 0) & 0x00FF; + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) + 32ba: 81 e0 ldi r24, 0x01 ; 1 + 32bc: 24 17 cp r18, r20 + 32be: 35 07 cpc r19, r21 + 32c0: 89 f7 brne .-30 ; 0x32a4 + 32c2: f1 cf rjmp .-30 ; 0x32a6 +{ + uint16_t Checksum = 0x6363; + uint8_t* DataPtr = (uint8_t*) Buffer; + 32c4: fc 01 movw r30, r24 + + while(ByteCount--) { + 32c6: 23 e6 ldi r18, 0x63 ; 99 + 32c8: 30 e0 ldi r19, 0x00 ; 0 + *DataPtr = (Checksum >> 8) & 0x00FF; +} + +bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount) +{ + uint16_t Checksum = 0x6363; + 32ca: 43 e6 ldi r20, 0x63 ; 99 + 32cc: 53 e6 ldi r21, 0x63 ; 99 + 32ce: e5 cf rjmp .-54 ; 0x329a + +000032d0 : +/* Split Crypto1 state into even and odd bits to speed up the output filter network */ +static uint8_t StateEven[LFSR_SIZE/2] = {0}; +static uint8_t StateOdd[LFSR_SIZE/2] = {0}; + +/* Proceed LFSR by one clock cycle */ +static void Crypto1LFSR(uint8_t In) { + 32d0: cf 92 push r12 + 32d2: df 92 push r13 + 32d4: ef 92 push r14 + 32d6: ff 92 push r15 + 32d8: 0f 93 push r16 + 32da: 1f 93 push r17 + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + 32dc: 00 91 e5 20 lds r16, 0x20E5 + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 32e0: 40 91 e6 20 lds r20, 0x20E6 + Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); + 32e4: 30 91 e7 20 lds r19, 0x20E7 + + Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); + 32e8: a0 91 e2 20 lds r26, 0x20E2 + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + 32ec: f0 91 e3 20 lds r31, 0x20E3 + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + 32f0: e0 91 e4 20 lds r30, 0x20E4 + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 32f4: 94 2f mov r25, r20 + 32f6: 90 71 andi r25, 0x10 ; 16 +static void Crypto1LFSR(uint8_t In) { + uint8_t Feedback = 0; + + /* Calculate feedback according to LFSR taps. XOR all 6 state bytes + * into a single bit. */ + Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0); + 32f8: 20 2f mov r18, r16 + 32fa: 21 7e andi r18, 0xE1 ; 225 + Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8); + 32fc: 92 27 eor r25, r18 + Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16); + 32fe: 23 2f mov r18, r19 + 3300: 20 72 andi r18, 0x20 ; 32 + 3302: 92 27 eor r25, r18 + + Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0); + 3304: 2a 2f mov r18, r26 + 3306: 24 79 andi r18, 0x94 ; 148 + 3308: 92 27 eor r25, r18 + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + 330a: 2f 2f mov r18, r31 + 330c: 23 77 andi r18, 0x73 ; 115 + 330e: 92 27 eor r25, r18 + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + 3310: 2e 2f mov r18, r30 + 3312: 2a 73 andi r18, 0x3A ; 58 + 3314: 92 27 eor r25, r18 + + Feedback ^= Feedback >> 4; + 3316: 29 2f mov r18, r25 + 3318: 22 95 swap r18 + 331a: 2f 70 andi r18, 0x0F ; 15 + 331c: 29 27 eor r18, r25 + Feedback ^= Feedback >> 2; + 331e: 92 2f mov r25, r18 + 3320: 96 95 lsr r25 + 3322: 96 95 lsr r25 + 3324: 92 27 eor r25, r18 + Feedback ^= Feedback >> 1; + 3326: b9 2f mov r27, r25 + 3328: b6 95 lsr r27 + * - the new even state becomes the old odd state + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + Temp |= ((uint32_t) StateEven[1] << 8); + 332a: 50 e0 ldi r21, 0x00 ; 0 + 332c: 60 e0 ldi r22, 0x00 ; 0 + 332e: 70 e0 ldi r23, 0x00 ; 0 + 3330: 76 2f mov r23, r22 + 3332: 65 2f mov r22, r21 + 3334: 54 2f mov r21, r20 + 3336: 44 27 eor r20, r20 + Temp |= ((uint32_t) StateEven[2] << 16); + 3338: c3 2e mov r12, r19 + 333a: dd 24 eor r13, r13 + 333c: ee 24 eor r14, r14 + 333e: ff 24 eor r15, r15 + 3340: 76 01 movw r14, r12 + 3342: dd 24 eor r13, r13 + 3344: cc 24 eor r12, r12 + * - the new even state becomes the old odd state + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + Temp |= ((uint32_t) StateEven[1] << 8); + 3346: 4c 29 or r20, r12 + 3348: 5d 29 or r21, r13 + 334a: 6e 29 or r22, r14 + 334c: 7f 29 or r23, r15 + * see that after one LFSR clock cycle + * - the new even state becomes the old odd state + * - the new odd state becomes the old even state right-shifted by 1. + * For shifting the even state, we convert it into a 32 bit int first */ + uint32_t Temp = 0; + Temp |= ((uint32_t) StateEven[0] << 0); + 334e: 10 e0 ldi r17, 0x00 ; 0 + 3350: 20 e0 ldi r18, 0x00 ; 0 + 3352: 30 e0 ldi r19, 0x00 ; 0 + Temp |= ((uint32_t) StateEven[1] << 8); + Temp |= ((uint32_t) StateEven[2] << 16); + 3354: 40 2b or r20, r16 + 3356: 51 2b or r21, r17 + 3358: 62 2b or r22, r18 + 335a: 73 2b or r23, r19 + + /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ + Temp = (Temp >> 1) & 0x00FFFFFF; + 335c: 76 95 lsr r23 + 335e: 67 95 ror r22 + 3360: 57 95 ror r21 + 3362: 47 95 ror r20 + Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8); + Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + 3364: b9 27 eor r27, r25 + + /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */ + Temp = (Temp >> 1) & 0x00FFFFFF; + + /* Calculate MSBit of even state as input bit to LFSR */ + if ( (Feedback & 0x01) ^ In ) { + 3366: 2b 2f mov r18, r27 + 3368: 30 e0 ldi r19, 0x00 ; 0 + 336a: 21 70 andi r18, 0x01 ; 1 + 336c: 30 70 andi r19, 0x00 ; 0 + 336e: 90 e0 ldi r25, 0x00 ; 0 + 3370: 28 17 cp r18, r24 + 3372: 39 07 cpc r19, r25 + 3374: 09 f0 breq .+2 ; 0x3378 + Temp |= (uint32_t) 1 << (8 * LFSR_SIZE/2 - 1); + 3376: 60 68 ori r22, 0x80 ; 128 + } + + /* Convert even state back into byte array and swap odd/even state + * as explained above. */ + StateEven[0] = StateOdd[0]; + 3378: a0 93 e5 20 sts 0x20E5, r26 + StateEven[1] = StateOdd[1]; + 337c: f0 93 e6 20 sts 0x20E6, r31 + StateEven[2] = StateOdd[2]; + 3380: e0 93 e7 20 sts 0x20E7, r30 + + StateOdd[0] = (uint8_t) (Temp >> 0); + 3384: 40 93 e2 20 sts 0x20E2, r20 + StateOdd[1] = (uint8_t) (Temp >> 8); + 3388: 50 93 e3 20 sts 0x20E3, r21 + StateOdd[2] = (uint8_t) (Temp >> 16); + 338c: 60 93 e4 20 sts 0x20E4, r22 +} + 3390: 1f 91 pop r17 + 3392: 0f 91 pop r16 + 3394: ff 90 pop r15 + 3396: ef 90 pop r14 + 3398: df 90 pop r13 + 339a: cf 90 pop r12 + 339c: 08 95 ret + +0000339e : + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + 339e: 50 91 e3 20 lds r21, 0x20E3 + Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; + Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; + 33a2: 40 91 e4 20 lds r20, 0x20E4 + 33a6: 24 2f mov r18, r20 + 33a8: 2f 70 andi r18, 0x0F ; 15 + 33aa: 8d e1 ldi r24, 0x1D ; 29 + 33ac: 90 e2 ldi r25, 0x20 ; 32 + 33ae: dc 01 movw r26, r24 + 33b0: a2 0f add r26, r18 + 33b2: b1 1d adc r27, r1 + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + 33b4: 25 2f mov r18, r21 + 33b6: 2f 70 andi r18, 0x0F ; 15 + 33b8: fc 01 movw r30, r24 + 33ba: e2 0f add r30, r18 + 33bc: f1 1d adc r31, r1 + 33be: d0 96 adiw r26, 0x30 ; 48 + 33c0: 2c 91 ld r18, X + 33c2: d0 97 sbiw r26, 0x30 ; 48 + 33c4: 30 89 ldd r19, Z+16 ; 0x10 + 33c6: 23 2b or r18, r19 + * can simply be ORed together to produce the resulting + * 5 bits that are used to lookup the output bit. + */ + uint8_t Sum = 0; + + Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F]; + 33c8: 30 91 e2 20 lds r19, 0x20E2 + 33cc: 32 95 swap r19 + 33ce: 3f 70 andi r19, 0x0F ; 15 + 33d0: fc 01 movw r30, r24 + 33d2: e3 0f add r30, r19 + 33d4: f1 1d adc r31, r1 + Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F]; + Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F]; + 33d6: 30 81 ld r19, Z + 33d8: 23 2b or r18, r19 + 33da: 52 95 swap r21 + 33dc: 5f 70 andi r21, 0x0F ; 15 + 33de: fc 01 movw r30, r24 + 33e0: e5 0f add r30, r21 + 33e2: f1 1d adc r31, r1 + Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F]; + 33e4: 30 a1 lds r19, 0x40 + 33e6: 23 2b or r18, r19 + Sum |= TableAB[4][(StateOdd[2] >> 4) & 0x0F]; + 33e8: 42 95 swap r20 + 33ea: 4f 70 andi r20, 0x0F ; 15 + 33ec: 84 0f add r24, r20 + 33ee: 91 1d adc r25, r1 + 33f0: 80 5c subi r24, 0xC0 ; 192 + 33f2: 9f 4f sbci r25, 0xFF ; 255 + 33f4: fc 01 movw r30, r24 + 33f6: 80 81 ld r24, Z + 33f8: 28 2b or r18, r24 + + return TableC[Sum]; + 33fa: ed e6 ldi r30, 0x6D ; 109 + 33fc: f0 e2 ldi r31, 0x20 ; 32 + 33fe: e2 0f add r30, r18 + 3400: f1 1d adc r31, r1 +} + 3402: 80 81 ld r24, Z + 3404: 08 95 ret + +00003406 : + +void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]) +{ + 3406: cf 92 push r12 + 3408: df 92 push r13 + 340a: ef 92 push r14 + 340c: ff 92 push r15 + 340e: 0f 93 push r16 + 3410: 1f 93 push r17 + 3412: cf 93 push r28 + 3414: df 93 push r29 + 3416: fc 01 movw r30, r24 + 3418: ea 01 movw r28, r20 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 341a: 31 81 ldd r19, Z+1 ; 0x01 + 341c: 20 e0 ldi r18, 0x00 ; 0 + 341e: 80 81 ld r24, Z + 3420: 90 e0 ldi r25, 0x00 ; 0 + 3422: 82 2b or r24, r18 + 3424: 93 2b or r25, r19 + 3426: 80 fd sbrc r24, 0 + 3428: b2 c1 rjmp .+868 ; 0x378e + 342a: 30 e0 ldi r19, 0x00 ; 0 + 342c: 81 fd sbrc r24, 1 + 342e: ad c1 rjmp .+858 ; 0x378a + 3430: 20 e0 ldi r18, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 3432: 96 95 lsr r25 + 3434: 87 95 ror r24 + 3436: 96 95 lsr r25 + 3438: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 343a: 43 2f mov r20, r19 + 343c: 40 68 ori r20, 0x80 ; 128 + 343e: 80 fd sbrc r24, 0 + 3440: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3442: 42 2f mov r20, r18 + 3444: 40 68 ori r20, 0x80 ; 128 + 3446: 81 fd sbrc r24, 1 + 3448: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 344a: 96 95 lsr r25 + 344c: 87 95 ror r24 + 344e: 96 95 lsr r25 + 3450: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3452: 36 95 lsr r19 + OddByte >>= 1; + 3454: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3456: 43 2f mov r20, r19 + 3458: 40 68 ori r20, 0x80 ; 128 + 345a: 80 fd sbrc r24, 0 + 345c: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 345e: 42 2f mov r20, r18 + 3460: 40 68 ori r20, 0x80 ; 128 + 3462: 81 fd sbrc r24, 1 + 3464: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3466: 96 95 lsr r25 + 3468: 87 95 ror r24 + 346a: 96 95 lsr r25 + 346c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 346e: 36 95 lsr r19 + OddByte >>= 1; + 3470: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3472: 43 2f mov r20, r19 + 3474: 40 68 ori r20, 0x80 ; 128 + 3476: 80 fd sbrc r24, 0 + 3478: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 347a: 42 2f mov r20, r18 + 347c: 40 68 ori r20, 0x80 ; 128 + 347e: 81 fd sbrc r24, 1 + 3480: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3482: 96 95 lsr r25 + 3484: 87 95 ror r24 + 3486: 96 95 lsr r25 + 3488: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 348a: 36 95 lsr r19 + OddByte >>= 1; + 348c: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 348e: 43 2f mov r20, r19 + 3490: 40 68 ori r20, 0x80 ; 128 + 3492: 80 fd sbrc r24, 0 + 3494: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3496: 42 2f mov r20, r18 + 3498: 40 68 ori r20, 0x80 ; 128 + 349a: 81 fd sbrc r24, 1 + 349c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 349e: 96 95 lsr r25 + 34a0: 87 95 ror r24 + 34a2: 96 95 lsr r25 + 34a4: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 34a6: 36 95 lsr r19 + OddByte >>= 1; + 34a8: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 34aa: 43 2f mov r20, r19 + 34ac: 40 68 ori r20, 0x80 ; 128 + 34ae: 80 fd sbrc r24, 0 + 34b0: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 34b2: 42 2f mov r20, r18 + 34b4: 40 68 ori r20, 0x80 ; 128 + 34b6: 81 fd sbrc r24, 1 + 34b8: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 34ba: 96 95 lsr r25 + 34bc: 87 95 ror r24 + 34be: 96 95 lsr r25 + 34c0: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 34c2: 36 95 lsr r19 + OddByte >>= 1; + 34c4: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 34c6: 43 2f mov r20, r19 + 34c8: 40 68 ori r20, 0x80 ; 128 + 34ca: 80 fd sbrc r24, 0 + 34cc: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 34ce: 42 2f mov r20, r18 + 34d0: 40 68 ori r20, 0x80 ; 128 + 34d2: 81 fd sbrc r24, 1 + 34d4: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 34d6: 96 95 lsr r25 + 34d8: 87 95 ror r24 + 34da: 96 95 lsr r25 + 34dc: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 34de: 36 95 lsr r19 + OddByte >>= 1; + 34e0: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 34e2: 53 2f mov r21, r19 + 34e4: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 34e6: 42 2f mov r20, r18 + 34e8: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 34ea: 80 fd sbrc r24, 0 + 34ec: 35 2f mov r19, r21 + 34ee: 30 93 e5 20 sts 0x20E5, r19 + StateOdd[i] = OddByte; + 34f2: 81 fd sbrc r24, 1 + 34f4: 24 2f mov r18, r20 + 34f6: 20 93 e2 20 sts 0x20E2, r18 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 34fa: 33 81 ldd r19, Z+3 ; 0x03 + 34fc: 20 e0 ldi r18, 0x00 ; 0 + 34fe: 82 81 ldd r24, Z+2 ; 0x02 + 3500: 90 e0 ldi r25, 0x00 ; 0 + 3502: 82 2b or r24, r18 + 3504: 93 2b or r25, r19 + 3506: 80 fd sbrc r24, 0 + 3508: 3e c1 rjmp .+636 ; 0x3786 + 350a: 30 e0 ldi r19, 0x00 ; 0 + 350c: 81 fd sbrc r24, 1 + 350e: 39 c1 rjmp .+626 ; 0x3782 + 3510: 20 e0 ldi r18, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 3512: 96 95 lsr r25 + 3514: 87 95 ror r24 + 3516: 96 95 lsr r25 + 3518: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 351a: 43 2f mov r20, r19 + 351c: 40 68 ori r20, 0x80 ; 128 + 351e: 80 fd sbrc r24, 0 + 3520: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3522: 42 2f mov r20, r18 + 3524: 40 68 ori r20, 0x80 ; 128 + 3526: 81 fd sbrc r24, 1 + 3528: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 352a: 96 95 lsr r25 + 352c: 87 95 ror r24 + 352e: 96 95 lsr r25 + 3530: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3532: 36 95 lsr r19 + OddByte >>= 1; + 3534: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3536: 43 2f mov r20, r19 + 3538: 40 68 ori r20, 0x80 ; 128 + 353a: 80 fd sbrc r24, 0 + 353c: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 353e: 42 2f mov r20, r18 + 3540: 40 68 ori r20, 0x80 ; 128 + 3542: 81 fd sbrc r24, 1 + 3544: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3546: 96 95 lsr r25 + 3548: 87 95 ror r24 + 354a: 96 95 lsr r25 + 354c: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 354e: 36 95 lsr r19 + OddByte >>= 1; + 3550: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3552: 43 2f mov r20, r19 + 3554: 40 68 ori r20, 0x80 ; 128 + 3556: 80 fd sbrc r24, 0 + 3558: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 355a: 42 2f mov r20, r18 + 355c: 40 68 ori r20, 0x80 ; 128 + 355e: 81 fd sbrc r24, 1 + 3560: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3562: 96 95 lsr r25 + 3564: 87 95 ror r24 + 3566: 96 95 lsr r25 + 3568: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 356a: 36 95 lsr r19 + OddByte >>= 1; + 356c: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 356e: 43 2f mov r20, r19 + 3570: 40 68 ori r20, 0x80 ; 128 + 3572: 80 fd sbrc r24, 0 + 3574: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3576: 42 2f mov r20, r18 + 3578: 40 68 ori r20, 0x80 ; 128 + 357a: 81 fd sbrc r24, 1 + 357c: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 357e: 96 95 lsr r25 + 3580: 87 95 ror r24 + 3582: 96 95 lsr r25 + 3584: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3586: 36 95 lsr r19 + OddByte >>= 1; + 3588: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 358a: 43 2f mov r20, r19 + 358c: 40 68 ori r20, 0x80 ; 128 + 358e: 80 fd sbrc r24, 0 + 3590: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3592: 42 2f mov r20, r18 + 3594: 40 68 ori r20, 0x80 ; 128 + 3596: 81 fd sbrc r24, 1 + 3598: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 359a: 96 95 lsr r25 + 359c: 87 95 ror r24 + 359e: 96 95 lsr r25 + 35a0: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 35a2: 36 95 lsr r19 + OddByte >>= 1; + 35a4: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 35a6: 43 2f mov r20, r19 + 35a8: 40 68 ori r20, 0x80 ; 128 + 35aa: 80 fd sbrc r24, 0 + 35ac: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 35ae: 42 2f mov r20, r18 + 35b0: 40 68 ori r20, 0x80 ; 128 + 35b2: 81 fd sbrc r24, 1 + 35b4: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 35b6: 96 95 lsr r25 + 35b8: 87 95 ror r24 + 35ba: 96 95 lsr r25 + 35bc: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 35be: 36 95 lsr r19 + OddByte >>= 1; + 35c0: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 35c2: 53 2f mov r21, r19 + 35c4: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 35c6: 42 2f mov r20, r18 + 35c8: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 35ca: 80 fd sbrc r24, 0 + 35cc: 35 2f mov r19, r21 + 35ce: 30 93 e6 20 sts 0x20E6, r19 + StateOdd[i] = OddByte; + 35d2: 81 fd sbrc r24, 1 + 35d4: 24 2f mov r18, r20 + 35d6: 20 93 e3 20 sts 0x20E3, r18 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 35da: 95 81 ldd r25, Z+5 ; 0x05 + 35dc: 80 e0 ldi r24, 0x00 ; 0 + 35de: 24 81 ldd r18, Z+4 ; 0x04 + 35e0: 30 e0 ldi r19, 0x00 ; 0 + 35e2: 28 2b or r18, r24 + 35e4: 39 2b or r19, r25 + 35e6: 20 fd sbrc r18, 0 + 35e8: ca c0 rjmp .+404 ; 0x377e + 35ea: 50 e0 ldi r21, 0x00 ; 0 + 35ec: 21 fd sbrc r18, 1 + 35ee: c5 c0 rjmp .+394 ; 0x377a + 35f0: 40 e0 ldi r20, 0x00 ; 0 + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + } + + KeyWord >>= 2; + 35f2: c9 01 movw r24, r18 + 35f4: 96 95 lsr r25 + 35f6: 87 95 ror r24 + 35f8: 96 95 lsr r25 + 35fa: 87 95 ror r24 + for (j=0; j<8; j++) { + EvenByte >>= 1; + OddByte >>= 1; + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 35fc: 35 2f mov r19, r21 + 35fe: 30 68 ori r19, 0x80 ; 128 + 3600: 80 ff sbrs r24, 0 + 3602: 35 2f mov r19, r21 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3604: 24 2f mov r18, r20 + 3606: 20 68 ori r18, 0x80 ; 128 + 3608: 81 ff sbrs r24, 1 + 360a: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 360c: 96 95 lsr r25 + 360e: 87 95 ror r24 + 3610: 96 95 lsr r25 + 3612: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3614: 36 95 lsr r19 + OddByte >>= 1; + 3616: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3618: 43 2f mov r20, r19 + 361a: 40 68 ori r20, 0x80 ; 128 + 361c: 80 fd sbrc r24, 0 + 361e: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3620: 42 2f mov r20, r18 + 3622: 40 68 ori r20, 0x80 ; 128 + 3624: 81 fd sbrc r24, 1 + 3626: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3628: 96 95 lsr r25 + 362a: 87 95 ror r24 + 362c: 96 95 lsr r25 + 362e: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3630: 36 95 lsr r19 + OddByte >>= 1; + 3632: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3634: 43 2f mov r20, r19 + 3636: 40 68 ori r20, 0x80 ; 128 + 3638: 80 fd sbrc r24, 0 + 363a: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 363c: 42 2f mov r20, r18 + 363e: 40 68 ori r20, 0x80 ; 128 + 3640: 81 fd sbrc r24, 1 + 3642: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3644: 96 95 lsr r25 + 3646: 87 95 ror r24 + 3648: 96 95 lsr r25 + 364a: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 364c: 36 95 lsr r19 + OddByte >>= 1; + 364e: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3650: 43 2f mov r20, r19 + 3652: 40 68 ori r20, 0x80 ; 128 + 3654: 80 fd sbrc r24, 0 + 3656: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3658: 42 2f mov r20, r18 + 365a: 40 68 ori r20, 0x80 ; 128 + 365c: 81 fd sbrc r24, 1 + 365e: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3660: 96 95 lsr r25 + 3662: 87 95 ror r24 + 3664: 96 95 lsr r25 + 3666: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3668: 36 95 lsr r19 + OddByte >>= 1; + 366a: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 366c: 43 2f mov r20, r19 + 366e: 40 68 ori r20, 0x80 ; 128 + 3670: 80 fd sbrc r24, 0 + 3672: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3674: 42 2f mov r20, r18 + 3676: 40 68 ori r20, 0x80 ; 128 + 3678: 81 fd sbrc r24, 1 + 367a: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 367c: 96 95 lsr r25 + 367e: 87 95 ror r24 + 3680: 96 95 lsr r25 + 3682: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 3684: 36 95 lsr r19 + OddByte >>= 1; + 3686: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 3688: 43 2f mov r20, r19 + 368a: 40 68 ori r20, 0x80 ; 128 + 368c: 80 fd sbrc r24, 0 + 368e: 34 2f mov r19, r20 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 3690: 42 2f mov r20, r18 + 3692: 40 68 ori r20, 0x80 ; 128 + 3694: 81 fd sbrc r24, 1 + 3696: 24 2f mov r18, r20 + } + + KeyWord >>= 2; + 3698: 96 95 lsr r25 + 369a: 87 95 ror r24 + 369c: 96 95 lsr r25 + 369e: 87 95 ror r24 + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + uint8_t j; + + for (j=0; j<8; j++) { + EvenByte >>= 1; + 36a0: 36 95 lsr r19 + OddByte >>= 1; + 36a2: 26 95 lsr r18 + + if (KeyWord & (1<<0)) { + EvenByte |= 0x80; + 36a4: 53 2f mov r21, r19 + 36a6: 50 68 ori r21, 0x80 ; 128 + } + + if (KeyWord & (1<<1)) { + OddByte |= 0x80; + 36a8: 42 2f mov r20, r18 + 36aa: 40 68 ori r20, 0x80 ; 128 + } + + KeyWord >>= 2; + } + + StateEven[i] = EvenByte; + 36ac: 80 fd sbrc r24, 0 + 36ae: 35 2f mov r19, r21 + 36b0: 30 93 e7 20 sts 0x20E7, r19 + StateOdd[i] = OddByte; + 36b4: 81 fd sbrc r24, 1 + 36b6: 24 2f mov r18, r20 + 36b8: 20 93 e4 20 sts 0x20E4, r18 + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + 36bc: c9 80 ldd r12, Y+1 ; 0x01 + 36be: db 01 movw r26, r22 + 36c0: 11 96 adiw r26, 0x01 ; 1 + 36c2: 8c 91 ld r24, X + 36c4: 11 97 sbiw r26, 0x01 ; 1 + 36c6: c8 26 eor r12, r24 + 36c8: dd 24 eor r13, r13 + 36ca: ee 24 eor r14, r14 + 36cc: ff 24 eor r15, r15 + 36ce: fe 2c mov r15, r14 + 36d0: ed 2c mov r14, r13 + 36d2: dc 2c mov r13, r12 + 36d4: cc 24 eor r12, r12 + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + 36d6: 8a 81 ldd r24, Y+2 ; 0x02 + 36d8: 12 96 adiw r26, 0x02 ; 2 + 36da: 9c 91 ld r25, X + 36dc: 89 27 eor r24, r25 + 36de: 90 e0 ldi r25, 0x00 ; 0 + 36e0: a0 e0 ldi r26, 0x00 ; 0 + 36e2: b0 e0 ldi r27, 0x00 ; 0 + 36e4: dc 01 movw r26, r24 + 36e6: 99 27 eor r25, r25 + 36e8: 88 27 eor r24, r24 + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + 36ea: c8 2a or r12, r24 + 36ec: d9 2a or r13, r25 + 36ee: ea 2a or r14, r26 + 36f0: fb 2a or r15, r27 + + /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the + * Crypto1 LFSR.*/ + uint32_t Temp = 0; + + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + 36f2: 88 81 ld r24, Y + 36f4: fb 01 movw r30, r22 + 36f6: 90 81 ld r25, Z + 36f8: 89 27 eor r24, r25 + 36fa: 90 e0 ldi r25, 0x00 ; 0 + 36fc: a0 e0 ldi r26, 0x00 ; 0 + 36fe: b0 e0 ldi r27, 0x00 ; 0 + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + 3700: c8 2a or r12, r24 + 3702: d9 2a or r13, r25 + 3704: ea 2a or r14, r26 + 3706: fb 2a or r15, r27 + Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; + 3708: 8b 81 ldd r24, Y+3 ; 0x03 + 370a: 93 81 ldd r25, Z+3 ; 0x03 + 370c: 89 27 eor r24, r25 + 370e: 90 e0 ldi r25, 0x00 ; 0 + 3710: a0 e0 ldi r26, 0x00 ; 0 + 3712: b0 e0 ldi r27, 0x00 ; 0 + 3714: b8 2f mov r27, r24 + 3716: aa 27 eor r26, r26 + 3718: 99 27 eor r25, r25 + 371a: 88 27 eor r24, r24 + 371c: c8 2a or r12, r24 + 371e: d9 2a or r13, r25 + 3720: ea 2a or r14, r26 + 3722: fb 2a or r15, r27 + 3724: 10 e2 ldi r17, 0x20 ; 32 + + for (i=0; i<32; i++) { + uint8_t Out = Crypto1FilterOutput(); + 3726: 3b de rcall .-906 ; 0x339e + 3728: 08 2f mov r16, r24 + 372a: 8c 2d mov r24, r12 + + Crypto1LFSR(Temp & 0x01); + 372c: 81 70 andi r24, 0x01 ; 1 + 372e: d0 dd rcall .-1120 ; 0x32d0 + 3730: f6 94 lsr r15 + 3732: e7 94 ror r14 + Temp >>= 1; + 3734: d7 94 ror r13 + 3736: c7 94 ror r12 + 3738: 00 23 and r16, r16 + 373a: 41 f0 breq .+16 ; 0x374c + + /* Store the keystream for later use */ + if (Out) { + 373c: 80 e0 ldi r24, 0x00 ; 0 + 373e: 90 e0 ldi r25, 0x00 ; 0 + Temp |= (uint32_t) 1 << 31; + 3740: a0 e0 ldi r26, 0x00 ; 0 + 3742: b0 e8 ldi r27, 0x80 ; 128 + 3744: c8 2a or r12, r24 + 3746: d9 2a or r13, r25 + 3748: ea 2a or r14, r26 + 374a: fb 2a or r15, r27 + 374c: 11 50 subi r17, 0x01 ; 1 + 374e: 59 f7 brne .-42 ; 0x3726 + 3750: 88 81 ld r24, Y + Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0; + Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8; + Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16; + Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24; + + for (i=0; i<32; i++) { + 3752: 8c 25 eor r24, r12 + } + + /* Crypto1 state register is now set up to be used for authentication. + * In case of nested authentication, we need to use the produced keystream + * to encrypt the CardNonce. For this case we do the encryption in-place. */ + CardNonce[0] ^= (uint8_t) (Temp >> 0); + 3754: 88 83 st Y, r24 + 3756: 89 81 ldd r24, Y+1 ; 0x01 + 3758: 8d 25 eor r24, r13 + CardNonce[1] ^= (uint8_t) (Temp >> 8); + 375a: 89 83 std Y+1, r24 ; 0x01 + 375c: 8a 81 ldd r24, Y+2 ; 0x02 + 375e: 8e 25 eor r24, r14 + CardNonce[2] ^= (uint8_t) (Temp >> 16); + 3760: 8a 83 std Y+2, r24 ; 0x02 + 3762: 8b 81 ldd r24, Y+3 ; 0x03 + 3764: 8f 25 eor r24, r15 + CardNonce[3] ^= (uint8_t) (Temp >> 24); + 3766: 8b 83 std Y+3, r24 ; 0x03 + 3768: df 91 pop r29 + 376a: cf 91 pop r28 +} + 376c: 1f 91 pop r17 + 376e: 0f 91 pop r16 + 3770: ff 90 pop r15 + 3772: ef 90 pop r14 + 3774: df 90 pop r13 + 3776: cf 90 pop r12 + 3778: 08 95 ret + 377a: 40 e4 ldi r20, 0x40 ; 64 + 377c: 3a cf rjmp .-396 ; 0x35f2 + * The inner loop generates 8 even and 8 odd bits from 16 key bits and + * the outer loop stores them. */ + for (i=0; i<(LFSR_SIZE/2); i++) { + uint8_t EvenByte = 0; + uint8_t OddByte = 0; + uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0]; + 377e: 50 e4 ldi r21, 0x40 ; 64 + 3780: 35 cf rjmp .-406 ; 0x35ec + 3782: 20 e4 ldi r18, 0x40 ; 64 + 3784: c6 ce rjmp .-628 ; 0x3512 + 3786: 30 e4 ldi r19, 0x40 ; 64 + 3788: c1 ce rjmp .-638 ; 0x350c + 378a: 20 e4 ldi r18, 0x40 ; 64 + 378c: 52 ce rjmp .-860 ; 0x3432 + 378e: 30 e4 ldi r19, 0x40 ; 64 + 3790: 4d ce rjmp .-870 ; 0x342c + +00003792 : + 3792: cf 92 push r12 + 3794: df 92 push r13 + CardNonce[2] ^= (uint8_t) (Temp >> 16); + CardNonce[3] ^= (uint8_t) (Temp >> 24); +} + +void Crypto1Auth(uint8_t EncryptedReaderNonce[4]) +{ + 3796: ef 92 push r14 + 3798: ff 92 push r15 + 379a: cf 93 push r28 + 379c: fc 01 movw r30, r24 + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + 379e: c1 80 ldd r12, Z+1 ; 0x01 + 37a0: dd 24 eor r13, r13 + 37a2: ee 24 eor r14, r14 + 37a4: ff 24 eor r15, r15 + 37a6: fe 2c mov r15, r14 + 37a8: ed 2c mov r14, r13 + 37aa: dc 2c mov r13, r12 + 37ac: cc 24 eor r12, r12 + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + 37ae: 82 81 ldd r24, Z+2 ; 0x02 + 37b0: 90 e0 ldi r25, 0x00 ; 0 + 37b2: a0 e0 ldi r26, 0x00 ; 0 + 37b4: b0 e0 ldi r27, 0x00 ; 0 + 37b6: dc 01 movw r26, r24 + 37b8: 99 27 eor r25, r25 + 37ba: 88 27 eor r24, r24 + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + 37bc: c8 2a or r12, r24 + 37be: d9 2a or r13, r25 + 37c0: ea 2a or r14, r26 + 37c2: fb 2a or r15, r27 +{ + uint32_t Temp = 0; + + /* For ease of processing, we convert the encrypted reader nonce + * into a 32 bit integer */ + Temp |= (uint32_t) EncryptedReaderNonce[0] << 0; + 37c4: 80 81 ld r24, Z + 37c6: 90 e0 ldi r25, 0x00 ; 0 + 37c8: a0 e0 ldi r26, 0x00 ; 0 + 37ca: b0 e0 ldi r27, 0x00 ; 0 + Temp |= (uint32_t) EncryptedReaderNonce[1] << 8; + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + 37cc: c8 2a or r12, r24 + 37ce: d9 2a or r13, r25 + 37d0: ea 2a or r14, r26 + 37d2: fb 2a or r15, r27 + Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; + 37d4: 83 81 ldd r24, Z+3 ; 0x03 + 37d6: 90 e0 ldi r25, 0x00 ; 0 + 37d8: a0 e0 ldi r26, 0x00 ; 0 + 37da: b0 e0 ldi r27, 0x00 ; 0 + 37dc: b8 2f mov r27, r24 + 37de: aa 27 eor r26, r26 + 37e0: 99 27 eor r25, r25 + 37e2: 88 27 eor r24, r24 + 37e4: c8 2a or r12, r24 + 37e6: d9 2a or r13, r25 + 37e8: ea 2a or r14, r26 + 37ea: fb 2a or r15, r27 + 37ec: c0 e2 ldi r28, 0x20 ; 32 + uint8_t i; + + for (i=0; i<32; i++) { + /* Decrypt one output bit of the given encrypted nonce using the + * filter output as keystream. */ + uint8_t Out = Crypto1FilterOutput(); + 37ee: d7 dd rcall .-1106 ; 0x339e + 37f0: 9c 2d mov r25, r12 + uint8_t Bit = Out ^ (Temp & 0x01); + 37f2: 91 70 andi r25, 0x01 ; 1 + 37f4: 89 27 eor r24, r25 + + /* Feed back the bit to load the LFSR with the (decrypted) nonce */ + Crypto1LFSR(Bit); + 37f6: 6c dd rcall .-1320 ; 0x32d0 + 37f8: f6 94 lsr r15 + 37fa: e7 94 ror r14 + Temp >>= 1; + 37fc: d7 94 ror r13 + 37fe: c7 94 ror r12 + 3800: c1 50 subi r28, 0x01 ; 1 + 3802: a9 f7 brne .-22 ; 0x37ee + 3804: cf 91 pop r28 + Temp |= (uint32_t) EncryptedReaderNonce[2] << 16; + Temp |= (uint32_t) EncryptedReaderNonce[3] << 24; + + uint8_t i; + + for (i=0; i<32; i++) { + 3806: ff 90 pop r15 + + /* Feed back the bit to load the LFSR with the (decrypted) nonce */ + Crypto1LFSR(Bit); + Temp >>= 1; + } +} + 3808: ef 90 pop r14 + 380a: df 90 pop r13 + 380c: cf 90 pop r12 + 380e: 08 95 ret + +00003810 : + 3810: cf 93 push r28 + 3812: df 93 push r29 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 3814: c4 dd rcall .-1144 ; 0x339e + 3816: c8 2f mov r28, r24 + 3818: 80 e0 ldi r24, 0x00 ; 0 + Crypto1LFSR(0); + 381a: 5a dd rcall .-1356 ; 0x32d0 + 381c: cc 23 and r28, r28 + 381e: 09 f4 brne .+2 ; 0x3822 + + /* Store keystream bit */ + KeyStream >>= 1; + + if (Out) { + 3820: 36 c0 rjmp .+108 ; 0x388e + 3822: c0 e8 ldi r28, 0x80 ; 128 + 3824: bc dd rcall .-1160 ; 0x339e + KeyStream |= (1<<7); + 3826: d8 2f mov r29, r24 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 3828: 80 e0 ldi r24, 0x00 ; 0 + 382a: 52 dd rcall .-1372 ; 0x32d0 + 382c: c6 95 lsr r28 + Crypto1LFSR(0); + 382e: d1 11 cpse r29, r1 + 3830: c0 68 ori r28, 0x80 ; 128 + 3832: b5 dd rcall .-1174 ; 0x339e + + /* Store keystream bit */ + KeyStream >>= 1; + 3834: d8 2f mov r29, r24 + + if (Out) { + 3836: 80 e0 ldi r24, 0x00 ; 0 + KeyStream |= (1<<7); + 3838: 4b dd rcall .-1386 ; 0x32d0 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 383a: c6 95 lsr r28 + 383c: d1 11 cpse r29, r1 + 383e: c0 68 ori r28, 0x80 ; 128 + Crypto1LFSR(0); + 3840: ae dd rcall .-1188 ; 0x339e + 3842: d8 2f mov r29, r24 + 3844: 80 e0 ldi r24, 0x00 ; 0 + + /* Store keystream bit */ + KeyStream >>= 1; + 3846: 44 dd rcall .-1400 ; 0x32d0 + + if (Out) { + 3848: c6 95 lsr r28 + KeyStream |= (1<<7); + 384a: d1 11 cpse r29, r1 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 384c: c0 68 ori r28, 0x80 ; 128 + 384e: a7 dd rcall .-1202 ; 0x339e + 3850: d8 2f mov r29, r24 + Crypto1LFSR(0); + 3852: 80 e0 ldi r24, 0x00 ; 0 + 3854: 3d dd rcall .-1414 ; 0x32d0 + 3856: c6 95 lsr r28 + + /* Store keystream bit */ + KeyStream >>= 1; + 3858: d1 11 cpse r29, r1 + + if (Out) { + 385a: c0 68 ori r28, 0x80 ; 128 + KeyStream |= (1<<7); + 385c: a0 dd rcall .-1216 ; 0x339e + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 385e: d8 2f mov r29, r24 + 3860: 80 e0 ldi r24, 0x00 ; 0 + 3862: 36 dd rcall .-1428 ; 0x32d0 + Crypto1LFSR(0); + 3864: c6 95 lsr r28 + 3866: d1 11 cpse r29, r1 + 3868: c0 68 ori r28, 0x80 ; 128 + + /* Store keystream bit */ + KeyStream >>= 1; + 386a: 99 dd rcall .-1230 ; 0x339e + + if (Out) { + 386c: d8 2f mov r29, r24 + KeyStream |= (1<<7); + 386e: 80 e0 ldi r24, 0x00 ; 0 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 3870: 2f dd rcall .-1442 ; 0x32d0 + 3872: c6 95 lsr r28 + 3874: d1 11 cpse r29, r1 + Crypto1LFSR(0); + 3876: c0 68 ori r28, 0x80 ; 128 + 3878: 92 dd rcall .-1244 ; 0x339e + 387a: d8 2f mov r29, r24 + + /* Store keystream bit */ + KeyStream >>= 1; + 387c: 80 e0 ldi r24, 0x00 ; 0 + + if (Out) { + 387e: 28 dd rcall .-1456 ; 0x32d0 + KeyStream |= (1<<7); + 3880: 8c 2f mov r24, r28 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 3882: 86 95 lsr r24 + 3884: d1 11 cpse r29, r1 + 3886: 80 68 ori r24, 0x80 ; 128 + Crypto1LFSR(0); + 3888: df 91 pop r29 + 388a: cf 91 pop r28 + 388c: 08 95 ret + + /* Store keystream bit */ + KeyStream >>= 1; + 388e: c0 e0 ldi r28, 0x00 ; 0 + + if (Out) { + 3890: c9 cf rjmp .-110 ; 0x3824 + +00003892 : + KeyStream |= (1<<7); + 3892: cf 93 push r28 + /* Generate 8 keystream-bits */ + for (i=0; i<8; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 3894: df 93 push r29 + 3896: 83 dd rcall .-1274 ; 0x339e + 3898: c8 2f mov r28, r24 + Crypto1LFSR(0); + 389a: 80 e0 ldi r24, 0x00 ; 0 + 389c: 19 dd rcall .-1486 ; 0x32d0 + 389e: cc 23 and r28, r28 + + /* Store keystream bit */ + KeyStream >>= 1; + 38a0: d1 f0 breq .+52 ; 0x38d6 + 38a2: c8 e0 ldi r28, 0x08 ; 8 + + if (Out) { + 38a4: 7c dd rcall .-1288 ; 0x339e + KeyStream |= (1<<7); + 38a6: d8 2f mov r29, r24 + } + } + + return KeyStream; +} + 38a8: 80 e0 ldi r24, 0x00 ; 0 + 38aa: 12 dd rcall .-1500 ; 0x32d0 + 38ac: c6 95 lsr r28 + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + 38ae: d1 11 cpse r29, r1 + 38b0: c8 60 ori r28, 0x08 ; 8 + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + 38b2: 75 dd rcall .-1302 ; 0x339e + + /* Store keystream bit */ + KeyStream >>= 1; + 38b4: d8 2f mov r29, r24 + + if (Out) { + 38b6: 80 e0 ldi r24, 0x00 ; 0 + KeyStream |= (1<<3); + 38b8: 0b dd rcall .-1514 ; 0x32d0 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 38ba: c6 95 lsr r28 + 38bc: d1 11 cpse r29, r1 + 38be: c8 60 ori r28, 0x08 ; 8 + Crypto1LFSR(0); + 38c0: 6e dd rcall .-1316 ; 0x339e + 38c2: d8 2f mov r29, r24 + 38c4: 80 e0 ldi r24, 0x00 ; 0 + + /* Store keystream bit */ + KeyStream >>= 1; + 38c6: 04 dd rcall .-1528 ; 0x32d0 + + if (Out) { + 38c8: 8c 2f mov r24, r28 + KeyStream |= (1<<3); + 38ca: 86 95 lsr r24 + /* Generate 4 keystream-bits */ + for (i=0; i<4; i++) { + + /* Calculate output of function-network and cycle LFSR with no + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + 38cc: d1 11 cpse r29, r1 + 38ce: 88 60 ori r24, 0x08 ; 8 + 38d0: df 91 pop r29 + Crypto1LFSR(0); + 38d2: cf 91 pop r28 + 38d4: 08 95 ret + 38d6: c0 e0 ldi r28, 0x00 ; 0 + + /* Store keystream bit */ + KeyStream >>= 1; + 38d8: e5 cf rjmp .-54 ; 0x38a4 + +000038da : + 38da: 8f 92 push r8 + + if (Out) { + 38dc: 9f 92 push r9 + KeyStream |= (1<<3); + 38de: af 92 push r10 + } + } + + return KeyStream; +} + 38e0: bf 92 push r11 + 38e2: cf 92 push r12 + 38e4: df 92 push r13 + * additional input, thus linearly! */ + uint8_t Out = Crypto1FilterOutput(); + Crypto1LFSR(0); + + /* Store keystream bit */ + KeyStream >>= 1; + 38e6: ef 92 push r14 + 38e8: ff 92 push r15 + + return KeyStream; +} + +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) +{ + 38ea: 0f 93 push r16 + 38ec: 1f 93 push r17 + 38ee: cf 93 push r28 + 38f0: df 93 push r29 + 38f2: 4c 01 movw r8, r24 + 38f4: 5b 01 movw r10, r22 + while(ClockCount--) { + 38f6: 61 15 cp r22, r1 + 38f8: 71 05 cpc r23, r1 + 38fa: 09 f4 brne .+2 ; 0x38fe + 38fc: 5f c0 rjmp .+190 ; 0x39bc + 38fe: dc 01 movw r26, r24 + 3900: 12 96 adiw r26, 0x02 ; 2 + 3902: cc 91 ld r28, X + 3904: 12 97 sbiw r26, 0x02 ; 2 + 3906: ec 91 ld r30, X + 3908: 11 96 adiw r26, 0x01 ; 1 + 390a: dc 91 ld r29, X + 390c: 11 97 sbiw r26, 0x01 ; 1 + 390e: 13 96 adiw r26, 0x03 ; 3 + 3910: fc 91 ld r31, X + * XOR all tapped bits to a single feedback bit. */ + uint8_t Feedback = 0; + + Feedback ^= State[0] & (uint8_t) (PRNG_MASK >> 0); + Feedback ^= State[1] & (uint8_t) (PRNG_MASK >> 8); + Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); + 3912: 9c 2f mov r25, r28 + 3914: 9d 72 andi r25, 0x2D ; 45 + Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); + + Feedback ^= Feedback >> 4; + 3916: 89 2f mov r24, r25 + 3918: 82 95 swap r24 + 391a: 8f 70 andi r24, 0x0F ; 15 + 391c: 89 27 eor r24, r25 + Feedback ^= Feedback >> 2; + 391e: 28 2f mov r18, r24 + 3920: 26 95 lsr r18 + 3922: 26 95 lsr r18 + 3924: 28 27 eor r18, r24 + Feedback ^= Feedback >> 1; + 3926: 32 2f mov r19, r18 + 3928: 36 95 lsr r19 + + /* For ease of processing convert the state into a 32 bit integer first */ + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + Temp |= (uint32_t) State[1] << 8; + 392a: 8d 2f mov r24, r29 + 392c: 90 e0 ldi r25, 0x00 ; 0 + 392e: a0 e0 ldi r26, 0x00 ; 0 + 3930: b0 e0 ldi r27, 0x00 ; 0 + 3932: ba 2f mov r27, r26 + 3934: a9 2f mov r26, r25 + 3936: 98 2f mov r25, r24 + 3938: 88 27 eor r24, r24 + Temp |= (uint32_t) State[2] << 16; + 393a: 4c 2f mov r20, r28 + 393c: 50 e0 ldi r21, 0x00 ; 0 + 393e: 60 e0 ldi r22, 0x00 ; 0 + 3940: 70 e0 ldi r23, 0x00 ; 0 + 3942: ba 01 movw r22, r20 + 3944: 55 27 eor r21, r21 + 3946: 44 27 eor r20, r20 + + /* For ease of processing convert the state into a 32 bit integer first */ + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + Temp |= (uint32_t) State[1] << 8; + 3948: 84 2b or r24, r20 + 394a: 95 2b or r25, r21 + 394c: a6 2b or r26, r22 + 394e: b7 2b or r27, r23 + Feedback ^= Feedback >> 1; + + /* For ease of processing convert the state into a 32 bit integer first */ + uint32_t Temp = 0; + + Temp |= (uint32_t) State[0] << 0; + 3950: 4e 2f mov r20, r30 + 3952: 50 e0 ldi r21, 0x00 ; 0 + 3954: 60 e0 ldi r22, 0x00 ; 0 + 3956: 70 e0 ldi r23, 0x00 ; 0 + Temp |= (uint32_t) State[1] << 8; + Temp |= (uint32_t) State[2] << 16; + 3958: 84 2b or r24, r20 + 395a: 95 2b or r25, r21 + 395c: a6 2b or r26, r22 + 395e: b7 2b or r27, r23 + Temp |= (uint32_t) State[3] << 24; + 3960: 4f 2f mov r20, r31 + 3962: 50 e0 ldi r21, 0x00 ; 0 + 3964: 60 e0 ldi r22, 0x00 ; 0 + 3966: 70 e0 ldi r23, 0x00 ; 0 + 3968: 74 2f mov r23, r20 + 396a: 66 27 eor r22, r22 + 396c: 55 27 eor r21, r21 + 396e: 44 27 eor r20, r20 + 3970: 84 2b or r24, r20 + 3972: 95 2b or r25, r21 + 3974: a6 2b or r26, r22 + 3976: b7 2b or r27, r23 + + /* Cycle LFSR and feed back. */ + Temp >>= 1; + 3978: b6 95 lsr r27 + 397a: a7 95 ror r26 + 397c: 97 95 ror r25 + 397e: 87 95 ror r24 + Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16); + Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24); + + Feedback ^= Feedback >> 4; + Feedback ^= Feedback >> 2; + Feedback ^= Feedback >> 1; + 3980: 32 27 eor r19, r18 + Temp |= (uint32_t) State[3] << 24; + + /* Cycle LFSR and feed back. */ + Temp >>= 1; + + if (Feedback & 0x01) { + 3982: 30 fd sbrc r19, 0 + Temp |= (uint32_t) 1 << (8 * PRNG_SIZE - 1); + 3984: b0 68 ori r27, 0x80 ; 128 + } + + /* Store back state */ + State[0] = (uint8_t) (Temp >> 0); + 3986: e8 2f mov r30, r24 + State[1] = (uint8_t) (Temp >> 8); + 3988: 49 2f mov r20, r25 + 398a: 5a 2f mov r21, r26 + 398c: 6b 2f mov r22, r27 + 398e: 77 27 eor r23, r23 + 3990: d4 2f mov r29, r20 + State[2] = (uint8_t) (Temp >> 16); + 3992: 8d 01 movw r16, r26 + 3994: 22 27 eor r18, r18 + 3996: 33 27 eor r19, r19 + 3998: c0 2f mov r28, r16 + State[3] = (uint8_t) (Temp >> 24); + 399a: cb 2e mov r12, r27 + 399c: dd 24 eor r13, r13 + 399e: ee 24 eor r14, r14 + 39a0: ff 24 eor r15, r15 + 39a2: fc 2d mov r31, r12 + 39a4: 08 94 sec + 39a6: a1 08 sbc r10, r1 + 39a8: b1 08 sbc r11, r1 + return KeyStream; +} + +void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount) +{ + while(ClockCount--) { + 39aa: a1 14 cp r10, r1 + 39ac: b1 04 cpc r11, r1 + 39ae: 09 f0 breq .+2 ; 0x39b2 + 39b0: b0 cf rjmp .-160 ; 0x3912 + 39b2: f4 01 movw r30, r8 + 39b4: 80 83 st Z, r24 + 39b6: 41 83 std Z+1, r20 ; 0x01 + 39b8: 02 83 std Z+2, r16 ; 0x02 + 39ba: c3 82 std Z+3, r12 ; 0x03 + State[2] = (uint8_t) (Temp >> 16); + State[3] = (uint8_t) (Temp >> 24); + } + + +} + 39bc: df 91 pop r29 + 39be: cf 91 pop r28 + 39c0: 1f 91 pop r17 + 39c2: 0f 91 pop r16 + 39c4: ff 90 pop r15 + 39c6: ef 90 pop r14 + 39c8: df 90 pop r13 + 39ca: cf 90 pop r12 + 39cc: bf 90 pop r11 + 39ce: af 90 pop r10 + 39d0: 9f 90 pop r9 + 39d2: 8f 90 pop r8 + 39d4: 08 95 ret + +000039d6 : +#if !defined(NO_DEVICE_REMOTE_WAKEUP) +bool USB_Device_RemoteWakeupEnabled; +#endif + +void USB_Device_ProcessControlRequest(void) +{ + 39d6: 1f 93 push r17 + 39d8: cf 93 push r28 + 39da: df 93 push r29 + 39dc: cd b7 in r28, 0x3d ; 61 + 39de: de b7 in r29, 0x3e ; 62 + 39e0: ee 97 sbiw r28, 0x3e ; 62 + 39e2: cd bf out 0x3d, r28 ; 61 + 39e4: de bf out 0x3e, r29 ; 62 + USB_ControlRequest.wLength = Endpoint_Read_16_LE(); + #else + uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest; + + for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++) + *(RequestHeader++) = Endpoint_Read_8(); + 39e6: 4d d3 rcall .+1690 ; 0x4082 + 39e8: 80 93 25 23 sts 0x2325, r24 + 39ec: 4a d3 rcall .+1684 ; 0x4082 + 39ee: 80 93 26 23 sts 0x2326, r24 + 39f2: 47 d3 rcall .+1678 ; 0x4082 + 39f4: 80 93 27 23 sts 0x2327, r24 + 39f8: 44 d3 rcall .+1672 ; 0x4082 + 39fa: 80 93 28 23 sts 0x2328, r24 + 39fe: 41 d3 rcall .+1666 ; 0x4082 + 3a00: 80 93 29 23 sts 0x2329, r24 + 3a04: 3e d3 rcall .+1660 ; 0x4082 + 3a06: 80 93 2a 23 sts 0x232A, r24 + 3a0a: 3b d3 rcall .+1654 ; 0x4082 + 3a0c: 80 93 2b 23 sts 0x232B, r24 + 3a10: 38 d3 rcall .+1648 ; 0x4082 + 3a12: 80 93 2c 23 sts 0x232C, r24 + 3a16: 0e 94 70 0b call 0x16e0 ; 0x16e0 + 3a1a: d5 d3 rcall .+1962 ; 0x41c6 + 3a1c: 88 23 and r24, r24 + 3a1e: 91 f0 breq .+36 ; 0x3a44 + 3a20: 90 91 25 23 lds r25, 0x2325 + 3a24: 80 91 26 23 lds r24, 0x2326 + #endif + + EVENT_USB_Device_ControlRequest(); + 3a28: 85 30 cpi r24, 0x05 ; 5 + + if (Endpoint_IsSETUPReceived()) + 3a2a: 09 f4 brne .+2 ; 0x3a2e + 3a2c: 53 c0 rjmp .+166 ; 0x3ad4 + 3a2e: 86 30 cpi r24, 0x06 ; 6 + 3a30: a8 f0 brcs .+42 ; 0x3a5c + { + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + 3a32: 88 30 cpi r24, 0x08 ; 8 + 3a34: 09 f4 brne .+2 ; 0x3a38 + + switch (USB_ControlRequest.bRequest) + 3a36: ba c0 rjmp .+372 ; 0x3bac + 3a38: 89 30 cpi r24, 0x09 ; 9 + 3a3a: 09 f4 brne .+2 ; 0x3a3e + 3a3c: 9e c0 rjmp .+316 ; 0x3b7a + 3a3e: 86 30 cpi r24, 0x06 ; 6 + 3a40: 09 f4 brne .+2 ; 0x3a44 + 3a42: 5d c0 rjmp .+186 ; 0x3afe + 3a44: c0 d3 rcall .+1920 ; 0x41c6 + 3a46: 88 23 and r24, r24 + 3a48: 11 f0 breq .+4 ; 0x3a4e + 3a4a: 91 d3 rcall .+1826 ; 0x416e + 3a4c: 74 d3 rcall .+1768 ; 0x4136 + 3a4e: ee 96 adiw r28, 0x3e ; 62 + 3a50: cd bf out 0x3d, r28 ; 61 + 3a52: de bf out 0x3e, r29 ; 62 + 3a54: df 91 pop r29 + default: + break; + } + } + + if (Endpoint_IsSETUPReceived()) + 3a56: cf 91 pop r28 + 3a58: 1f 91 pop r17 + 3a5a: 08 95 ret + 3a5c: 81 30 cpi r24, 0x01 ; 1 + { + Endpoint_ClearSETUP(); + 3a5e: 29 f0 breq .+10 ; 0x3a6a + 3a60: 81 30 cpi r24, 0x01 ; 1 + Endpoint_StallTransaction(); + 3a62: 08 f4 brcc .+2 ; 0x3a66 + 3a64: 6e c0 rjmp .+220 ; 0x3b42 + } +} + 3a66: 83 30 cpi r24, 0x03 ; 3 + 3a68: 69 f7 brne .-38 ; 0x3a44 + 3a6a: 99 23 and r25, r25 + 3a6c: 09 f4 brne .+2 ; 0x3a70 + 3a6e: a8 c0 rjmp .+336 ; 0x3bc0 + 3a70: 92 30 cpi r25, 0x02 ; 2 + 3a72: 41 f7 brne .-48 ; 0x3a44 + + if (Endpoint_IsSETUPReceived()) + { + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + + switch (USB_ControlRequest.bRequest) + 3a74: 80 91 27 23 lds r24, 0x2327 + 3a78: 88 23 and r24, r24 + 3a7a: 39 f5 brne .+78 ; 0x3aca + 3a7c: 10 91 29 23 lds r17, 0x2329 + 3a80: 1f 70 andi r17, 0x0F ; 15 + } + + break; + case REQ_ClearFeature: + case REQ_SetFeature: + if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) || + 3a82: 01 f3 breq .-64 ; 0x3a44 + 3a84: 81 2f mov r24, r17 + 3a86: 1b d3 rcall .+1590 ; 0x40be + 3a88: 80 91 26 23 lds r24, 0x2326 + + break; + #endif + #if !defined(CONTROL_ONLY_DEVICE) + case REQREC_ENDPOINT: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt) + 3a8c: 83 30 cpi r24, 0x03 ; 3 + 3a8e: 09 f4 brne .+2 ; 0x3a92 + 3a90: f8 c0 rjmp .+496 ; 0x3c82 + 3a92: e0 91 2f 23 lds r30, 0x232F + { + uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + 3a96: f0 91 30 23 lds r31, 0x2330 + + if (EndpointIndex == ENDPOINT_CONTROLEP) + 3a9a: 81 81 ldd r24, Z+1 ; 0x01 + return; + + Endpoint_SelectEndpoint(EndpointIndex); + 3a9c: 8b 7f andi r24, 0xFB ; 251 + 3a9e: 81 83 std Z+1, r24 ; 0x01 + 3aa0: 21 2f mov r18, r17 + + if (Endpoint_IsEnabled()) + { + if (USB_ControlRequest.bRequest == REQ_SetFeature) + 3aa2: 30 e0 ldi r19, 0x00 ; 0 + 3aa4: 84 e8 ldi r24, 0x84 ; 132 + 3aa6: 90 e0 ldi r25, 0x00 ; 0 + 3aa8: 28 9f mul r18, r24 + 3aaa: f0 01 movw r30, r0 + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearStall(void) + { + USB_Endpoint_SelectedHandle->CTRL &= ~USB_EP_STALL_bm; + 3aac: 29 9f mul r18, r25 + 3aae: f0 0d add r31, r0 + 3ab0: 38 9f mul r19, r24 + 3ab2: f0 0d add r31, r0 + 3ab4: 11 24 eor r1, r1 + 3ab6: ed 58 subi r30, 0x8D ; 141 + 3ab8: fc 4d sbci r31, 0xDC ; 220 + static inline void Endpoint_ResetEndpoint(const uint8_t Address) + { + if (Address & ENDPOINT_DIR_IN) + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].IN.Position = 0; + else + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].OUT.Position = 0; + 3aba: 10 82 st Z, r1 + 3abc: e0 91 2f 23 lds r30, 0x232F + 3ac0: f0 91 30 23 lds r31, 0x2330 + 3ac4: 80 81 ld r24, Z + 3ac6: 8e 7f andi r24, 0xFE ; 254 + 3ac8: 80 83 st Z, r24 + 3aca: 80 e0 ldi r24, 0x00 ; 0 + 3acc: f8 d2 rcall .+1520 ; 0x40be + 3ace: 4f d3 rcall .+1694 ; 0x416e + 3ad0: a8 d4 rcall .+2384 ; 0x4422 + 3ad2: b8 cf rjmp .-144 ; 0x3a44 + 3ad4: 99 23 and r25, r25 + + /** Resets the data toggle of the currently selected endpoint. */ + static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetDataToggle(void) + { + USB_Endpoint_SelectedHandle->STATUS &= ~USB_EP_TOGGLE_bm; + 3ad6: 09 f0 breq .+2 ; 0x3ada + 3ad8: b5 cf rjmp .-150 ; 0x3a44 + 3ada: 10 91 27 23 lds r17, 0x2327 + 3ade: 1f 77 andi r17, 0x7F ; 127 + 3ae0: 46 d3 rcall .+1676 ; 0x416e + 3ae2: 9f d4 rcall .+2366 ; 0x4422 + #endif + default: + return; + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 3ae4: a0 d3 rcall .+1856 ; 0x4226 + 3ae6: 88 23 and r24, r24 + 3ae8: e9 f3 breq .-6 ; 0x3ae4 + + Endpoint_ClearSETUP(); + 3aea: e0 ec ldi r30, 0xC0 ; 192 + 3aec: f4 e0 ldi r31, 0x04 ; 4 + + Endpoint_ClearStatusStage(); + 3aee: 13 83 std Z+3, r17 ; 0x03 + 3af0: 11 23 and r17, r17 + 3af2: 09 f0 breq .+2 ; 0x3af6 + USB_Device_ClearSetFeature(); + } + + break; + case REQ_SetAddress: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + 3af4: 7a c0 rjmp .+244 ; 0x3bea + 3af6: 82 e0 ldi r24, 0x02 ; 2 + 3af8: 80 93 24 23 sts 0x2324, r24 + } +} + +static void USB_Device_SetAddress(void) +{ + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + 3afc: a3 cf rjmp .-186 ; 0x3a44 + 3afe: 90 58 subi r25, 0x80 ; 128 + + USB_Device_SetDeviceAddress(DeviceAddress); + + Endpoint_ClearSETUP(); + 3b00: 92 30 cpi r25, 0x02 ; 2 + 3b02: 08 f0 brcs .+2 ; 0x3b06 + + Endpoint_ClearStatusStage(); + 3b04: 9f cf rjmp .-194 ; 0x3a44 + 3b06: 80 91 27 23 lds r24, 0x2327 + + while (!(Endpoint_IsINReady())); + 3b0a: 90 91 28 23 lds r25, 0x2328 + 3b0e: 23 e0 ldi r18, 0x03 ; 3 + } + + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) + { + USB.ADDR = Address; + 3b10: 8c 3d cpi r24, 0xDC ; 220 + 3b12: 92 07 cpc r25, r18 + 3b14: 09 f4 brne .+2 ; 0x3b18 + + USB_Device_EnableDeviceAddress(DeviceAddress); + + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + 3b16: 6b c0 rjmp .+214 ; 0x3bee + 3b18: 60 91 29 23 lds r22, 0x2329 + 3b1c: ae 01 movw r20, r28 + 3b1e: 4f 5f subi r20, 0xFF ; 255 + 3b20: 5f 4f sbci r21, 0xFF ; 255 + 3b22: 0e 94 7a 03 call 0x6f4 ; 0x6f4 + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_SetAddress(); + + break; + case REQ_GetDescriptor: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + 3b26: bc 01 movw r22, r24 + 3b28: 00 97 sbiw r24, 0x00 ; 0 + 3b2a: 09 f4 brne .+2 ; 0x3b2e + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + uint8_t DescriptorAddressSpace; + #endif + + #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL)) + 3b2c: 8b cf rjmp .-234 ; 0x3a44 + 3b2e: 8d af sts 0x7d, r24 + 3b30: 7e af sts 0x7e, r23 + 3b32: 1d d3 rcall .+1594 ; 0x416e + 3b34: 89 81 ldd r24, Y+1 ; 0x01 + 3b36: 9a 81 ldd r25, Y+2 ; 0x02 + 3b38: 6d ad sts 0x6d, r22 + 3b3a: 7e ad sts 0x6e, r23 + 3b3c: ca d1 rcall .+916 ; 0x3ed2 + USB_Device_GetInternalSerialDescriptor(); + return; + } + #endif + + if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, + 3b3e: 92 d2 rcall .+1316 ; 0x4064 + 3b40: 81 cf rjmp .-254 ; 0x3a44 + 3b42: 90 38 cpi r25, 0x80 ; 128 + 3b44: 09 f4 brne .+2 ; 0x3b48 + 3b46: 48 c0 rjmp .+144 ; 0x3bd8 + 3b48: 92 38 cpi r25, 0x82 ; 130 + 3b4a: 09 f0 breq .+2 ; 0x3b4e + 3b4c: 7b cf rjmp .-266 ; 0x3a44 + 3b4e: 80 91 29 23 lds r24, 0x2329 + 3b52: 8f 70 andi r24, 0x0F ; 15 + )) == NO_DESCRIPTOR) + { + return; + } + + Endpoint_ClearSETUP(); + 3b54: b4 d2 rcall .+1384 ; 0x40be + 3b56: e0 91 2f 23 lds r30, 0x232F + 3b5a: f0 91 30 23 lds r31, 0x2330 + #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE) + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_EEPROM_DESCRIPTORS) + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_FLASH_DESCRIPTORS) + Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); + 3b5e: 81 81 ldd r24, Z+1 ; 0x01 + 3b60: 11 e0 ldi r17, 0x01 ; 1 + 3b62: 82 ff sbrs r24, 2 + 3b64: 10 e0 ldi r17, 0x00 ; 0 + 3b66: 80 e0 ldi r24, 0x00 ; 0 + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + else + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #endif + + Endpoint_ClearOUT(); + 3b68: aa d2 rcall .+1364 ; 0x40be + 3b6a: 01 d3 rcall .+1538 ; 0x416e + 3b6c: 81 2f mov r24, r17 + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + + switch (USB_ControlRequest.bRequest) + { + case REQ_GetStatus: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + 3b6e: 98 d2 rcall .+1328 ; 0x40a0 + 3b70: 80 e0 ldi r24, 0x00 ; 0 + 3b72: 96 d2 rcall .+1324 ; 0x40a0 + 3b74: 5e d2 rcall .+1212 ; 0x4032 + 3b76: 55 d4 rcall .+2218 ; 0x4422 + 3b78: 65 cf rjmp .-310 ; 0x3a44 + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + #endif + break; + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): + #if !defined(CONTROL_ONLY_DEVICE) + Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + 3b7a: 99 23 and r25, r25 + 3b7c: 09 f0 breq .+2 ; 0x3b80 + 3b7e: 62 cf rjmp .-316 ; 0x3a44 + 3b80: 80 91 27 23 lds r24, 0x2327 + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); + 3b84: 82 30 cpi r24, 0x02 ; 2 + 3b86: 08 f0 brcs .+2 ; 0x3b8a + 3b88: 5d cf rjmp .-326 ; 0x3a44 + 3b8a: f1 d2 rcall .+1506 ; 0x416e + 3b8c: 80 91 27 23 lds r24, 0x2327 + + CurrentStatus = Endpoint_IsStalled(); + 3b90: 80 93 20 23 sts 0x2320, r24 + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 3b94: 46 d4 rcall .+2188 ; 0x4422 + 3b96: 80 91 20 23 lds r24, 0x2320 + break; + default: + return; + } + + Endpoint_ClearSETUP(); + 3b9a: 88 23 and r24, r24 + 3b9c: 09 f4 brne .+2 ; 0x3ba0 + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_LE(const uint16_t Data) + { + Endpoint_Write_8(Data & 0xFF); + 3b9e: 67 c0 rjmp .+206 ; 0x3c6e + 3ba0: 84 e0 ldi r24, 0x04 ; 4 + 3ba2: 80 93 24 23 sts 0x2324, r24 + Endpoint_Write_8(Data >> 8); + 3ba6: 0e 94 6c 0b call 0x16d8 ; 0x16d8 + + Endpoint_Write_16_LE(CurrentStatus); + Endpoint_ClearIN(); + 3baa: 4c cf rjmp .-360 ; 0x3a44 + 3bac: 90 38 cpi r25, 0x80 ; 128 + + Endpoint_ClearStatusStage(); + 3bae: 09 f0 breq .+2 ; 0x3bb2 + 3bb0: 49 cf rjmp .-366 ; 0x3a44 + 3bb2: dd d2 rcall .+1466 ; 0x416e + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_GetConfiguration(); + + break; + case REQ_SetConfiguration: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + 3bb4: 80 91 20 23 lds r24, 0x2320 + 3bb8: 73 d2 rcall .+1254 ; 0x40a0 +} + +static void USB_Device_SetConfiguration(void) +{ + #if defined(FIXED_NUM_CONFIGURATIONS) + if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS) + 3bba: 3b d2 rcall .+1142 ; 0x4032 + 3bbc: 32 d4 rcall .+2148 ; 0x4422 + 3bbe: 42 cf rjmp .-380 ; 0x3a44 + 3bc0: 90 91 27 23 lds r25, 0x2327 + if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations) + return; + #endif + #endif + + Endpoint_ClearSETUP(); + 3bc4: 91 30 cpi r25, 0x01 ; 1 + 3bc6: 09 f0 breq .+2 ; 0x3bca + + USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue; + 3bc8: 3d cf rjmp .-390 ; 0x3a44 + 3bca: 91 e0 ldi r25, 0x01 ; 1 + 3bcc: 83 30 cpi r24, 0x03 ; 3 + 3bce: 09 f0 breq .+2 ; 0x3bd2 + + Endpoint_ClearStatusStage(); + 3bd0: 90 e0 ldi r25, 0x00 ; 0 + 3bd2: 90 93 22 23 sts 0x2322, r25 + + if (USB_Device_ConfigurationNumber) + 3bd6: 79 cf rjmp .-270 ; 0x3aca + 3bd8: 10 91 21 23 lds r17, 0x2321 + 3bdc: 80 91 22 23 lds r24, 0x2322 + USB_DeviceState = DEVICE_STATE_Configured; + 3be0: 88 23 and r24, r24 + 3be2: 09 f4 brne .+2 ; 0x3be6 + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + EVENT_USB_Device_ConfigurationChanged(); + 3be4: c2 cf rjmp .-124 ; 0x3b6a + 3be6: 12 60 ori r17, 0x02 ; 2 + 3be8: c0 cf rjmp .-128 ; 0x3b6a + USB_Device_GetDescriptor(); + } + + break; + case REQ_GetConfiguration: + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + 3bea: 83 e0 ldi r24, 0x03 ; 3 + 3bec: 85 cf rjmp .-246 ; 0x3af8 + 3bee: 83 e0 ldi r24, 0x03 ; 3 + EVENT_USB_Device_ConfigurationChanged(); +} + +static void USB_Device_GetConfiguration(void) +{ + Endpoint_ClearSETUP(); + 3bf0: 8c 83 std Y+4, r24 ; 0x04 + 3bf2: 8a e3 ldi r24, 0x3A ; 58 + + Endpoint_Write_8(USB_Device_ConfigurationNumber); + 3bf4: 8b 83 std Y+3, r24 ; 0x03 + 3bf6: 6f b7 in r22, 0x3f ; 63 + 3bf8: f8 94 cli + 3bfa: a0 ec ldi r26, 0xC0 ; 192 + Endpoint_ClearIN(); + 3bfc: b1 e0 ldi r27, 0x01 ; 1 + 3bfe: 82 e0 ldi r24, 0x02 ; 2 + + Endpoint_ClearStatusStage(); + 3c00: 1a 96 adiw r26, 0x0a ; 10 + 3c02: 8c 93 st X, r24 + 3c04: 1a 97 sbiw r26, 0x0a ; 10 +{ + switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) + { + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + case REQREC_DEVICE: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup) + 3c06: e8 e0 ldi r30, 0x08 ; 8 + 3c08: f0 e0 ldi r31, 0x00 ; 0 + 3c0a: 24 91 lpm r18, Z + 3c0c: 1a 96 adiw r26, 0x0a ; 10 + 3c0e: 1c 92 st X, r1 + USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature); + 3c10: de 01 movw r26, r28 + 3c12: 15 96 adiw r26, 0x05 ; 5 + 3c14: 81 e0 ldi r24, 0x01 ; 1 + 3c16: 90 e0 ldi r25, 0x00 ; 0 + 3c18: 78 e0 ldi r23, 0x08 ; 8 + 3c1a: 40 ec ldi r20, 0xC0 ; 192 + 3c1c: 51 e0 ldi r21, 0x01 ; 1 + Endpoint_ClearOUT(); +} + +static void USB_Device_GetStatus(void) +{ + uint8_t CurrentStatus = 0; + 3c1e: 12 e0 ldi r17, 0x02 ; 2 + 3c20: e2 2f mov r30, r18 + if (USB_Device_CurrentlySelfPowered) + CurrentStatus |= FEATURE_SELFPOWERED_ENABLED; + #endif + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + if (USB_Device_RemoteWakeupEnabled) + 3c22: ef 70 andi r30, 0x0F ; 15 + 3c24: 2e 2f mov r18, r30 + 3c26: 30 e0 ldi r19, 0x00 ; 0 + 3c28: ea 30 cpi r30, 0x0A ; 10 + 3c2a: a8 f0 brcs .+42 ; 0x3c56 + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + 3c2c: 29 5c subi r18, 0xC9 ; 201 + 3c2e: 3f 4f sbci r19, 0xFF ; 255 + + while (!(Endpoint_IsINReady())); + + USB_Device_EnableDeviceAddress(DeviceAddress); + + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + 3c30: 2d 93 st X+, r18 + 3c32: 3d 93 st X+, r19 + { + USB_Descriptor_Header_t Header; + uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4]; + } SignatureDescriptor; + + SignatureDescriptor.Header.Type = DTYPE_String; + 3c34: 8c 31 cpi r24, 0x1C ; 28 + 3c36: 91 05 cpc r25, r1 + SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4); + 3c38: 89 f0 breq .+34 ; 0x3c5c + 3c3a: fa 01 movw r30, r20 + #if (ARCH == ARCH_AVR8) + return SREG; + #elif (ARCH == ARCH_UC3) + return __builtin_mfsr(AVR32_SR); + #elif (ARCH == ARCH_XMEGA) + return SREG; + 3c3c: 12 87 std Z+10, r17 ; 0x0a + #if (ARCH == ARCH_AVR8) + cli(); + #elif (ARCH == ARCH_UC3) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + cli(); + 3c3e: e7 2f mov r30, r23 + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 3c40: f0 e0 ldi r31, 0x00 ; 0 + 3c42: 24 91 lpm r18, Z + 3c44: fa 01 movw r30, r20 + 3c46: 12 86 std Z+10, r1 ; 0x0a + 3c48: 80 ff sbrs r24, 0 + 3c4a: 03 c0 rjmp .+6 ; 0x3c52 + SerialByte = pgm_read_byte(SigReadAddress); + 3c4c: 22 95 swap r18 + 3c4e: 2f 70 andi r18, 0x0F ; 15 + 3c50: 7f 5f subi r23, 0xFF ; 255 + NVM.CMD = 0; + 3c52: 01 96 adiw r24, 0x01 ; 1 + 3c54: e5 cf rjmp .-54 ; 0x3c20 + +#if !defined(NO_DEVICE_REMOTE_WAKEUP) +bool USB_Device_RemoteWakeupEnabled; +#endif + +void USB_Device_ProcessControlRequest(void) + 3c56: 20 5d subi r18, 0xD0 ; 208 + 3c58: 3f 4f sbci r19, 0xFF ; 255 + 3c5a: ea cf rjmp .-44 ; 0x3c30 + 3c5c: 6f bf out 0x3f, r22 ; 63 + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) + { + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + 3c5e: 87 d2 rcall .+1294 ; 0x416e + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 3c60: ce 01 movw r24, r28 + 3c62: 03 96 adiw r24, 0x03 ; 3 + 3c64: 6a e3 ldi r22, 0x3A ; 58 + { + SerialByte >>= 4; + SigReadAddress++; + } + + SerialByte &= 0x0F; + 3c66: 70 e0 ldi r23, 0x00 ; 0 + 3c68: 8f d0 rcall .+286 ; 0x3d88 + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + 3c6a: fc d1 rcall .+1016 ; 0x4064 + 3c6c: eb ce rjmp .-554 ; 0x3a44 + 3c6e: 80 91 c3 04 lds r24, 0x04C3 + 3c72: 88 23 and r24, r24 + 3c74: 21 f0 breq .+8 ; 0x3c7e + 3c76: 84 e0 ldi r24, 0x04 ; 4 + 3c78: 80 93 24 23 sts 0x2324, r24 + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + 3c7c: 94 cf rjmp .-216 ; 0x3ba6 + 3c7e: 81 e0 ldi r24, 0x01 ; 1 + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 3c80: fb cf rjmp .-10 ; 0x3c78 + 3c82: 59 d2 rcall .+1202 ; 0x4136 + SerialByte = pgm_read_byte(SigReadAddress); + 3c84: 22 cf rjmp .-444 ; 0x3aca + +00003c86 : +#include "Events.h" + +void USB_Event_Stub(void) +{ + +} + 3c86: 08 95 ret + +00003c88 : +#if defined(USB_CAN_BE_DEVICE) && !defined(DEVICE_STATE_AS_GPIOR) +volatile uint8_t USB_DeviceState; +#endif + +void USB_USBTask(void) +{ + 3c88: cf 93 push r28 +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_DeviceTask(void) +{ + if (USB_DeviceState == DEVICE_STATE_Unattached) + 3c8a: 80 91 24 23 lds r24, 0x2324 + 3c8e: 88 23 and r24, r24 + 3c90: 11 f4 brne .+4 ; 0x3c96 + #elif defined(USB_CAN_BE_HOST) + USB_HostTask(); + #elif defined(USB_CAN_BE_DEVICE) + USB_DeviceTask(); + #endif +} + 3c92: cf 91 pop r28 + 3c94: 08 95 ret + * \return Index of the currently selected endpoint. + */ + static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetCurrentEndpoint(void) + { + return USB_Endpoint_SelectedEndpoint; + 3c96: c0 91 31 23 lds r28, 0x2331 + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + + uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + 3c9a: 80 e0 ldi r24, 0x00 ; 0 + 3c9c: 10 d2 rcall .+1056 ; 0x40be + 3c9e: 93 d2 rcall .+1318 ; 0x41c6 + + if (Endpoint_IsSETUPReceived()) + 3ca0: 88 23 and r24, r24 + 3ca2: 21 f4 brne .+8 ; 0x3cac + 3ca4: 8c 2f mov r24, r28 + 3ca6: 0b d2 rcall .+1046 ; 0x40be + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(PrevEndpoint); + 3ca8: cf 91 pop r28 + 3caa: 08 95 ret + 3cac: 94 de rcall .-728 ; 0x39d6 + #elif defined(USB_CAN_BE_HOST) + USB_HostTask(); + #elif defined(USB_CAN_BE_DEVICE) + USB_DeviceTask(); + #endif +} + 3cae: fa cf rjmp .-12 ; 0x3ca4 + +00003cb0 : +#if defined(TEMPLATE_FUNC_NAME) + +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + 3cb0: af 92 push r10 + 3cb2: bf 92 push r11 + 3cb4: cf 92 push r12 + 3cb6: df 92 push r13 + 3cb8: ff 92 push r15 + 3cba: 0f 93 push r16 + 3cbc: 1f 93 push r17 + 3cbe: cf 93 push r28 + 3cc0: df 93 push r29 + 3cc2: ec 01 movw r28, r24 + 3cc4: 8b 01 movw r16, r22 + 3cc6: 6a 01 movw r12, r20 + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + 3cc8: c2 d3 rcall .+1924 ; 0x444e + 3cca: f8 2e mov r15, r24 + 3ccc: 88 23 and r24, r24 + 3cce: 61 f5 brne .+88 ; 0x3d28 + 3cd0: c1 14 cp r12, r1 + return ErrorCode; + + if (BytesProcessed != NULL) + 3cd2: d1 04 cpc r13, r1 + 3cd4: 39 f0 breq .+14 ; 0x3ce4 + 3cd6: f6 01 movw r30, r12 + { + Length -= *BytesProcessed; + 3cd8: 80 81 ld r24, Z + 3cda: 91 81 ldd r25, Z+1 ; 0x01 + 3cdc: 08 1b sub r16, r24 + 3cde: 19 0b sbc r17, r25 + 3ce0: c8 0f add r28, r24 + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + 3ce2: d9 1f adc r29, r25 + 3ce4: 01 15 cp r16, r1 + } + + while (Length) + 3ce6: 11 05 cpc r17, r1 + 3ce8: f9 f0 breq .+62 ; 0x3d28 + 3cea: c1 14 cp r12, r1 + 3cec: d1 04 cpc r13, r1 + 3cee: 41 f0 breq .+16 ; 0x3d00 + 3cf0: 26 c0 rjmp .+76 ; 0x3d3e + 3cf2: 89 91 ld r24, Y+ + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + 3cf4: d5 d1 rcall .+938 ; 0x40a0 + 3cf6: 01 50 subi r16, 0x01 ; 1 + 3cf8: 10 40 sbci r17, 0x00 ; 0 + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + 3cfa: 01 15 cp r16, r1 + 3cfc: 11 05 cpc r17, r1 + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + 3cfe: a1 f0 breq .+40 ; 0x3d28 + 3d00: 80 91 2d 23 lds r24, 0x232D + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length); + 3d04: 90 91 2e 23 lds r25, 0x232E + 3d08: fc 01 movw r30, r24 + 3d0a: ef 5b subi r30, 0xBF ; 191 + 3d0c: ff 4f sbci r31, 0xFF ; 255 + 3d0e: 20 81 ld r18, Z + 3d10: 80 5c subi r24, 0xC0 ; 192 + 3d12: 9f 4f sbci r25, 0xFF ; 255 + 3d14: fc 01 movw r30, r24 + 3d16: 80 81 ld r24, Z + 3d18: 28 17 cp r18, r24 + 3d1a: 58 f3 brcs .-42 ; 0x3cf2 + { + if (!(Endpoint_IsReadWriteAllowed())) + 3d1c: 8a d1 rcall .+788 ; 0x4032 + 3d1e: b4 df rcall .-152 ; 0x3c88 + { + TEMPLATE_CLEAR_ENDPOINT(); + 3d20: 96 d3 rcall .+1836 ; 0x444e + 3d22: 88 23 and r24, r24 + + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + 3d24: 51 f3 breq .-44 ; 0x3cfa + 3d26: f8 2e mov r15, r24 + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + 3d28: 8f 2d mov r24, r15 + 3d2a: df 91 pop r29 + 3d2c: cf 91 pop r28 + 3d2e: 1f 91 pop r17 + 3d30: 0f 91 pop r16 + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + 3d32: ff 90 pop r15 + 3d34: df 90 pop r13 + 3d36: cf 90 pop r12 + 3d38: bf 90 pop r11 + 3d3a: af 90 pop r10 + 3d3c: 08 95 ret + 3d3e: aa 24 eor r10, r10 + 3d40: bb 24 eor r11, r11 + 3d42: 80 91 2d 23 lds r24, 0x232D + 3d46: 90 91 2e 23 lds r25, 0x232E + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + 3d4a: fc 01 movw r30, r24 + 3d4c: ef 5b subi r30, 0xBF ; 191 + 3d4e: ff 4f sbci r31, 0xFF ; 255 + 3d50: 20 81 ld r18, Z + 3d52: fc 01 movw r30, r24 + 3d54: e0 5c subi r30, 0xC0 ; 192 + 3d56: ff 4f sbci r31, 0xFF ; 255 + 3d58: 80 81 ld r24, Z + 3d5a: 28 17 cp r18, r24 + 3d5c: 60 f0 brcs .+24 ; 0x3d76 + 3d5e: 69 d1 rcall .+722 ; 0x4032 + 3d60: 93 df rcall .-218 ; 0x3c88 + 3d62: f6 01 movw r30, r12 + { + if (!(Endpoint_IsReadWriteAllowed())) + 3d64: 80 81 ld r24, Z + 3d66: 91 81 ldd r25, Z+1 ; 0x01 + { + TEMPLATE_CLEAR_ENDPOINT(); + 3d68: 8a 0d add r24, r10 + 3d6a: 9b 1d adc r25, r11 + + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + 3d6c: 80 83 st Z, r24 + 3d6e: 91 83 std Z+1, r25 ; 0x01 + #endif + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + 3d70: 25 e0 ldi r18, 0x05 ; 5 + 3d72: f2 2e mov r15, r18 + 3d74: d9 cf rjmp .-78 ; 0x3d28 + 3d76: 89 91 ld r24, Y+ + 3d78: 93 d1 rcall .+806 ; 0x40a0 + 3d7a: 08 94 sec + 3d7c: a1 1c adc r10, r1 + return ENDPOINT_RWSTREAM_IncompleteTransfer; + 3d7e: b1 1c adc r11, r1 + 3d80: 0a 15 cp r16, r10 + 3d82: 1b 05 cpc r17, r11 + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + 3d84: f1 f6 brne .-68 ; 0x3d42 + 3d86: d0 cf rjmp .-96 ; 0x3d28 + +00003d88 : + 3d88: cf 92 push r12 + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + 3d8a: df 92 push r13 + 3d8c: ef 92 push r14 + 3d8e: ff 92 push r15 + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + 3d90: 0f 93 push r16 + 3d92: 1f 93 push r17 + 3d94: cf 93 push r28 + 3d96: df 93 push r29 + +#if defined(TEMPLATE_FUNC_NAME) + +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + 3d98: d8 2e mov r13, r24 + 3d9a: c9 2e mov r12, r25 + 3d9c: eb 01 movw r28, r22 + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 3d9e: 80 91 31 23 lds r24, 0x2331 + 3da2: 80 68 ori r24, 0x80 ; 128 + 3da4: 8c d1 rcall .+792 ; 0x40be + 3da6: e0 90 2b 23 lds r14, 0x232B + + if (Length > USB_ControlRequest.wLength) + 3daa: f0 90 2c 23 lds r15, 0x232C + 3dae: ec 16 cp r14, r28 + 3db0: fd 06 cpc r15, r29 + 3db2: 20 f0 brcs .+8 ; 0x3dbc + 3db4: 20 97 sbiw r28, 0x00 ; 0 + Length = USB_ControlRequest.wLength; + else if (!(Length)) + 3db6: 09 f4 brne .+2 ; 0x3dba + 3db8: 86 c0 rjmp .+268 ; 0x3ec6 + 3dba: 7e 01 movw r14, r28 + 3dbc: 00 e0 ldi r16, 0x00 ; 0 + 3dbe: e1 14 cp r14, r1 + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + 3dc0: f1 04 cpc r15, r1 + 3dc2: 09 f0 breq .+2 ; 0x3dc6 + 3dc4: 4c c0 rjmp .+152 ; 0x3e5e + 3dc6: 00 23 and r16, r16 + 3dc8: 09 f4 brne .+2 ; 0x3dcc + 3dca: 5f c0 rjmp .+190 ; 0x3e8a + 3dcc: 80 91 24 23 lds r24, 0x2324 + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3dd0: 88 23 and r24, r24 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3dd2: 09 f4 brne .+2 ; 0x3dd6 + 3dd4: 58 c0 rjmp .+176 ; 0x3e86 + 3dd6: 85 30 cpi r24, 0x05 ; 5 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 3dd8: 09 f4 brne .+2 ; 0x3ddc + 3dda: 60 c0 rjmp .+192 ; 0x3e9c + 3ddc: f4 d1 rcall .+1000 ; 0x41c6 + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 3dde: 88 23 and r24, r24 + 3de0: 09 f0 breq .+2 ; 0x3de4 + 3de2: 6f c0 rjmp .+222 ; 0x3ec2 + 3de4: 08 d2 rcall .+1040 ; 0x41f6 + 3de6: 88 23 and r24, r24 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 3de8: 09 f0 breq .+2 ; 0x3dec + 3dea: 4f c0 rjmp .+158 ; 0x3e8a + 3dec: 1c d2 rcall .+1080 ; 0x4226 + 3dee: 88 23 and r24, r24 + 3df0: 69 f3 breq .-38 ; 0x3dcc + break; + + if (Endpoint_IsINReady()) + 3df2: 80 91 31 23 lds r24, 0x2331 + 3df6: 87 fd sbrc r24, 7 + 3df8: 5b c0 rjmp .+182 ; 0x3eb0 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 3dfa: 80 91 2d 23 lds r24, 0x232D + 3dfe: 90 91 2e 23 lds r25, 0x232E + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 3e02: fc 01 movw r30, r24 + 3e04: e0 5c subi r30, 0xC0 ; 192 + 3e06: ff 4f sbci r31, 0xFF ; 255 + 3e08: c0 81 ld r28, Z + 3e0a: 8f 5b subi r24, 0xBF ; 191 + 3e0c: 9f 4f sbci r25, 0xFF ; 255 + 3e0e: fc 01 movw r30, r24 + 3e10: 80 81 ld r24, Z + 3e12: d0 e0 ldi r29, 0x00 ; 0 + 3e14: c8 1b sub r28, r24 + 3e16: d1 09 sbc r29, r1 + 3e18: e1 14 cp r14, r1 + 3e1a: f1 04 cpc r15, r1 + 3e1c: b1 f0 breq .+44 ; 0x3e4a + 3e1e: c8 30 cpi r28, 0x08 ; 8 + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 3e20: d1 05 cpc r29, r1 + 3e22: 98 f4 brcc .+38 ; 0x3e4a + 3e24: 0d 2d mov r16, r13 + 3e26: 1c 2d mov r17, r12 + 3e28: 03 c0 rjmp .+6 ; 0x3e30 + 3e2a: c8 30 cpi r28, 0x08 ; 8 + 3e2c: d1 05 cpc r29, r1 + 3e2e: 69 f0 breq .+26 ; 0x3e4a + 3e30: f8 01 movw r30, r16 + 3e32: 81 91 ld r24, Z+ + 3e34: 8f 01 movw r16, r30 + 3e36: 34 d1 rcall .+616 ; 0x40a0 + { + TEMPLATE_TRANSFER_BYTE(DataStream); + 3e38: d0 2e mov r13, r16 + 3e3a: c1 2e mov r12, r17 + 3e3c: 08 94 sec + 3e3e: e1 08 sbc r14, r1 + 3e40: f1 08 sbc r15, r1 + TEMPLATE_BUFFER_MOVE(DataStream, 1); + 3e42: 21 96 adiw r28, 0x01 ; 1 + 3e44: e1 14 cp r14, r1 + Length--; + 3e46: f1 04 cpc r15, r1 + 3e48: 81 f7 brne .-32 ; 0x3e2a + 3e4a: 01 e0 ldi r16, 0x01 ; 1 + BytesInEndpoint++; + 3e4c: c8 30 cpi r28, 0x08 ; 8 + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 3e4e: d1 05 cpc r29, r1 + 3e50: 09 f0 breq .+2 ; 0x3e54 + 3e52: 00 e0 ldi r16, 0x00 ; 0 + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + 3e54: ee d0 rcall .+476 ; 0x4032 + 3e56: e1 14 cp r14, r1 + 3e58: f1 04 cpc r15, r1 + 3e5a: 09 f4 brne .+2 ; 0x3e5e + 3e5c: b4 cf rjmp .-152 ; 0x3dc6 + Endpoint_ClearIN(); + 3e5e: 80 91 24 23 lds r24, 0x2324 + 3e62: 88 23 and r24, r24 + 3e64: 81 f0 breq .+32 ; 0x3e86 + 3e66: 85 30 cpi r24, 0x05 ; 5 + 3e68: c9 f0 breq .+50 ; 0x3e9c + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3e6a: ad d1 rcall .+858 ; 0x41c6 + 3e6c: 88 23 and r24, r24 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3e6e: 49 f5 brne .+82 ; 0x3ec2 + 3e70: c2 d1 rcall .+900 ; 0x41f6 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 3e72: 88 23 and r24, r24 + 3e74: 51 f4 brne .+20 ; 0x3e8a + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 3e76: d7 d1 rcall .+942 ; 0x4226 + 3e78: 88 23 and r24, r24 + 3e7a: 09 f0 breq .+2 ; 0x3e7e + 3e7c: ba cf rjmp .-140 ; 0x3df2 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 3e7e: 80 91 24 23 lds r24, 0x2324 + 3e82: 88 23 and r24, r24 + 3e84: 81 f7 brne .-32 ; 0x3e66 + break; + + if (Endpoint_IsINReady()) + 3e86: 82 e0 ldi r24, 0x02 ; 2 + 3e88: 0a c0 rjmp .+20 ; 0x3e9e + 3e8a: b5 d1 rcall .+874 ; 0x41f6 + 3e8c: 88 23 and r24, r24 + 3e8e: f9 f4 brne .+62 ; 0x3ece + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3e90: 80 91 24 23 lds r24, 0x2324 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3e94: 88 23 and r24, r24 + 3e96: b9 f3 breq .-18 ; 0x3e86 + while (!(Endpoint_IsOUTReceived())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + 3e98: 85 30 cpi r24, 0x05 ; 5 + 3e9a: b9 f7 brne .-18 ; 0x3e8a + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + 3e9c: 83 e0 ldi r24, 0x03 ; 3 + 3e9e: df 91 pop r29 + 3ea0: cf 91 pop r28 + 3ea2: 1f 91 pop r17 + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3ea4: 0f 91 pop r16 + 3ea6: ff 90 pop r15 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3ea8: ef 90 pop r14 + 3eaa: df 90 pop r13 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 3eac: cf 90 pop r12 + 3eae: 08 95 ret + return ENDPOINT_RWCSTREAM_BusSuspended; + 3eb0: e0 91 2d 23 lds r30, 0x232D + } + + return ENDPOINT_RWCSTREAM_NoError; +} + 3eb4: f0 91 2e 23 lds r31, 0x232E + 3eb8: ef 5b subi r30, 0xBF ; 191 + 3eba: ff 4f sbci r31, 0xFF ; 255 + 3ebc: c0 81 ld r28, Z + 3ebe: d0 e0 ldi r29, 0x00 ; 0 + 3ec0: ab cf rjmp .-170 ; 0x3e18 + 3ec2: 81 e0 ldi r24, 0x01 ; 1 + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + return USB_Endpoint_SelectedFIFO->Position; + 3ec4: ec cf rjmp .-40 ; 0x3e9e + 3ec6: b5 d0 rcall .+362 ; 0x4032 + 3ec8: ee 24 eor r14, r14 + 3eca: ff 24 eor r15, r15 + 3ecc: 77 cf rjmp .-274 ; 0x3dbc + 3ece: 80 e0 ldi r24, 0x00 ; 0 + 3ed0: e6 cf rjmp .-52 ; 0x3e9e + +00003ed2 : + 3ed2: cf 92 push r12 + 3ed4: df 92 push r13 + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + 3ed6: ef 92 push r14 + 3ed8: ff 92 push r15 + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + + if (Length > USB_ControlRequest.wLength) + Length = USB_ControlRequest.wLength; + else if (!(Length)) + Endpoint_ClearIN(); + 3eda: 0f 93 push r16 + 3edc: 1f 93 push r17 + 3ede: cf 93 push r28 + 3ee0: df 93 push r29 + 3ee2: 0f 92 push r0 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; + 3ee4: cd b7 in r28, 0x3d ; 61 + 3ee6: de b7 in r29, 0x3e ; 62 + +#if defined(TEMPLATE_FUNC_NAME) + +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + 3ee8: d8 2e mov r13, r24 + 3eea: c9 2e mov r12, r25 + 3eec: 7b 01 movw r14, r22 + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 3eee: 80 91 31 23 lds r24, 0x2331 + 3ef2: 80 68 ori r24, 0x80 ; 128 + 3ef4: e4 d0 rcall .+456 ; 0x40be + 3ef6: 00 91 2b 23 lds r16, 0x232B + + if (Length > USB_ControlRequest.wLength) + 3efa: 10 91 2c 23 lds r17, 0x232C + 3efe: 0e 15 cp r16, r14 + 3f00: 1f 05 cpc r17, r15 + 3f02: 28 f0 brcs .+10 ; 0x3f0e + 3f04: e1 14 cp r14, r1 + Length = USB_ControlRequest.wLength; + else if (!(Length)) + 3f06: f1 04 cpc r15, r1 + 3f08: 09 f4 brne .+2 ; 0x3f0c + 3f0a: 8d c0 rjmp .+282 ; 0x4026 + 3f0c: 87 01 movw r16, r14 + 3f0e: ed 2c mov r14, r13 + 3f10: fc 2c mov r15, r12 + 3f12: 80 e0 ldi r24, 0x00 ; 0 + 3f14: 01 15 cp r16, r1 + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + 3f16: 11 05 cpc r17, r1 + 3f18: 09 f0 breq .+2 ; 0x3f1c + 3f1a: 50 c0 rjmp .+160 ; 0x3fbc + 3f1c: 88 23 and r24, r24 + 3f1e: 09 f4 brne .+2 ; 0x3f22 + 3f20: 63 c0 rjmp .+198 ; 0x3fe8 + 3f22: 80 91 24 23 lds r24, 0x2324 + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3f26: 88 23 and r24, r24 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3f28: 09 f4 brne .+2 ; 0x3f2c + 3f2a: 5c c0 rjmp .+184 ; 0x3fe4 + 3f2c: 85 30 cpi r24, 0x05 ; 5 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 3f2e: 09 f4 brne .+2 ; 0x3f32 + 3f30: 64 c0 rjmp .+200 ; 0x3ffa + 3f32: 49 d1 rcall .+658 ; 0x41c6 + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 3f34: 88 23 and r24, r24 + 3f36: 09 f0 breq .+2 ; 0x3f3a + 3f38: 74 c0 rjmp .+232 ; 0x4022 + 3f3a: 5d d1 rcall .+698 ; 0x41f6 + 3f3c: 88 23 and r24, r24 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 3f3e: 09 f0 breq .+2 ; 0x3f42 + 3f40: 53 c0 rjmp .+166 ; 0x3fe8 + 3f42: 71 d1 rcall .+738 ; 0x4226 + 3f44: 88 23 and r24, r24 + 3f46: 69 f3 breq .-38 ; 0x3f22 + break; + + if (Endpoint_IsINReady()) + 3f48: 80 91 31 23 lds r24, 0x2331 + 3f4c: 87 fd sbrc r24, 7 + 3f4e: 60 c0 rjmp .+192 ; 0x4010 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 3f50: 80 91 2d 23 lds r24, 0x232D + 3f54: 90 91 2e 23 lds r25, 0x232E + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 3f58: fc 01 movw r30, r24 + 3f5a: e0 5c subi r30, 0xC0 ; 192 + 3f5c: ff 4f sbci r31, 0xFF ; 255 + 3f5e: c0 80 ld r12, Z + 3f60: 8f 5b subi r24, 0xBF ; 191 + 3f62: 9f 4f sbci r25, 0xFF ; 255 + 3f64: fc 01 movw r30, r24 + 3f66: 80 81 ld r24, Z + 3f68: dd 24 eor r13, r13 + 3f6a: c8 1a sub r12, r24 + 3f6c: d1 08 sbc r13, r1 + 3f6e: 01 15 cp r16, r1 + 3f70: 11 05 cpc r17, r1 + 3f72: b9 f0 breq .+46 ; 0x3fa2 + 3f74: 88 e0 ldi r24, 0x08 ; 8 + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 3f76: c8 16 cp r12, r24 + 3f78: d1 04 cpc r13, r1 + 3f7a: 28 f0 brcs .+10 ; 0x3f86 + 3f7c: 12 c0 rjmp .+36 ; 0x3fa2 + 3f7e: f8 e0 ldi r31, 0x08 ; 8 + 3f80: cf 16 cp r12, r31 + 3f82: d1 04 cpc r13, r1 + 3f84: 71 f0 breq .+28 ; 0x3fa2 + 3f86: f7 01 movw r30, r14 + 3f88: 84 91 lpm r24, Z + 3f8a: 8a d0 rcall .+276 ; 0x40a0 + 3f8c: 08 94 sec + { + TEMPLATE_TRANSFER_BYTE(DataStream); + 3f8e: e1 1c adc r14, r1 + 3f90: f1 1c adc r15, r1 + 3f92: 01 50 subi r16, 0x01 ; 1 + 3f94: 10 40 sbci r17, 0x00 ; 0 + TEMPLATE_BUFFER_MOVE(DataStream, 1); + 3f96: 08 94 sec + 3f98: c1 1c adc r12, r1 + 3f9a: d1 1c adc r13, r1 + Length--; + 3f9c: 01 15 cp r16, r1 + 3f9e: 11 05 cpc r17, r1 + BytesInEndpoint++; + 3fa0: 71 f7 brne .-36 ; 0x3f7e + 3fa2: 81 e0 ldi r24, 0x01 ; 1 + 3fa4: 98 e0 ldi r25, 0x08 ; 8 + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + 3fa6: c9 16 cp r12, r25 + 3fa8: d1 04 cpc r13, r1 + 3faa: 09 f0 breq .+2 ; 0x3fae + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + 3fac: 80 e0 ldi r24, 0x00 ; 0 + 3fae: 89 83 std Y+1, r24 ; 0x01 + 3fb0: 40 d0 rcall .+128 ; 0x4032 + 3fb2: 89 81 ldd r24, Y+1 ; 0x01 + 3fb4: 01 15 cp r16, r1 + 3fb6: 11 05 cpc r17, r1 + Endpoint_ClearIN(); + 3fb8: 09 f4 brne .+2 ; 0x3fbc + 3fba: b0 cf rjmp .-160 ; 0x3f1c + 3fbc: 80 91 24 23 lds r24, 0x2324 + 3fc0: 88 23 and r24, r24 + 3fc2: 81 f0 breq .+32 ; 0x3fe4 + 3fc4: 85 30 cpi r24, 0x05 ; 5 + 3fc6: c9 f0 breq .+50 ; 0x3ffa + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3fc8: fe d0 rcall .+508 ; 0x41c6 + 3fca: 88 23 and r24, r24 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3fcc: 51 f5 brne .+84 ; 0x4022 + 3fce: 13 d1 rcall .+550 ; 0x41f6 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 3fd0: 88 23 and r24, r24 + 3fd2: 51 f4 brne .+20 ; 0x3fe8 + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + 3fd4: 28 d1 rcall .+592 ; 0x4226 + 3fd6: 88 23 and r24, r24 + 3fd8: 09 f0 breq .+2 ; 0x3fdc + 3fda: b6 cf rjmp .-148 ; 0x3f48 + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + 3fdc: 80 91 24 23 lds r24, 0x2324 + 3fe0: 88 23 and r24, r24 + 3fe2: 81 f7 brne .-32 ; 0x3fc4 + break; + + if (Endpoint_IsINReady()) + 3fe4: 82 e0 ldi r24, 0x02 ; 2 + 3fe6: 0a c0 rjmp .+20 ; 0x3ffc + 3fe8: 06 d1 rcall .+524 ; 0x41f6 + 3fea: 88 23 and r24, r24 + 3fec: 01 f5 brne .+64 ; 0x402e + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 3fee: 80 91 24 23 lds r24, 0x2324 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 3ff2: 88 23 and r24, r24 + 3ff4: b9 f3 breq .-18 ; 0x3fe4 + while (!(Endpoint_IsOUTReceived())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + 3ff6: 85 30 cpi r24, 0x05 ; 5 + 3ff8: b9 f7 brne .-18 ; 0x3fe8 + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + 3ffa: 83 e0 ldi r24, 0x03 ; 3 + 3ffc: 0f 90 pop r0 + 3ffe: df 91 pop r29 + 4000: cf 91 pop r28 + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 4002: 1f 91 pop r17 + 4004: 0f 91 pop r16 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 4006: ff 90 pop r15 + 4008: ef 90 pop r14 + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 400a: df 90 pop r13 + 400c: cf 90 pop r12 + return ENDPOINT_RWCSTREAM_BusSuspended; + 400e: 08 95 ret + } + + return ENDPOINT_RWCSTREAM_NoError; +} + 4010: e0 91 2d 23 lds r30, 0x232D + 4014: f0 91 2e 23 lds r31, 0x232E + 4018: ef 5b subi r30, 0xBF ; 191 + 401a: ff 4f sbci r31, 0xFF ; 255 + 401c: c0 80 ld r12, Z + 401e: dd 24 eor r13, r13 + 4020: a6 cf rjmp .-180 ; 0x3f6e + 4022: 81 e0 ldi r24, 0x01 ; 1 + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + return USB_Endpoint_SelectedFIFO->Position; + 4024: eb cf rjmp .-42 ; 0x3ffc + 4026: 05 d0 rcall .+10 ; 0x4032 + 4028: 00 e0 ldi r16, 0x00 ; 0 + 402a: 10 e0 ldi r17, 0x00 ; 0 + 402c: 70 cf rjmp .-288 ; 0x3f0e + 402e: 80 e0 ldi r24, 0x00 ; 0 + 4030: e5 cf rjmp .-54 ; 0x3ffc + +00004032 : + USB_Endpoint_SelectedFIFO->Position = 0; +} + +void Endpoint_ClearIN(void) +{ + USB_Endpoint_SelectedHandle->CNT = USB_Endpoint_SelectedFIFO->Position; + 4032: e0 91 2f 23 lds r30, 0x232F + 4036: f0 91 30 23 lds r31, 0x2330 + 403a: a0 91 2d 23 lds r26, 0x232D + 403e: b0 91 2e 23 lds r27, 0x232E + 4042: af 5b subi r26, 0xBF ; 191 + 4044: bf 4f sbci r27, 0xFF ; 255 + 4046: 8c 91 ld r24, X + 4048: 90 e0 ldi r25, 0x00 ; 0 + 404a: 82 83 std Z+2, r24 ; 0x02 + 404c: 93 83 std Z+3, r25 ; 0x03 + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 404e: 80 81 ld r24, Z + 4050: 8d 79 andi r24, 0x9D ; 157 + 4052: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 4054: e0 91 2d 23 lds r30, 0x232D + 4058: f0 91 2e 23 lds r31, 0x232E + 405c: ef 5b subi r30, 0xBF ; 191 + 405e: ff 4f sbci r31, 0xFF ; 255 + 4060: 10 82 st Z, r1 +} + 4062: 08 95 ret + +00004064 : + +void Endpoint_ClearOUT(void) +{ + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 4064: e0 91 2f 23 lds r30, 0x232F + 4068: f0 91 30 23 lds r31, 0x2330 + 406c: 80 81 ld r24, Z + 406e: 8d 79 andi r24, 0x9D ; 157 + 4070: 80 83 st Z, r24 + USB_Endpoint_SelectedFIFO->Position = 0; + 4072: e0 91 2d 23 lds r30, 0x232D + 4076: f0 91 2e 23 lds r31, 0x232E + 407a: ef 5b subi r30, 0xBF ; 191 + 407c: ff 4f sbci r31, 0xFF ; 255 + 407e: 10 82 st Z, r1 +} + 4080: 08 95 ret + +00004082 : + } +} + +uint8_t Endpoint_Read_8(void) +{ + return USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++]; + 4082: 80 91 2d 23 lds r24, 0x232D + 4086: 90 91 2e 23 lds r25, 0x232E + 408a: fc 01 movw r30, r24 + 408c: ef 5b subi r30, 0xBF ; 191 + 408e: ff 4f sbci r31, 0xFF ; 255 + 4090: 20 81 ld r18, Z + 4092: 82 0f add r24, r18 + 4094: 91 1d adc r25, r1 + 4096: dc 01 movw r26, r24 + 4098: 8c 91 ld r24, X + 409a: 2f 5f subi r18, 0xFF ; 255 + 409c: 20 83 st Z, r18 +} + 409e: 08 95 ret + +000040a0 : + +void Endpoint_Write_8(const uint8_t Data) +{ + USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; + 40a0: 20 91 2d 23 lds r18, 0x232D + 40a4: 30 91 2e 23 lds r19, 0x232E + 40a8: f9 01 movw r30, r18 + 40aa: ef 5b subi r30, 0xBF ; 191 + 40ac: ff 4f sbci r31, 0xFF ; 255 + 40ae: 90 81 ld r25, Z + 40b0: 29 0f add r18, r25 + 40b2: 31 1d adc r19, r1 + 40b4: d9 01 movw r26, r18 + 40b6: 8c 93 st X, r24 + 40b8: 9f 5f subi r25, 0xFF ; 255 + 40ba: 90 83 st Z, r25 +} + 40bc: 08 95 ret + +000040be : + +void Endpoint_SelectEndpoint(const uint8_t Address) +{ + uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); + 40be: 28 2f mov r18, r24 + 40c0: 2f 70 andi r18, 0x0F ; 15 + + USB_Endpoint_SelectedEndpoint = Address; + 40c2: 80 93 31 23 sts 0x2331, r24 + + Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; + 40c6: 30 e0 ldi r19, 0x00 ; 0 + 40c8: 64 e8 ldi r22, 0x84 ; 132 + 40ca: 70 e0 ldi r23, 0x00 ; 0 + 40cc: 26 9f mul r18, r22 + 40ce: a0 01 movw r20, r0 + 40d0: 27 9f mul r18, r23 + 40d2: 50 0d add r21, r0 + 40d4: 36 9f mul r19, r22 + 40d6: 50 0d add r21, r0 + 40d8: 11 24 eor r1, r1 + 40da: 4e 5c subi r20, 0xCE ; 206 + 40dc: 5c 4d sbci r21, 0xDC ; 220 + USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; + 40de: 60 91 c6 04 lds r22, 0x04C6 + 40e2: 70 91 c7 04 lds r23, 0x04C7 + + if (Address & ENDPOINT_DIR_IN) + 40e6: 87 fd sbrc r24, 7 + 40e8: 11 c0 rjmp .+34 ; 0x410c + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; + } + else + { + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->OUT; + 40ea: 40 93 2d 23 sts 0x232D, r20 + 40ee: 50 93 2e 23 sts 0x232E, r21 + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].OUT; + 40f2: 22 95 swap r18 + 40f4: 32 95 swap r19 + 40f6: 30 7f andi r19, 0xF0 ; 240 + 40f8: 32 27 eor r19, r18 + 40fa: 20 7f andi r18, 0xF0 ; 240 + 40fc: 32 27 eor r19, r18 + 40fe: 26 0f add r18, r22 + 4100: 37 1f adc r19, r23 + 4102: 20 93 2f 23 sts 0x232F, r18 + 4106: 30 93 30 23 sts 0x2330, r19 + 410a: 08 95 ret + Endpoint_FIFOPair_t* EndpointFIFOPair = &USB_Endpoint_FIFOs[EndpointNumber]; + USB_EndpointTable_t* EndpointTable = (USB_EndpointTable_t*)USB.EPPTR; + + if (Address & ENDPOINT_DIR_IN) + { + USB_Endpoint_SelectedFIFO = &EndpointFIFOPair->IN; + 410c: 4e 5b subi r20, 0xBE ; 190 + 410e: 5f 4f sbci r21, 0xFF ; 255 + 4110: 40 93 2d 23 sts 0x232D, r20 + 4114: 50 93 2e 23 sts 0x232E, r21 + USB_Endpoint_SelectedHandle = &EndpointTable->Endpoints[EndpointNumber].IN; + 4118: 22 95 swap r18 + 411a: 32 95 swap r19 + 411c: 30 7f andi r19, 0xF0 ; 240 + 411e: 32 27 eor r19, r18 + 4120: 20 7f andi r18, 0xF0 ; 240 + 4122: 32 27 eor r19, r18 + 4124: 28 5f subi r18, 0xF8 ; 248 + 4126: 3f 4f sbci r19, 0xFF ; 255 + 4128: 26 0f add r18, r22 + 412a: 37 1f adc r19, r23 + 412c: 20 93 2f 23 sts 0x232F, r18 + 4130: 30 93 30 23 sts 0x2330, r19 + 4134: 08 95 ret + +00004136 : + USB_Endpoint_SelectedFIFO->Position = 0; +} + +void Endpoint_StallTransaction(void) +{ + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + 4136: e0 91 2f 23 lds r30, 0x232F + 413a: f0 91 30 23 lds r31, 0x2330 + 413e: 81 81 ldd r24, Z+1 ; 0x01 + 4140: 84 60 ori r24, 0x04 ; 4 + 4142: 81 83 std Z+1, r24 ; 0x01 + + if ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) == USB_EP_TYPE_CONTROL_gc) + 4144: e0 91 2f 23 lds r30, 0x232F + 4148: f0 91 30 23 lds r31, 0x2330 + 414c: 81 81 ldd r24, Z+1 ; 0x01 + 414e: 80 7c andi r24, 0xC0 ; 192 + 4150: 80 34 cpi r24, 0x40 ; 64 + 4152: 09 f0 breq .+2 ; 0x4156 + 4154: 08 95 ret + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint ^ ENDPOINT_DIR_IN); + 4156: 80 91 31 23 lds r24, 0x2331 + 415a: 80 58 subi r24, 0x80 ; 128 + 415c: b0 df rcall .-160 ; 0x40be + 415e: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + 4162: f0 91 30 23 lds r31, 0x2330 + 4166: 81 81 ldd r24, Z+1 ; 0x01 + 4168: 84 60 ori r24, 0x04 ; 4 + 416a: 81 83 std Z+1, r24 ; 0x01 + 416c: 08 95 ret + +0000416e : + 416e: 80 91 31 23 lds r24, 0x2331 + return false; +} + +void Endpoint_ClearSETUP(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 4172: 8f 77 andi r24, 0x7F ; 127 + 4174: a4 df rcall .-184 ; 0x40be + 4176: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + 417a: f0 91 30 23 lds r31, 0x2330 + 417e: 80 81 ld r24, Z + 4180: 8d 78 andi r24, 0x8D ; 141 + 4182: 80 83 st Z, r24 + 4184: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + 4188: f0 91 30 23 lds r31, 0x2330 + 418c: 80 81 ld r24, Z + 418e: 81 60 ori r24, 0x01 ; 1 + 4190: 80 83 st Z, r24 + 4192: e0 91 2d 23 lds r30, 0x232D + USB_Endpoint_SelectedFIFO->Position = 0; + 4196: f0 91 2e 23 lds r31, 0x232E + 419a: ef 5b subi r30, 0xBF ; 191 + 419c: ff 4f sbci r31, 0xFF ; 255 + 419e: 10 82 st Z, r1 + 41a0: 80 91 31 23 lds r24, 0x2331 + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 41a4: 80 68 ori r24, 0x80 ; 128 + 41a6: 8b df rcall .-234 ; 0x40be + 41a8: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + 41ac: f0 91 30 23 lds r31, 0x2330 + 41b0: 80 81 ld r24, Z + 41b2: 81 60 ori r24, 0x01 ; 1 + 41b4: 80 83 st Z, r24 + 41b6: e0 91 2d 23 lds r30, 0x232D + USB_Endpoint_SelectedFIFO->Position = 0; + 41ba: f0 91 2e 23 lds r31, 0x232E + 41be: ef 5b subi r30, 0xBF ; 191 + 41c0: ff 4f sbci r31, 0xFF ; 255 + 41c2: 10 82 st Z, r1 + 41c4: 08 95 ret + +000041c6 : + 41c6: 80 91 31 23 lds r24, 0x2331 + return false; +} + +bool Endpoint_IsSETUPReceived(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 41ca: 8f 77 andi r24, 0x7F ; 127 + 41cc: 78 df rcall .-272 ; 0x40be + 41ce: e0 91 2f 23 lds r30, 0x232F + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_SETUP_bm) + 41d2: f0 91 30 23 lds r31, 0x2330 + 41d6: 80 81 ld r24, Z + 41d8: 84 ff sbrs r24, 4 + 41da: 0b c0 rjmp .+22 ; 0x41f2 + 41dc: a0 91 2d 23 lds r26, 0x232D + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + 41e0: b0 91 2e 23 lds r27, 0x232E + 41e4: 82 81 ldd r24, Z+2 ; 0x02 + 41e6: 93 81 ldd r25, Z+3 ; 0x03 + 41e8: a0 5c subi r26, 0xC0 ; 192 + 41ea: bf 4f sbci r27, 0xFF ; 255 + 41ec: 8c 93 st X, r24 + 41ee: 81 e0 ldi r24, 0x01 ; 1 + return true; + 41f0: 08 95 ret + 41f2: 80 e0 ldi r24, 0x00 ; 0 + } + + return false; + 41f4: 08 95 ret + +000041f6 : +} + 41f6: 80 91 31 23 lds r24, 0x2331 + return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); +} + +bool Endpoint_IsOUTReceived(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + 41fa: 8f 77 andi r24, 0x7F ; 127 + 41fc: 60 df rcall .-320 ; 0x40be + 41fe: e0 91 2f 23 lds r30, 0x232F + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) + 4202: f0 91 30 23 lds r31, 0x2330 + 4206: 80 81 ld r24, Z + 4208: 85 ff sbrs r24, 5 + 420a: 0b c0 rjmp .+22 ; 0x4222 + 420c: a0 91 2d 23 lds r26, 0x232D + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + 4210: b0 91 2e 23 lds r27, 0x232E + 4214: 82 81 ldd r24, Z+2 ; 0x02 + 4216: 93 81 ldd r25, Z+3 ; 0x03 + 4218: a0 5c subi r26, 0xC0 ; 192 + 421a: bf 4f sbci r27, 0xFF ; 255 + 421c: 8c 93 st X, r24 + 421e: 81 e0 ldi r24, 0x01 ; 1 + return true; + 4220: 08 95 ret + 4222: 80 e0 ldi r24, 0x00 ; 0 + } + + return false; + 4224: 08 95 ret + +00004226 : +} + 4226: 80 91 31 23 lds r24, 0x2331 +volatile USB_EP_t* USB_Endpoint_SelectedHandle; +volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO; + +bool Endpoint_IsINReady(void) +{ + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + 422a: 80 68 ori r24, 0x80 ; 128 + 422c: 48 df rcall .-368 ; 0x40be + 422e: e0 91 2f 23 lds r30, 0x232F + + return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); + 4232: f0 91 30 23 lds r31, 0x2330 + 4236: 90 81 ld r25, Z + 4238: 81 e0 ldi r24, 0x01 ; 1 + 423a: 91 ff sbrs r25, 1 + 423c: 80 e0 ldi r24, 0x00 ; 0 + 423e: 08 95 ret + +00004240 : +} + 4240: 1f 93 push r17 +} + +bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Address, + const uint8_t Config, + const uint8_t Size) +{ + 4242: cf 93 push r28 + 4244: df 93 push r29 + 4246: 00 d0 rcall .+0 ; 0x4248 + 4248: cd b7 in r28, 0x3d ; 61 + 424a: de b7 in r29, 0x3e ; 62 + 424c: 18 2f mov r17, r24 + Endpoint_SelectEndpoint(Address); + 424e: 4a 83 std Y+2, r20 ; 0x02 + 4250: 69 83 std Y+1, r22 ; 0x01 + 4252: 35 df rcall .-406 ; 0x40be + 4254: e0 91 2f 23 lds r30, 0x232F + + USB_Endpoint_SelectedHandle->CTRL = 0; + 4258: f0 91 30 23 lds r31, 0x2330 + 425c: 11 82 std Z+1, r1 ; 0x01 + 425e: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; + 4262: f0 91 30 23 lds r31, 0x2330 + 4266: 4a 81 ldd r20, Y+2 ; 0x02 + 4268: 69 81 ldd r22, Y+1 ; 0x01 + 426a: 17 fd sbrc r17, 7 + 426c: 22 c0 rjmp .+68 ; 0x42b2 + 426e: 10 82 st Z, r1 + 4270: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->CTRL = Config; + 4274: f0 91 30 23 lds r31, 0x2330 + 4278: 61 83 std Z+1, r22 ; 0x01 + 427a: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->CNT = 0; + 427e: f0 91 30 23 lds r31, 0x2330 + 4282: 12 82 std Z+2, r1 ; 0x02 + 4284: 13 82 std Z+3, r1 ; 0x03 + 4286: 80 91 2d 23 lds r24, 0x232D + USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; + 428a: 90 91 2e 23 lds r25, 0x232E + 428e: 84 83 std Z+4, r24 ; 0x04 + 4290: 95 83 std Z+5, r25 ; 0x05 + 4292: 40 e0 ldi r20, 0x00 ; 0 + + USB_Endpoint_SelectedFIFO->Length = (Address & ENDPOINT_DIR_IN) ? Size : 0; + 4294: fc 01 movw r30, r24 + 4296: e0 5c subi r30, 0xC0 ; 192 + 4298: ff 4f sbci r31, 0xFF ; 255 + 429a: 40 83 st Z, r20 + 429c: 8f 5b subi r24, 0xBF ; 191 + USB_Endpoint_SelectedFIFO->Position = 0; + 429e: 9f 4f sbci r25, 0xFF ; 255 + 42a0: dc 01 movw r26, r24 + 42a2: 1c 92 st X, r1 + 42a4: 81 e0 ldi r24, 0x01 ; 1 + + return true; +} + 42a6: 0f 90 pop r0 + 42a8: 0f 90 pop r0 + 42aa: df 91 pop r29 + 42ac: cf 91 pop r28 + 42ae: 1f 91 pop r17 + 42b0: 08 95 ret + 42b2: 82 e0 ldi r24, 0x02 ; 2 + const uint8_t Size) +{ + Endpoint_SelectEndpoint(Address); + + USB_Endpoint_SelectedHandle->CTRL = 0; + USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; + 42b4: 80 83 st Z, r24 + 42b6: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->CTRL = Config; + 42ba: f0 91 30 23 lds r31, 0x2330 + 42be: 61 83 std Z+1, r22 ; 0x01 + 42c0: e0 91 2f 23 lds r30, 0x232F + USB_Endpoint_SelectedHandle->CNT = 0; + 42c4: f0 91 30 23 lds r31, 0x2330 + 42c8: 12 82 std Z+2, r1 ; 0x02 + 42ca: 13 82 std Z+3, r1 ; 0x03 + 42cc: 80 91 2d 23 lds r24, 0x232D + USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; + 42d0: 90 91 2e 23 lds r25, 0x232E + 42d4: 84 83 std Z+4, r24 ; 0x04 + 42d6: 95 83 std Z+5, r25 ; 0x05 + 42d8: dd cf rjmp .-70 ; 0x4294 + +000042da : + 42da: cf 92 push r12 + } +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + 42dc: df 92 push r13 + 42de: ef 92 push r14 + 42e0: ff 92 push r15 + 42e2: 0f 93 push r16 + 42e4: 1f 93 push r17 + 42e6: cf 93 push r28 + 42e8: df 93 push r29 + 42ea: 0f 92 push r0 + 42ec: cd b7 in r28, 0x3d ; 61 + 42ee: de b7 in r29, 0x3e ; 62 + 42f0: f6 2e mov r15, r22 + for (uint8_t i = 0; i < Entries; i++) + 42f2: 66 23 and r22, r22 + 42f4: 09 f4 brne .+2 ; 0x42f8 + 42f6: 41 c0 rjmp .+130 ; 0x437a + 42f8: 6c 01 movw r12, r24 + 42fa: 10 e0 ldi r17, 0x00 ; 0 + { + if (!(Table[i].Address)) + 42fc: f6 01 movw r30, r12 + 42fe: 00 81 ld r16, Z + 4300: 00 23 and r16, r16 + 4302: 99 f1 breq .+102 ; 0x436a + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + 4304: 63 81 ldd r22, Z+3 ; 0x03 + 4306: 21 81 ldd r18, Z+1 ; 0x01 + 4308: 32 81 ldd r19, Z+2 ; 0x02 + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + 430a: 84 81 ldd r24, Z+4 ; 0x04 + 430c: 82 30 cpi r24, 0x02 ; 2 + 430e: 08 f4 brcc .+2 ; 0x4312 + 4310: 41 c0 rjmp .+130 ; 0x4394 + 4312: 48 e1 ldi r20, 0x18 ; 24 + 4314: 58 e1 ldi r21, 0x18 ; 24 + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + 4316: 29 30 cpi r18, 0x09 ; 9 + 4318: 31 05 cpc r19, r1 + 431a: 50 f0 brcs .+20 ; 0x4330 + 431c: 88 e0 ldi r24, 0x08 ; 8 + 431e: 90 e0 ldi r25, 0x00 ; 0 + 4320: 40 e0 ldi r20, 0x00 ; 0 + { + MaskVal++; + 4322: 4f 5f subi r20, 0xFF ; 255 + CheckBytes <<= 1; + 4324: 88 0f add r24, r24 + 4326: 99 1f adc r25, r25 + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + 4328: 82 17 cp r24, r18 + 432a: 93 07 cpc r25, r19 + 432c: d0 f3 brcs .-12 ; 0x4322 + 432e: 45 2b or r20, r21 + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + 4330: 80 2f mov r24, r16 + 4332: 90 e0 ldi r25, 0x00 ; 0 + 4334: 8f 70 andi r24, 0x0F ; 15 + 4336: 90 70 andi r25, 0x00 ; 0 + 4338: 86 30 cpi r24, 0x06 ; 6 + 433a: 91 05 cpc r25, r1 + 433c: 4c f5 brge .+82 ; 0x4390 + return false; + + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) + 433e: 21 34 cpi r18, 0x41 ; 65 + 4340: 31 05 cpc r19, r1 + 4342: 30 f5 brcc .+76 ; 0x4390 + + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + 4344: 4f 7e andi r20, 0xEF ; 239 + if (Size > 64) + return false; + + switch (Type) + 4346: 66 23 and r22, r22 + 4348: 41 f5 brne .+80 ; 0x439a + { + case EP_TYPE_CONTROL: + EPConfigMask |= USB_EP_TYPE_CONTROL_gc; + 434a: 94 2f mov r25, r20 + 434c: 90 64 ori r25, 0x40 ; 64 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 434e: e2 2e mov r14, r18 + 4350: 80 2f mov r24, r16 + 4352: 80 58 subi r24, 0x80 ; 128 + 4354: 69 2f mov r22, r25 + 4356: 42 2f mov r20, r18 + 4358: 99 83 std Y+1, r25 ; 0x01 + 435a: 72 df rcall .-284 ; 0x4240 + 435c: 99 81 ldd r25, Y+1 ; 0x01 + 435e: 80 2f mov r24, r16 + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 4360: 69 2f mov r22, r25 + 4362: 4e 2d mov r20, r14 + 4364: 6d df rcall .-294 ; 0x4240 + 4366: 88 23 and r24, r24 + 4368: 99 f0 breq .+38 ; 0x4390 + 436a: 1f 5f subi r17, 0xFF ; 255 + 436c: 85 e0 ldi r24, 0x05 ; 5 +} + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + 436e: 90 e0 ldi r25, 0x00 ; 0 + 4370: c8 0e add r12, r24 + 4372: d9 1e adc r13, r25 + 4374: 1f 15 cp r17, r15 + 4376: 09 f0 breq .+2 ; 0x437a + 4378: c1 cf rjmp .-126 ; 0x42fc + 437a: 81 e0 ldi r24, 0x01 ; 1 + 437c: 0f 90 pop r0 + { + return false; + } + } + + return true; + 437e: df 91 pop r29 +} + 4380: cf 91 pop r28 + 4382: 1f 91 pop r17 + 4384: 0f 91 pop r16 + 4386: ff 90 pop r15 + 4388: ef 90 pop r14 + 438a: df 90 pop r13 + 438c: cf 90 pop r12 + 438e: 08 95 ret + 4390: 80 e0 ldi r24, 0x00 ; 0 + 4392: f4 cf rjmp .-24 ; 0x437c + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + { + return false; + 4394: 48 e0 ldi r20, 0x08 ; 8 + 4396: 58 e0 ldi r21, 0x08 ; 8 + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + 4398: be cf rjmp .-132 ; 0x4316 + 439a: 61 30 cpi r22, 0x01 ; 1 + 439c: 31 f0 breq .+12 ; 0x43aa + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) + return false; + + switch (Type) + 439e: 94 2f mov r25, r20 + 43a0: 90 68 ori r25, 0x80 ; 128 + break; + case EP_TYPE_ISOCHRONOUS: + EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; + break; + default: + EPConfigMask |= USB_EP_TYPE_BULK_gc; + 43a2: 66 23 and r22, r22 + 43a4: a1 f2 breq .-88 ; 0x434e + break; + } + + if (Type == EP_TYPE_CONTROL) + 43a6: e2 2e mov r14, r18 + 43a8: da cf rjmp .-76 ; 0x435e + 43aa: 94 2f mov r25, r20 + 43ac: 90 6c ori r25, 0xC0 ; 192 + { + case EP_TYPE_CONTROL: + EPConfigMask |= USB_EP_TYPE_CONTROL_gc; + break; + case EP_TYPE_ISOCHRONOUS: + EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; + 43ae: e2 2e mov r14, r18 + 43b0: d6 cf rjmp .-84 ; 0x435e + +000043b2 : + 43b2: e0 ec ldi r30, 0xC0 ; 192 + 43b4: f4 e0 ldi r31, 0x04 ; 4 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 43b6: a6 81 ldd r26, Z+6 ; 0x06 + 43b8: b7 81 ldd r27, Z+7 ; 0x07 + 43ba: 19 96 adiw r26, 0x09 ; 9 + 43bc: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 43be: a6 81 ldd r26, Z+6 ; 0x06 + 43c0: b7 81 ldd r27, Z+7 ; 0x07 + 43c2: 11 96 adiw r26, 0x01 ; 1 + 43c4: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 43c6: a6 81 ldd r26, Z+6 ; 0x06 + 43c8: b7 81 ldd r27, Z+7 ; 0x07 + 43ca: 59 96 adiw r26, 0x19 ; 25 + 43cc: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 43ce: a6 81 ldd r26, Z+6 ; 0x06 + 43d0: b7 81 ldd r27, Z+7 ; 0x07 + 43d2: 51 96 adiw r26, 0x11 ; 17 + 43d4: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 43d6: a6 81 ldd r26, Z+6 ; 0x06 + 43d8: b7 81 ldd r27, Z+7 ; 0x07 + 43da: 99 96 adiw r26, 0x29 ; 41 + 43dc: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 43de: a6 81 ldd r26, Z+6 ; 0x06 + 43e0: b7 81 ldd r27, Z+7 ; 0x07 + 43e2: 91 96 adiw r26, 0x21 ; 33 + 43e4: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 43e6: a6 81 ldd r26, Z+6 ; 0x06 + 43e8: b7 81 ldd r27, Z+7 ; 0x07 + 43ea: d9 96 adiw r26, 0x39 ; 57 + 43ec: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 43ee: a6 81 ldd r26, Z+6 ; 0x06 + 43f0: b7 81 ldd r27, Z+7 ; 0x07 + 43f2: d1 96 adiw r26, 0x31 ; 49 + 43f4: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 43f6: a6 81 ldd r26, Z+6 ; 0x06 + 43f8: b7 81 ldd r27, Z+7 ; 0x07 + 43fa: a7 5b subi r26, 0xB7 ; 183 + 43fc: bf 4f sbci r27, 0xFF ; 255 + 43fe: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 4400: a6 81 ldd r26, Z+6 ; 0x06 + 4402: b7 81 ldd r27, Z+7 ; 0x07 + 4404: af 5b subi r26, 0xBF ; 191 + 4406: bf 4f sbci r27, 0xFF ; 255 + 4408: 1c 92 st X, r1 + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + 440a: a6 81 ldd r26, Z+6 ; 0x06 + 440c: b7 81 ldd r27, Z+7 ; 0x07 + 440e: a7 5a subi r26, 0xA7 ; 167 + 4410: bf 4f sbci r27, 0xFF ; 255 + 4412: 1c 92 st X, r1 + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + 4414: 06 80 ldd r0, Z+6 ; 0x06 + 4416: f7 81 ldd r31, Z+7 ; 0x07 + 4418: e0 2d mov r30, r0 + 441a: ef 5a subi r30, 0xAF ; 175 + 441c: ff 4f sbci r31, 0xFF ; 255 + 441e: 10 82 st Z, r1 + } +} + 4420: 08 95 ret + +00004422 : + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + 4422: 80 91 25 23 lds r24, 0x2325 + 4426: 87 fd sbrc r24, 7 + 4428: 08 c0 rjmp .+16 ; 0x443a + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + 442a: fd de rcall .-518 ; 0x4226 + 442c: 88 23 and r24, r24 + 442e: 69 f4 brne .+26 ; 0x444a + 4430: 80 91 24 23 lds r24, 0x2324 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 4434: 88 23 and r24, r24 + 4436: c9 f7 brne .-14 ; 0x442a + 4438: 08 95 ret + 443a: dd de rcall .-582 ; 0x41f6 + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + 443c: 88 23 and r24, r24 + 443e: 31 f4 brne .+12 ; 0x444c + 4440: 80 91 24 23 lds r24, 0x2324 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 4444: 88 23 and r24, r24 + 4446: c9 f7 brne .-14 ; 0x443a + 4448: 08 95 ret + 444a: f3 cd rjmp .-1050 ; 0x4032 + 444c: 0b ce rjmp .-1002 ; 0x4064 + +0000444e : + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + 444e: 1f 93 push r17 + 4450: cf 93 push r28 + 4452: df 93 push r29 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + 4454: e0 91 c6 04 lds r30, 0x04C6 + 4458: f0 91 c7 04 lds r31, 0x04C7 + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint16_t USB_Device_GetFrameNumber(void) + { + return ((USB_EndpointTable_t*)USB.EPPTR)->FrameNum; + 445c: e0 5a subi r30, 0xA0 ; 160 + 445e: ff 4f sbci r31, 0xFF ; 255 + 4460: c0 81 ld r28, Z + 4462: d1 81 ldd r29, Z+1 ; 0x01 + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + 4464: 14 e6 ldi r17, 0x64 ; 100 + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); + 4466: 80 91 31 23 lds r24, 0x2331 + 446a: 80 78 andi r24, 0x80 ; 128 + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + 446c: 80 38 cpi r24, 0x80 ; 128 + 446e: 21 f1 breq .+72 ; 0x44b8 + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + 4470: c2 de rcall .-636 ; 0x41f6 + 4472: 88 23 and r24, r24 + 4474: 21 f5 brne .+72 ; 0x44be + 4476: 80 91 24 23 lds r24, 0x2324 + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + 447a: 88 23 and r24, r24 + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + 447c: 29 f1 breq .+74 ; 0x44c8 + 447e: 85 30 cpi r24, 0x05 ; 5 + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + 4480: 41 f1 breq .+80 ; 0x44d2 + 4482: e0 91 2f 23 lds r30, 0x232F + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); + 4486: f0 91 30 23 lds r31, 0x2330 + 448a: 81 81 ldd r24, Z+1 ; 0x01 + 448c: 82 fd sbrc r24, 2 + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + 448e: 26 c0 rjmp .+76 ; 0x44dc + 4490: e0 91 c6 04 lds r30, 0x04C6 + 4494: f0 91 c7 04 lds r31, 0x04C7 + 4498: e0 5a subi r30, 0xA0 ; 160 + 449a: ff 4f sbci r31, 0xFF ; 255 + 449c: 80 81 ld r24, Z + 449e: 91 81 ldd r25, Z+1 ; 0x01 + 44a0: c8 17 cp r28, r24 + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + 44a2: d9 07 cpc r29, r25 + 44a4: 01 f3 breq .-64 ; 0x4466 + 44a6: 11 23 and r17, r17 + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + 44a8: f1 f0 breq .+60 ; 0x44e6 + 44aa: 11 50 subi r17, 0x01 ; 1 + 44ac: ec 01 movw r28, r24 + 44ae: 80 91 31 23 lds r24, 0x2331 + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); + 44b2: 80 78 andi r24, 0x80 ; 128 + 44b4: 80 38 cpi r24, 0x80 ; 128 + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + 44b6: e1 f6 brne .-72 ; 0x4470 + 44b8: b6 de rcall .-660 ; 0x4226 + { + if (Endpoint_IsINReady()) + 44ba: 88 23 and r24, r24 + 44bc: e1 f2 breq .-72 ; 0x4476 + 44be: 80 e0 ldi r24, 0x00 ; 0 + 44c0: df 91 pop r29 + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + return ENDPOINT_READYWAIT_NoError; + 44c2: cf 91 pop r28 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 44c4: 1f 91 pop r17 + 44c6: 08 95 ret + 44c8: 82 e0 ldi r24, 0x02 ; 2 + 44ca: df 91 pop r29 + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + 44cc: cf 91 pop r28 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 44ce: 1f 91 pop r17 + 44d0: 08 95 ret + 44d2: 83 e0 ldi r24, 0x03 ; 3 + 44d4: df 91 pop r29 + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + 44d6: cf 91 pop r28 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 44d8: 1f 91 pop r17 + 44da: 08 95 ret + 44dc: 81 e0 ldi r24, 0x01 ; 1 + 44de: df 91 pop r29 + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + 44e0: cf 91 pop r28 + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} + 44e2: 1f 91 pop r17 + 44e4: 08 95 ret + 44e6: 84 e0 ldi r24, 0x04 ; 4 + 44e8: df 91 pop r29 + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + 44ea: cf 91 pop r28 + } + } +} + 44ec: 1f 91 pop r17 + 44ee: 08 95 ret + +000044f0 : + USB_ResetInterface(); +} + +void USB_Disable(void) +{ + USB_INT_DisableAllInterrupts(); + 44f0: 64 d0 rcall .+200 ; 0x45ba + 44f2: 6a d0 rcall .+212 ; 0x45c8 + USB_INT_ClearAllInterrupts(); + 44f4: e0 ec ldi r30, 0xC0 ; 192 + 44f6: f4 e0 ldi r31, 0x04 ; 4 + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + USB.CTRLB &= ~USB_ATTACH_bm; + 44f8: 81 81 ldd r24, Z+1 ; 0x01 + 44fa: 8e 7f andi r24, 0xFE ; 254 + 44fc: 81 83 std Z+1, r24 ; 0x01 + 44fe: 80 81 ld r24, Z + 4500: 8f 77 andi r24, 0x7F ; 127 + } + + static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Disable(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + 4502: 80 83 st Z, r24 + 4504: 10 92 23 23 sts 0x2323, r1 + + USB_Detach(); + USB_Controller_Disable(); + + USB_IsInitialized = false; + 4508: 08 95 ret + +0000450a : + 450a: cf 93 push r28 +} + 450c: df 93 push r29 +{ + #if defined(USB_DEVICE_OPT_FULLSPEED) + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + else + CLK.USBCTRL = (((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp); + 450e: e0 e4 ldi r30, 0x40 ; 64 + 4510: f0 e0 ldi r31, 0x00 ; 0 + 4512: 14 82 std Z+4, r1 ; 0x04 + #else + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + #endif + + if (USB_Options & USB_OPT_PLLCLKSRC) + CLK.USBCTRL |= (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + 4514: 84 81 ldd r24, Z+4 ; 0x04 + 4516: 81 60 ori r24, 0x01 ; 1 + 4518: 84 83 std Z+4, r24 ; 0x04 + else + CLK.USBCTRL |= (CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); + + USB_Device_SetDeviceAddress(0); + + USB_INT_DisableAllInterrupts(); + 451a: 4f d0 rcall .+158 ; 0x45ba + 451c: 55 d0 rcall .+170 ; 0x45c8 + USB_INT_ClearAllInterrupts(); + 451e: c0 ec ldi r28, 0xC0 ; 192 + 4520: d4 e0 ldi r29, 0x04 ; 4 + } + + static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Reset(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + 4522: 88 81 ld r24, Y + 4524: 8f 77 andi r24, 0x7F ; 127 + 4526: 88 83 st Y, r24 + 4528: 88 81 ld r24, Y + 452a: 80 68 ori r24, 0x80 ; 128 + USB.CTRLA |= USB_ENABLE_bm; + 452c: 88 83 st Y, r24 + 452e: 10 92 24 23 sts 0x2324, r1 +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_Init_Device(void) +{ + USB_DeviceState = DEVICE_STATE_Unattached; + 4532: 10 92 20 23 sts 0x2320, r1 + USB_Device_ConfigurationNumber = 0; + 4536: 10 92 22 23 sts 0x2322, r1 + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + USB_Device_RemoteWakeupEnabled = false; + 453a: 10 92 21 23 sts 0x2321, r1 + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + USB_Device_CurrentlySelfPowered = false; + 453e: 88 81 ld r24, Y + 4540: 80 64 ori r24, 0x40 ; 64 + } + + static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetFullSpeed(void) + { + USB.CTRLA |= USB_SPEED_bm; + 4542: 88 83 st Y, r24 + 4544: 80 e8 ldi r24, 0x80 ; 128 + 4546: 68 e4 ldi r22, 0x48 ; 72 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 4548: 48 e0 ldi r20, 0x08 ; 8 + 454a: 7a de rcall .-780 ; 0x4240 + 454c: 80 e0 ldi r24, 0x00 ; 0 + 454e: 68 e4 ldi r22, 0x48 ; 72 + 4550: 48 e0 ldi r20, 0x08 ; 8 + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 4552: 76 de rcall .-788 ; 0x4240 + 4554: 88 85 ldd r24, Y+8 ; 0x08 + 4556: 80 64 ori r24, 0x40 ; 64 + 4558: 88 87 std Y+8, r24 ; 0x08 + 455a: 89 81 ldd r24, Y+1 ; 0x01 + static inline void USB_INT_Enable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + USB.INTCTRLA |= USB_BUSEVIE_bm; + 455c: 81 60 ori r24, 0x01 ; 1 + 455e: 89 83 std Y+1, r24 ; 0x01 + 4560: df 91 pop r29 + * register and despite the datasheet making no mention of its requirement in host mode. + */ + static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Attach(void) + { + USB.CTRLB |= USB_ATTACH_bm; + 4562: cf 91 pop r28 + 4564: 08 95 ret + +00004566 : + 4566: cf 93 push r28 + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Controller_Reset(); + USB_Init_Device(); +} + 4568: df 93 push r29 + 456a: 3f b7 in r19, 0x3f ; 63 + 456c: f8 94 cli + #endif + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + 456e: c0 ec ldi r28, 0xC0 ; 192 + 4570: d1 e0 ldi r29, 0x01 ; 1 + 4572: 22 e0 ldi r18, 0x02 ; 2 + 4574: 2a 87 std Y+10, r18 ; 0x0a + USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0)); + 4576: ea e1 ldi r30, 0x1A ; 26 + 4578: f0 e0 ldi r31, 0x00 ; 0 + 457a: e4 91 lpm r30, Z + 457c: a0 ec ldi r26, 0xC0 ; 192 + 457e: b4 e0 ldi r27, 0x04 ; 4 + 4580: da 96 adiw r26, 0x3a ; 58 + 4582: ec 93 st X, r30 + 4584: da 97 sbiw r26, 0x3a ; 58 + USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1)); + 4586: eb e1 ldi r30, 0x1B ; 27 + 4588: f0 e0 ldi r31, 0x00 ; 0 + 458a: e4 91 lpm r30, Z + 458c: db 96 adiw r26, 0x3b ; 59 + 458e: ec 93 st X, r30 + 4590: db 97 sbiw r26, 0x3b ; 59 + NVM.CMD = NVM_CMD_NO_OPERATION_gc; + 4592: 1a 86 std Y+10, r1 ; 0x0a + + /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for the 8-bit AVR-GCC toolchain */ + USB.EPPTR = ((intptr_t)&USB_EndpointTable[1] & ~(1 << 0)); + 4594: 8b e4 ldi r24, 0x4B ; 75 + 4596: 96 e2 ldi r25, 0x26 ; 38 + 4598: 8e 7f andi r24, 0xFE ; 254 + 459a: 16 96 adiw r26, 0x06 ; 6 + 459c: 8d 93 st X+, r24 + 459e: 9c 93 st X, r25 + 45a0: 17 97 sbiw r26, 0x07 ; 7 + USB.CTRLA = (USB_STFRNUM_bm | ((ENDPOINT_TOTAL_ENDPOINTS - 1) << USB_MAXEP_gp)); + 45a2: 85 e1 ldi r24, 0x15 ; 21 + 45a4: 8c 93 st X, r24 + + if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH) + USB.INTCTRLA = (3 << USB_INTLVL_gp); + else if ((USB_Options & USB_OPT_BUSEVENT_PRIMED) == USB_OPT_BUSEVENT_PRIMED) + USB.INTCTRLA = (2 << USB_INTLVL_gp); + 45a6: 18 96 adiw r26, 0x08 ; 8 + 45a8: 2c 93 st X, r18 + if (GlobalIntState & AVR32_SR_GM) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + else + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + SREG = GlobalIntState; + 45aa: 3f bf out 0x3f, r19 ; 63 + + #if defined(USB_CAN_BE_BOTH) + USB_CurrentMode = Mode; + #endif + + USB_IsInitialized = true; + 45ac: 81 e0 ldi r24, 0x01 ; 1 + 45ae: 80 93 23 23 sts 0x2323, r24 + + USB_ResetInterface(); + 45b2: ab df rcall .-170 ; 0x450a + 45b4: df 91 pop r29 +} + 45b6: cf 91 pop r28 + 45b8: 08 95 ret + +000045ba : +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBInterrupt.h" + +void USB_INT_DisableAllInterrupts(void) +{ + USB.INTCTRLA &= USB_INTLVL_gm; + 45ba: e0 ec ldi r30, 0xC0 ; 192 + 45bc: f4 e0 ldi r31, 0x04 ; 4 + 45be: 80 85 ldd r24, Z+8 ; 0x08 + 45c0: 83 70 andi r24, 0x03 ; 3 + 45c2: 80 87 std Z+8, r24 ; 0x08 + USB.INTCTRLB = 0; + 45c4: 11 86 std Z+9, r1 ; 0x09 +} + 45c6: 08 95 ret + +000045c8 : + +void USB_INT_ClearAllInterrupts(void) +{ + USB.INTFLAGSACLR = 0xFF; + 45c8: e0 ec ldi r30, 0xC0 ; 192 + 45ca: f4 e0 ldi r31, 0x04 ; 4 + 45cc: 8f ef ldi r24, 0xFF ; 255 + 45ce: 82 87 std Z+10, r24 ; 0x0a + USB.INTFLAGSBCLR = 0xFF; + 45d0: 84 87 std Z+12, r24 ; 0x0c +} + 45d2: 08 95 ret + +000045d4 <__vector_125>: + +ISR(USB_BUSEVENT_vect) +{ + 45d4: 1f 92 push r1 + 45d6: 0f 92 push r0 + 45d8: 0f b6 in r0, 0x3f ; 63 + 45da: 0f 92 push r0 + 45dc: 11 24 eor r1, r1 + 45de: 2f 93 push r18 + 45e0: 3f 93 push r19 + 45e2: 4f 93 push r20 + 45e4: 5f 93 push r21 + 45e6: 6f 93 push r22 + 45e8: 7f 93 push r23 + 45ea: 8f 93 push r24 + 45ec: 9f 93 push r25 + 45ee: af 93 push r26 + 45f0: bf 93 push r27 + 45f2: ef 93 push r30 + 45f4: ff 93 push r31 + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Reset: + return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTFLAGSACLR & USB_SOFIF_bm) ? true : false); + 45f6: 80 91 ca 04 lds r24, 0x04CA + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + 45fa: 87 fd sbrc r24, 7 + 45fc: 4f c0 rjmp .+158 ; 0x469c <__vector_125+0xc8> + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); + 45fe: 80 91 ca 04 lds r24, 0x04CA + + EVENT_USB_Device_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) + 4602: 86 fd sbrc r24, 6 + 4604: 42 c0 rjmp .+132 ; 0x468a <__vector_125+0xb6> + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + 4606: 80 91 ca 04 lds r24, 0x04CA + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Device_Suspend(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume)) + 460a: 85 ff sbrs r24, 5 + 460c: 0d c0 rjmp .+26 ; 0x4628 <__vector_125+0x54> + { + case USB_INT_BUSEVENTI_Suspend: + USB.INTFLAGSACLR = USB_SUSPENDIF_bm; + break; + case USB_INT_BUSEVENTI_Resume: + USB.INTFLAGSACLR = USB_RESUMEIF_bm; + 460e: 80 e2 ldi r24, 0x20 ; 32 + 4610: e0 ec ldi r30, 0xC0 ; 192 + 4612: f4 e0 ldi r31, 0x04 ; 4 + 4614: 82 87 std Z+10, r24 ; 0x0a + { + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + 4616: 80 91 20 23 lds r24, 0x2320 + 461a: 88 23 and r24, r24 + 461c: 71 f1 breq .+92 ; 0x467a <__vector_125+0xa6> + USB_DeviceState = DEVICE_STATE_Configured; + 461e: 84 e0 ldi r24, 0x04 ; 4 + 4620: 80 93 24 23 sts 0x2324, r24 + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + EVENT_USB_Device_Connect(); + 4624: 0e 94 62 0b call 0x16c4 ; 0x16c4 + case USB_INT_BUSEVENTI_Suspend: + return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Reset: + return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); + 4628: e0 ec ldi r30, 0xC0 ; 192 + 462a: f4 e0 ldi r31, 0x04 ; 4 + 462c: 80 91 ca 04 lds r24, 0x04CA + #else + EVENT_USB_Device_WakeUp(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset)) + 4630: 84 ff sbrs r24, 4 + 4632: 12 c0 rjmp .+36 ; 0x4658 <__vector_125+0x84> + break; + case USB_INT_BUSEVENTI_Resume: + USB.INTFLAGSACLR = USB_RESUMEIF_bm; + break; + case USB_INT_BUSEVENTI_Reset: + USB.INTFLAGSACLR = USB_RSTIF_bm; + 4634: 80 e1 ldi r24, 0x10 ; 16 + 4636: 82 87 std Z+10, r24 ; 0x0a + { + USB_INT_Clear(USB_INT_BUSEVENTI_Reset); + + USB_DeviceState = DEVICE_STATE_Default; + 4638: 82 e0 ldi r24, 0x02 ; 2 + 463a: 80 93 24 23 sts 0x2324, r24 + USB_Device_ConfigurationNumber = 0; + 463e: 10 92 20 23 sts 0x2320, r1 + } + + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) + { + USB.ADDR = Address; + 4642: 13 82 std Z+3, r1 ; 0x03 + + USB_Device_EnableDeviceAddress(0); + + Endpoint_ClearEndpoints(); + 4644: b6 de rcall .-660 ; 0x43b2 + 4646: 80 e8 ldi r24, 0x80 ; 128 + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + 4648: 68 e4 ldi r22, 0x48 ; 72 + 464a: 48 e0 ldi r20, 0x08 ; 8 + 464c: f9 dd rcall .-1038 ; 0x4240 + 464e: 80 e0 ldi r24, 0x00 ; 0 + 4650: 68 e4 ldi r22, 0x48 ; 72 + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + 4652: 48 e0 ldi r20, 0x08 ; 8 + 4654: f5 dd rcall .-1046 ; 0x4240 + 4656: 17 db rcall .-2514 ; 0x3c86 + 4658: ff 91 pop r31 + 465a: ef 91 pop r30 + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + EVENT_USB_Device_Reset(); + 465c: bf 91 pop r27 + 465e: af 91 pop r26 + } +} + 4660: 9f 91 pop r25 + 4662: 8f 91 pop r24 + 4664: 7f 91 pop r23 + 4666: 6f 91 pop r22 + 4668: 5f 91 pop r21 + 466a: 4f 91 pop r20 + 466c: 3f 91 pop r19 + 466e: 2f 91 pop r18 + 4670: 0f 90 pop r0 + 4672: 0f be out 0x3f, r0 ; 63 + 4674: 0f 90 pop r0 + 4676: 1f 90 pop r1 + 4678: 18 95 reti + 467a: 80 91 c3 04 lds r24, 0x04C3 + 467e: 88 23 and r24, r24 + 4680: b9 f4 brne .+46 ; 0x46b0 <__vector_125+0xdc> + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return ((USB.ADDR != 0) ? true : false); + 4682: 81 e0 ldi r24, 0x01 ; 1 + 4684: 80 93 24 23 sts 0x2324, r24 + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Addressed : DEVICE_STATE_Powered; + 4688: cd cf rjmp .-102 ; 0x4624 <__vector_125+0x50> + 468a: 80 e4 ldi r24, 0x40 ; 64 + 468c: e0 ec ldi r30, 0xC0 ; 192 + 468e: f4 e0 ldi r31, 0x04 ; 4 + 4690: 82 87 std Z+10, r24 ; 0x0a + static inline void USB_INT_Clear(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + USB.INTFLAGSACLR = USB_SUSPENDIF_bm; + 4692: 10 92 24 23 sts 0x2324, r1 + 4696: 0e 94 67 0b call 0x16ce ; 0x16ce + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) + { + USB_INT_Clear(USB_INT_BUSEVENTI_Suspend); + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + USB_DeviceState = DEVICE_STATE_Unattached; + 469a: b5 cf rjmp .-150 ; 0x4606 <__vector_125+0x32> + 469c: 80 91 c8 04 lds r24, 0x04C8 + EVENT_USB_Device_Disconnect(); + 46a0: 87 ff sbrs r24, 7 + 46a2: ad cf rjmp .-166 ; 0x45fe <__vector_125+0x2a> + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + return ((USB.INTCTRLA & USB_BUSEVIE_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTCTRLA & USB_SOFIE_bm) ? true : false); + 46a4: 80 e8 ldi r24, 0x80 ; 128 + 46a6: e0 ec ldi r30, 0xC0 ; 192 +} + +ISR(USB_BUSEVENT_vect) +{ + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + 46a8: f4 e0 ldi r31, 0x04 ; 4 + 46aa: 82 87 std Z+10, r24 ; 0x0a + break; + case USB_INT_BUSEVENTI_Reset: + USB.INTFLAGSACLR = USB_RSTIF_bm; + break; + case USB_INT_SOFI: + USB.INTFLAGSACLR = USB_SOFIF_bm; + 46ac: ec da rcall .-2600 ; 0x3c86 + 46ae: a7 cf rjmp .-178 ; 0x45fe <__vector_125+0x2a> + 46b0: 83 e0 ldi r24, 0x03 ; 3 + 46b2: e8 cf rjmp .-48 ; 0x4684 <__vector_125+0xb0> + +000046b4 : +#define __INCLUDE_FROM_CDC_DRIVER +#define __INCLUDE_FROM_CDC_DEVICE_C +#include "CDCClassDevice.h" + +void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + 46b4: ef 92 push r14 + 46b6: ff 92 push r15 + 46b8: 0f 93 push r16 + 46ba: 1f 93 push r17 + 46bc: cf 93 push r28 + 46be: df 93 push r29 + 46c0: ec 01 movw r28, r24 + if (!(Endpoint_IsSETUPReceived())) + 46c2: 81 dd rcall .-1278 ; 0x41c6 + 46c4: 88 23 and r24, r24 + 46c6: 49 f0 breq .+18 ; 0x46da + 46c8: 88 81 ld r24, Y + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + 46ca: 90 e0 ldi r25, 0x00 ; 0 + 46cc: 20 91 29 23 lds r18, 0x2329 + 46d0: 30 91 2a 23 lds r19, 0x232A + 46d4: 28 17 cp r18, r24 + 46d6: 39 07 cpc r19, r25 + 46d8: 39 f0 breq .+14 ; 0x46e8 + 46da: df 91 pop r29 + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + 46dc: cf 91 pop r28 + 46de: 1f 91 pop r17 + 46e0: 0f 91 pop r16 + 46e2: ff 90 pop r15 + 46e4: ef 90 pop r14 + 46e6: 08 95 ret + 46e8: 80 91 26 23 lds r24, 0x2326 + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + 46ec: 81 32 cpi r24, 0x21 ; 33 + 46ee: 09 f4 brne .+2 ; 0x46f2 + 46f0: 5f c0 rjmp .+190 ; 0x47b0 + 46f2: 82 32 cpi r24, 0x22 ; 34 + 46f4: 08 f0 brcs .+2 ; 0x46f8 + 46f6: 4b c0 rjmp .+150 ; 0x478e + 46f8: 80 32 cpi r24, 0x20 ; 32 + 46fa: 79 f7 brne .-34 ; 0x46da + 46fc: 80 91 25 23 lds r24, 0x2325 + Endpoint_ClearStatusStage(); + } + + break; + case CDC_REQ_SetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 4700: 81 32 cpi r24, 0x21 ; 33 + 4702: 59 f7 brne .-42 ; 0x46da + 4704: 34 dd rcall .-1432 ; 0x416e + { + Endpoint_ClearSETUP(); + 4706: 04 c0 rjmp .+8 ; 0x4710 + 4708: 80 91 24 23 lds r24, 0x2324 + + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + 470c: 88 23 and r24, r24 + 470e: 29 f3 breq .-54 ; 0x46da + 4710: 72 dd rcall .-1308 ; 0x41f6 + 4712: 88 23 and r24, r24 + case CDC_REQ_SetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + + while (!(Endpoint_IsOUTReceived())) + 4714: c9 f3 breq .-14 ; 0x4708 + 4716: b5 dc rcall .-1686 ; 0x4082 + 4718: e8 2e mov r14, r24 + 471a: b3 dc rcall .-1690 ; 0x4082 + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + 471c: f8 2e mov r15, r24 + 471e: b1 dc rcall .-1694 ; 0x4082 + 4720: 08 2f mov r16, r24 + uint32_t Byte1 = Endpoint_Read_8(); + 4722: af dc rcall .-1698 ; 0x4082 + 4724: 48 2f mov r20, r24 + 4726: 50 e0 ldi r21, 0x00 ; 0 + uint32_t Byte2 = Endpoint_Read_8(); + 4728: 60 e0 ldi r22, 0x00 ; 0 + 472a: 70 e0 ldi r23, 0x00 ; 0 + 472c: 74 2f mov r23, r20 + uint32_t Byte3 = Endpoint_Read_8(); + 472e: 66 27 eor r22, r22 + 4730: 55 27 eor r21, r21 + 4732: 44 27 eor r20, r20 + 4734: 10 e0 ldi r17, 0x00 ; 0 + 4736: 20 e0 ldi r18, 0x00 ; 0 + 4738: 30 e0 ldi r19, 0x00 ; 0 + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + 473a: 98 01 movw r18, r16 + 473c: 11 27 eor r17, r17 + 473e: 00 27 eor r16, r16 + 4740: 40 2b or r20, r16 + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + uint32_t Byte1 = Endpoint_Read_8(); + uint32_t Byte2 = Endpoint_Read_8(); + 4742: 51 2b or r21, r17 + 4744: 62 2b or r22, r18 + 4746: 73 2b or r23, r19 + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + 4748: 8e 2d mov r24, r14 + 474a: 90 e0 ldi r25, 0x00 ; 0 + 474c: a0 e0 ldi r26, 0x00 ; 0 + 474e: b0 e0 ldi r27, 0x00 ; 0 + 4750: 48 2b or r20, r24 + 4752: 59 2b or r21, r25 + 4754: 6a 2b or r22, r26 + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + 4756: 7b 2b or r23, r27 + 4758: 8f 2d mov r24, r15 + 475a: 90 e0 ldi r25, 0x00 ; 0 + 475c: a0 e0 ldi r26, 0x00 ; 0 + uint32_t Byte1 = Endpoint_Read_8(); + uint32_t Byte2 = Endpoint_Read_8(); + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + 475e: b0 e0 ldi r27, 0x00 ; 0 + 4760: ba 2f mov r27, r26 + 4762: a9 2f mov r26, r25 + 4764: 98 2f mov r25, r24 + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + uint32_t Byte1 = Endpoint_Read_8(); + 4766: 88 27 eor r24, r24 + 4768: 48 2b or r20, r24 + 476a: 59 2b or r21, r25 + 476c: 6a 2b or r22, r26 + uint32_t Byte2 = Endpoint_Read_8(); + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + 476e: 7b 2b or r23, r27 + 4770: 4c 8b std Y+20, r20 ; 0x14 + 4772: 5d 8b std Y+21, r21 ; 0x15 + 4774: 6e 8b std Y+22, r22 ; 0x16 + 4776: 7f 8b std Y+23, r23 ; 0x17 + 4778: 84 dc rcall .-1784 ; 0x4082 + 477a: 88 8f std Y+24, r24 ; 0x18 + 477c: 82 dc rcall .-1788 ; 0x4082 + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE(); + 477e: 89 8f std Y+25, r24 ; 0x19 + 4780: 80 dc rcall .-1792 ; 0x4082 + 4782: 8a 8f std Y+26, r24 ; 0x1a + 4784: 6f dc rcall .-1826 ; 0x4064 + CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8(); + 4786: 4d de rcall .-870 ; 0x4422 + 4788: ce 01 movw r24, r28 + 478a: 9e d1 rcall .+828 ; 0x4ac8 + CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8(); + 478c: a6 cf rjmp .-180 ; 0x46da + 478e: 82 32 cpi r24, 0x22 ; 34 + 4790: 61 f1 breq .+88 ; 0x47ea + CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); + 4792: 83 32 cpi r24, 0x23 ; 35 + 4794: 09 f0 breq .+2 ; 0x4798 + 4796: a1 cf rjmp .-190 ; 0x46da + + Endpoint_ClearOUT(); + 4798: 80 91 25 23 lds r24, 0x2325 + Endpoint_ClearStatusStage(); + 479c: 81 32 cpi r24, 0x21 ; 33 + 479e: 09 f0 breq .+2 ; 0x47a2 + + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + 47a0: 9c cf rjmp .-200 ; 0x46da + 47a2: e5 dc rcall .-1590 ; 0x416e + 47a4: 3e de rcall .-900 ; 0x4422 + 47a6: ce 01 movw r24, r28 + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + 47a8: 60 91 27 23 lds r22, 0x2327 + 47ac: 8d d1 rcall .+794 ; 0x4ac8 + 47ae: 95 cf rjmp .-214 ; 0x46da + 47b0: 80 91 25 23 lds r24, 0x2325 + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SendBreak: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 47b4: 81 3a cpi r24, 0xA1 ; 161 + 47b6: 09 f0 breq .+2 ; 0x47ba + 47b8: 90 cf rjmp .-224 ; 0x46da + 47ba: d9 dc rcall .-1614 ; 0x416e + { + Endpoint_ClearSETUP(); + 47bc: 34 dd rcall .-1432 ; 0x4226 + 47be: 88 23 and r24, r24 + Endpoint_ClearStatusStage(); + 47c0: e9 f3 breq .-6 ; 0x47bc + 47c2: 8c 89 ldd r24, Y+20 ; 0x14 + + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + 47c4: ed 88 ldd r14, Y+21 ; 0x15 + 47c6: fe 88 ldd r15, Y+22 ; 0x16 + 47c8: 0f 89 ldd r16, Y+23 ; 0x17 + 47ca: 6a dc rcall .-1836 ; 0x40a0 + 47cc: 8e 2d mov r24, r14 + 47ce: 68 dc rcall .-1840 ; 0x40a0 + return; + + switch (USB_ControlRequest.bRequest) + { + case CDC_REQ_GetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + 47d0: 8f 2d mov r24, r15 + 47d2: 66 dc rcall .-1844 ; 0x40a0 + 47d4: 80 2f mov r24, r16 + 47d6: 64 dc rcall .-1848 ; 0x40a0 + 47d8: 88 8d ldd r24, Y+24 ; 0x18 + { + Endpoint_ClearSETUP(); + 47da: 62 dc rcall .-1852 ; 0x40a0 + 47dc: 89 8d ldd r24, Y+25 ; 0x19 + + while (!(Endpoint_IsINReady())); + 47de: 60 dc rcall .-1856 ; 0x40a0 + 47e0: 8a 8d ldd r24, Y+26 ; 0x1a + 47e2: 5e dc rcall .-1860 ; 0x40a0 + 47e4: 26 dc rcall .-1972 ; 0x4032 + + Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + 47e6: 1d de rcall .-966 ; 0x4422 + 47e8: 78 cf rjmp .-272 ; 0x46da + 47ea: 80 91 25 23 lds r24, 0x2325 + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_LE(const uint32_t Data) + { + Endpoint_Write_8(Data & 0xFF); + 47ee: 81 32 cpi r24, 0x21 ; 33 + 47f0: 09 f0 breq .+2 ; 0x47f4 + Endpoint_Write_8(Data >> 8); + 47f2: 73 cf rjmp .-282 ; 0x46da + 47f4: bc dc rcall .-1672 ; 0x416e + 47f6: 15 de rcall .-982 ; 0x4422 + Endpoint_Write_8(Data >> 16); + 47f8: 80 91 27 23 lds r24, 0x2327 + 47fc: 90 91 28 23 lds r25, 0x2328 + Endpoint_Write_8(Data >> 24); + 4800: 88 8b std Y+16, r24 ; 0x10 + 4802: 99 8b std Y+17, r25 ; 0x11 + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); + 4804: ce 01 movw r24, r28 + 4806: 60 d1 rcall .+704 ; 0x4ac8 + 4808: 68 cf rjmp .-304 ; 0x46da + +0000480a : + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); + 480a: cf 93 push r28 + 480c: df 93 push r29 + 480e: ec 01 movw r28, r24 + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); + 4810: 40 96 adiw r24, 0x10 ; 16 + 4812: fc 01 movw r30, r24 + 4814: 8b e0 ldi r24, 0x0B ; 11 + + Endpoint_ClearIN(); + 4816: df 01 movw r26, r30 + 4818: 1d 92 st X+, r1 + Endpoint_ClearStatusStage(); + 481a: 8a 95 dec r24 + 481c: e9 f7 brne .-6 ; 0x4818 + 481e: 82 e0 ldi r24, 0x02 ; 2 + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SetControlLineState: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + 4820: 8c 83 std Y+4, r24 ; 0x04 + 4822: 89 87 std Y+9, r24 ; 0x09 + 4824: 83 e0 ldi r24, 0x03 ; 3 + 4826: 8e 87 std Y+14, r24 ; 0x0e + 4828: ce 01 movw r24, r28 + { + Endpoint_ClearSETUP(); + 482a: 01 96 adiw r24, 0x01 ; 1 + 482c: 61 e0 ldi r22, 0x01 ; 1 + Endpoint_ClearStatusStage(); + 482e: 55 dd rcall .-1366 ; 0x42da + 4830: 88 23 and r24, r24 + + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; + 4832: 21 f4 brne .+8 ; 0x483c + 4834: 80 e0 ldi r24, 0x00 ; 0 + 4836: df 91 pop r29 + 4838: cf 91 pop r28 + 483a: 08 95 ret + 483c: ce 01 movw r24, r28 + + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + 483e: 06 96 adiw r24, 0x06 ; 6 + 4840: 61 e0 ldi r22, 0x01 ; 1 + 4842: 4b dd rcall .-1386 ; 0x42da + 4844: 88 23 and r24, r24 + CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1))) + 4846: b1 f3 breq .-20 ; 0x4834 + 4848: ce 01 movw r24, r28 + 484a: 0b 96 adiw r24, 0x0b ; 11 + return false; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1))) + 484c: 61 e0 ldi r22, 0x01 ; 1 + 484e: 45 dd rcall .-1398 ; 0x42da + 4850: df 91 pop r29 + 4852: cf 91 pop r28 + 4854: 08 95 ret + +00004856 : + return false; + + return true; +} + 4856: cf 93 push r28 + 4858: df 93 push r29 + 485a: eb 01 movw r28, r22 +} + +uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const String) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 485c: 20 91 24 23 lds r18, 0x2324 + 4860: 24 30 cpi r18, 0x04 ; 4 + 4862: 21 f0 breq .+8 ; 0x486c + return ENDPOINT_RWSTREAM_DeviceDisconnected; + 4864: 82 e0 ldi r24, 0x02 ; 2 + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + return Endpoint_Write_Stream_LE(String, strlen(String), NULL); +} + 4866: df 91 pop r29 + 4868: cf 91 pop r28 + 486a: 08 95 ret +} + +uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const String) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 486c: fc 01 movw r30, r24 + 486e: 44 89 ldd r20, Z+20 ; 0x14 + 4870: 55 89 ldd r21, Z+21 ; 0x15 + 4872: 66 89 ldd r22, Z+22 ; 0x16 + 4874: 77 89 ldd r23, Z+23 ; 0x17 + 4876: 41 15 cp r20, r1 + 4878: 51 05 cpc r21, r1 + 487a: 61 05 cpc r22, r1 + 487c: 71 05 cpc r23, r1 + 487e: 91 f3 breq .-28 ; 0x4864 + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + 4880: 81 81 ldd r24, Z+1 ; 0x01 + 4882: 1d dc rcall .-1990 ; 0x40be + 4884: fe 01 movw r30, r28 + return Endpoint_Write_Stream_LE(String, strlen(String), NULL); + 4886: 01 90 ld r0, Z+ + 4888: 00 20 and r0, r0 + 488a: e9 f7 brne .-6 ; 0x4886 + 488c: 31 97 sbiw r30, 0x01 ; 1 + 488e: ec 1b sub r30, r28 + 4890: fd 0b sbc r31, r29 + 4892: ce 01 movw r24, r28 + 4894: bf 01 movw r22, r30 + 4896: 40 e0 ldi r20, 0x00 ; 0 + 4898: 50 e0 ldi r21, 0x00 ; 0 + 489a: 0a da rcall .-3052 ; 0x3cb0 + 489c: e4 cf rjmp .-56 ; 0x4866 + +0000489e : + 489e: 0f 93 push r16 + 48a0: 1f 93 push r17 +} + +uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const void* const Buffer, + const uint16_t Length) +{ + 48a2: cf 93 push r28 + 48a4: df 93 push r29 + 48a6: 8b 01 movw r16, r22 + 48a8: ea 01 movw r28, r20 + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 48aa: 20 91 24 23 lds r18, 0x2324 + 48ae: 24 30 cpi r18, 0x04 ; 4 + 48b0: 31 f0 breq .+12 ; 0x48be + return ENDPOINT_RWSTREAM_DeviceDisconnected; + 48b2: 82 e0 ldi r24, 0x02 ; 2 + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + return Endpoint_Write_Stream_LE(Buffer, Length, NULL); +} + 48b4: df 91 pop r29 + 48b6: cf 91 pop r28 + 48b8: 1f 91 pop r17 + 48ba: 0f 91 pop r16 + 48bc: 08 95 ret + +uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const void* const Buffer, + const uint16_t Length) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 48be: fc 01 movw r30, r24 + 48c0: 44 89 ldd r20, Z+20 ; 0x14 + 48c2: 55 89 ldd r21, Z+21 ; 0x15 + 48c4: 66 89 ldd r22, Z+22 ; 0x16 + 48c6: 77 89 ldd r23, Z+23 ; 0x17 + 48c8: 41 15 cp r20, r1 + 48ca: 51 05 cpc r21, r1 + 48cc: 61 05 cpc r22, r1 + 48ce: 71 05 cpc r23, r1 + 48d0: 81 f3 breq .-32 ; 0x48b2 + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + 48d2: 81 81 ldd r24, Z+1 ; 0x01 + 48d4: f4 db rcall .-2072 ; 0x40be + 48d6: c8 01 movw r24, r16 + return Endpoint_Write_Stream_LE(Buffer, Length, NULL); + 48d8: be 01 movw r22, r28 + 48da: 40 e0 ldi r20, 0x00 ; 0 + 48dc: 50 e0 ldi r21, 0x00 ; 0 + 48de: e8 d9 rcall .-3120 ; 0x3cb0 + 48e0: e9 cf rjmp .-46 ; 0x48b4 + +000048e2 : + 48e2: cf 93 push r28 + 48e4: c6 2f mov r28, r22 +} + +uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Data) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 48e6: 20 91 24 23 lds r18, 0x2324 + 48ea: 24 30 cpi r18, 0x04 ; 4 + 48ec: 19 f0 breq .+6 ; 0x48f4 + return ENDPOINT_RWSTREAM_DeviceDisconnected; + 48ee: 82 e0 ldi r24, 0x02 ; 2 + return ErrorCode; + } + + Endpoint_Write_8(Data); + return ENDPOINT_READYWAIT_NoError; +} + 48f0: cf 91 pop r28 + 48f2: 08 95 ret +} + +uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Data) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 48f4: fc 01 movw r30, r24 + 48f6: 44 89 ldd r20, Z+20 ; 0x14 + 48f8: 55 89 ldd r21, Z+21 ; 0x15 + 48fa: 66 89 ldd r22, Z+22 ; 0x16 + 48fc: 77 89 ldd r23, Z+23 ; 0x17 + 48fe: 41 15 cp r20, r1 + 4900: 51 05 cpc r21, r1 + 4902: 61 05 cpc r22, r1 + 4904: 71 05 cpc r23, r1 + 4906: 99 f3 breq .-26 ; 0x48ee + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + 4908: 81 81 ldd r24, Z+1 ; 0x01 + 490a: d9 db rcall .-2126 ; 0x40be + 490c: 20 91 2d 23 lds r18, 0x232D + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length); + 4910: 30 91 2e 23 lds r19, 0x232E + 4914: f9 01 movw r30, r18 + 4916: ef 5b subi r30, 0xBF ; 191 + 4918: ff 4f sbci r31, 0xFF ; 255 + 491a: 90 81 ld r25, Z + 491c: 20 5c subi r18, 0xC0 ; 192 + 491e: 3f 4f sbci r19, 0xFF ; 255 + 4920: f9 01 movw r30, r18 + 4922: 80 81 ld r24, Z + 4924: 98 17 cp r25, r24 + + if (!(Endpoint_IsReadWriteAllowed())) + 4926: 20 f0 brcs .+8 ; 0x4930 + 4928: 84 db rcall .-2296 ; 0x4032 + { + Endpoint_ClearIN(); + 492a: 91 dd rcall .-1246 ; 0x444e + 492c: 88 23 and r24, r24 + + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + 492e: 01 f7 brne .-64 ; 0x48f0 + 4930: 8c 2f mov r24, r28 + 4932: b6 db rcall .-2196 ; 0x40a0 + 4934: 80 e0 ldi r24, 0x00 ; 0 + return ErrorCode; + } + + Endpoint_Write_8(Data); + 4936: dc cf rjmp .-72 ; 0x48f0 + +00004938 : + 4938: 0f 93 push r16 + 493a: 1f 93 push r17 + return ENDPOINT_READYWAIT_NoError; + 493c: cf 93 push r28 + 493e: df 93 push r29 +} + +uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + 4940: 0f 92 push r0 + 4942: cd b7 in r28, 0x3d ; 61 + 4944: de b7 in r29, 0x3e ; 62 + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 4946: 20 91 24 23 lds r18, 0x2324 + 494a: 24 30 cpi r18, 0x04 ; 4 + 494c: 39 f0 breq .+14 ; 0x495c + return ENDPOINT_RWSTREAM_DeviceDisconnected; + 494e: 82 e0 ldi r24, 0x02 ; 2 + + Endpoint_ClearIN(); + } + + return ENDPOINT_READYWAIT_NoError; +} + 4950: 0f 90 pop r0 + 4952: df 91 pop r29 + 4954: cf 91 pop r28 + 4956: 1f 91 pop r17 + 4958: 0f 91 pop r16 + 495a: 08 95 ret + return ENDPOINT_READYWAIT_NoError; +} + +uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 495c: fc 01 movw r30, r24 + 495e: 44 89 ldd r20, Z+20 ; 0x14 + 4960: 55 89 ldd r21, Z+21 ; 0x15 + 4962: 66 89 ldd r22, Z+22 ; 0x16 + 4964: 77 89 ldd r23, Z+23 ; 0x17 + 4966: 41 15 cp r20, r1 + 4968: 51 05 cpc r21, r1 + 496a: 61 05 cpc r22, r1 + 496c: 71 05 cpc r23, r1 + 496e: 79 f3 breq .-34 ; 0x494e + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + 4970: 81 81 ldd r24, Z+1 ; 0x01 + 4972: a5 db rcall .-2230 ; 0x40be + 4974: 80 91 31 23 lds r24, 0x2331 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4978: 20 91 2d 23 lds r18, 0x232D + return USB_Endpoint_SelectedFIFO->Position; + 497c: 30 91 2e 23 lds r19, 0x232E + 4980: f9 01 movw r30, r18 + 4982: 87 fd sbrc r24, 7 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4984: 1d c0 rjmp .+58 ; 0x49c0 + 4986: e0 5c subi r30, 0xC0 ; 192 + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 4988: ff 4f sbci r31, 0xFF ; 255 + 498a: 80 81 ld r24, Z + 498c: f9 01 movw r30, r18 + 498e: ef 5b subi r30, 0xBF ; 191 + 4990: ff 4f sbci r31, 0xFF ; 255 + 4992: 40 81 ld r20, Z + 4994: 90 e0 ldi r25, 0x00 ; 0 + 4996: 84 1b sub r24, r20 + 4998: 91 09 sbc r25, r1 + 499a: 00 97 sbiw r24, 0x00 ; 0 + + if (!(Endpoint_BytesInEndpoint())) + 499c: 11 f4 brne .+4 ; 0x49a2 + 499e: 80 e0 ldi r24, 0x00 ; 0 + return ErrorCode; + + Endpoint_ClearIN(); + } + + return ENDPOINT_READYWAIT_NoError; + 49a0: d7 cf rjmp .-82 ; 0x4950 + 49a2: 00 81 ld r16, Z + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length); + 49a4: 20 5c subi r18, 0xC0 ; 192 + 49a6: 3f 4f sbci r19, 0xFF ; 255 + 49a8: f9 01 movw r30, r18 + 49aa: 10 81 ld r17, Z + 49ac: 42 db rcall .-2428 ; 0x4032 + if (!(Endpoint_BytesInEndpoint())) + return ENDPOINT_READYWAIT_NoError; + + bool BankFull = !(Endpoint_IsReadWriteAllowed()); + + Endpoint_ClearIN(); + 49ae: 01 17 cp r16, r17 + 49b0: b0 f3 brcs .-20 ; 0x499e + + if (BankFull) + 49b2: 4d dd rcall .-1382 ; 0x444e + 49b4: 88 23 and r24, r24 + { + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + 49b6: 61 f6 brne .-104 ; 0x4950 + 49b8: 89 83 std Y+1, r24 ; 0x01 + 49ba: 3b db rcall .-2442 ; 0x4032 + 49bc: 89 81 ldd r24, Y+1 ; 0x01 + return ErrorCode; + + Endpoint_ClearIN(); + 49be: c8 cf rjmp .-112 ; 0x4950 + 49c0: ef 5b subi r30, 0xBF ; 191 + 49c2: ff 4f sbci r31, 0xFF ; 255 + 49c4: 80 81 ld r24, Z + 49c6: 90 e0 ldi r25, 0x00 ; 0 + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + return USB_Endpoint_SelectedFIFO->Position; + 49c8: e8 cf rjmp .-48 ; 0x499a + +000049ca : + 49ca: cf 93 push r28 + 49cc: df 93 push r29 + 49ce: ec 01 movw r28, r24 + 49d0: 80 91 24 23 lds r24, 0x2324 + return true; +} + +void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 49d4: 84 30 cpi r24, 0x04 ; 4 + 49d6: 19 f0 breq .+6 ; 0x49de + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + + if (Endpoint_IsINReady()) + CDC_Device_Flush(CDCInterfaceInfo); + #endif +} + 49d8: df 91 pop r29 + 49da: cf 91 pop r28 + 49dc: 08 95 ret + return true; +} + +void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 49de: 8c 89 ldd r24, Y+20 ; 0x14 + 49e0: 9d 89 ldd r25, Y+21 ; 0x15 + 49e2: ae 89 ldd r26, Y+22 ; 0x16 + 49e4: bf 89 ldd r27, Y+23 ; 0x17 + 49e6: 00 97 sbiw r24, 0x00 ; 0 + 49e8: a1 05 cpc r26, r1 + 49ea: b1 05 cpc r27, r1 + 49ec: a9 f3 breq .-22 ; 0x49d8 + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + 49ee: 89 81 ldd r24, Y+1 ; 0x01 + 49f0: 66 db rcall .-2356 ; 0x40be + 49f2: 19 dc rcall .-1998 ; 0x4226 + + if (Endpoint_IsINReady()) + 49f4: 88 23 and r24, r24 + 49f6: 81 f3 breq .-32 ; 0x49d8 + 49f8: ce 01 movw r24, r28 + 49fa: 9e df rcall .-196 ; 0x4938 + CDC_Device_Flush(CDCInterfaceInfo); + 49fc: ed cf rjmp .-38 ; 0x49d8 + +000049fe : + 49fe: cf 93 push r28 + 4a00: df 93 push r29 + 4a02: 00 d0 rcall .+0 ; 0x4a04 + return 0; + } +} + +int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + 4a04: cd b7 in r28, 0x3d ; 61 + 4a06: de b7 in r29, 0x3e ; 62 + 4a08: fc 01 movw r30, r24 + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + 4a0a: 80 91 24 23 lds r24, 0x2324 + 4a0e: 84 30 cpi r24, 0x04 ; 4 + 4a10: 09 f0 breq .+2 ; 0x4a14 + 4a12: 3e c0 rjmp .+124 ; 0x4a90 + 4a14: 44 89 ldd r20, Z+20 ; 0x14 + 4a16: 55 89 ldd r21, Z+21 ; 0x15 + 4a18: 66 89 ldd r22, Z+22 ; 0x16 + 4a1a: 77 89 ldd r23, Z+23 ; 0x17 + 4a1c: 41 15 cp r20, r1 + 4a1e: 51 05 cpc r21, r1 + 4a20: 61 05 cpc r22, r1 + 4a22: 71 05 cpc r23, r1 + 4a24: a9 f1 breq .+106 ; 0x4a90 + return -1; + + int16_t ReceivedByte = -1; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); + 4a26: 86 81 ldd r24, Z+6 ; 0x06 + 4a28: 4a db rcall .-2412 ; 0x40be + 4a2a: e5 db rcall .-2102 ; 0x41f6 + + if (Endpoint_IsOUTReceived()) + 4a2c: 88 23 and r24, r24 + 4a2e: 81 f1 breq .+96 ; 0x4a90 + 4a30: 80 91 31 23 lds r24, 0x2331 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4a34: 20 91 2d 23 lds r18, 0x232D + return USB_Endpoint_SelectedFIFO->Position; + 4a38: 30 91 2e 23 lds r19, 0x232E + 4a3c: f9 01 movw r30, r18 + 4a3e: 87 fd sbrc r24, 7 + 4a40: 3e c0 rjmp .+124 ; 0x4abe + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4a42: e0 5c subi r30, 0xC0 ; 192 + 4a44: ff 4f sbci r31, 0xFF ; 255 + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 4a46: 80 81 ld r24, Z + 4a48: f9 01 movw r30, r18 + 4a4a: ef 5b subi r30, 0xBF ; 191 + 4a4c: ff 4f sbci r31, 0xFF ; 255 + 4a4e: 40 81 ld r20, Z + 4a50: 90 e0 ldi r25, 0x00 ; 0 + 4a52: 84 1b sub r24, r20 + 4a54: 91 09 sbc r25, r1 + 4a56: 00 97 sbiw r24, 0x00 ; 0 + 4a58: 11 f5 brne .+68 ; 0x4a9e + { + if (Endpoint_BytesInEndpoint()) + 4a5a: 8f ef ldi r24, 0xFF ; 255 + 4a5c: 9f ef ldi r25, 0xFF ; 255 +int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return -1; + + int16_t ReceivedByte = -1; + 4a5e: 40 91 31 23 lds r20, 0x2331 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4a62: 47 fd sbrc r20, 7 + 4a64: 29 c0 rjmp .+82 ; 0x4ab8 + 4a66: 20 5c subi r18, 0xC0 ; 192 + 4a68: 3f 4f sbci r19, 0xFF ; 255 + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + 4a6a: d9 01 movw r26, r18 + 4a6c: 2c 91 ld r18, X + 4a6e: 40 81 ld r20, Z + 4a70: 30 e0 ldi r19, 0x00 ; 0 + 4a72: 24 1b sub r18, r20 + 4a74: 31 09 sbc r19, r1 + 4a76: 21 15 cp r18, r1 + 4a78: 31 05 cpc r19, r1 + if (Endpoint_IsOUTReceived()) + { + if (Endpoint_BytesInEndpoint()) + ReceivedByte = Endpoint_Read_8(); + + if (!(Endpoint_BytesInEndpoint())) + 4a7a: 61 f4 brne .+24 ; 0x4a94 + 4a7c: 89 83 std Y+1, r24 ; 0x01 + 4a7e: 9a 83 std Y+2, r25 ; 0x02 + Endpoint_ClearOUT(); + 4a80: f1 da rcall .-2590 ; 0x4064 + 4a82: 89 81 ldd r24, Y+1 ; 0x01 + 4a84: 9a 81 ldd r25, Y+2 ; 0x02 + 4a86: 0f 90 pop r0 + 4a88: 0f 90 pop r0 + 4a8a: df 91 pop r29 + } + + return ReceivedByte; +} + 4a8c: cf 91 pop r28 + 4a8e: 08 95 ret + 4a90: 8f ef ldi r24, 0xFF ; 255 + 4a92: 9f ef ldi r25, 0xFF ; 255 + 4a94: 0f 90 pop r0 +int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return -1; + + int16_t ReceivedByte = -1; + 4a96: 0f 90 pop r0 + 4a98: df 91 pop r29 + if (!(Endpoint_BytesInEndpoint())) + Endpoint_ClearOUT(); + } + + return ReceivedByte; +} + 4a9a: cf 91 pop r28 + 4a9c: 08 95 ret + 4a9e: f1 da rcall .-2590 ; 0x4082 + 4aa0: 90 e0 ldi r25, 0x00 ; 0 + 4aa2: 20 91 2d 23 lds r18, 0x232D + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); + + if (Endpoint_IsOUTReceived()) + { + if (Endpoint_BytesInEndpoint()) + ReceivedByte = Endpoint_Read_8(); + 4aa6: 30 91 2e 23 lds r19, 0x232E + 4aaa: f9 01 movw r30, r18 + 4aac: ef 5b subi r30, 0xBF ; 191 + 4aae: ff 4f sbci r31, 0xFF ; 255 + 4ab0: 40 91 31 23 lds r20, 0x2331 + 4ab4: 47 ff sbrs r20, 7 + 4ab6: d7 cf rjmp .-82 ; 0x4a66 + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + 4ab8: 20 81 ld r18, Z + 4aba: 30 e0 ldi r19, 0x00 ; 0 + 4abc: dc cf rjmp .-72 ; 0x4a76 + 4abe: ef 5b subi r30, 0xBF ; 191 + return USB_Endpoint_SelectedFIFO->Position; + 4ac0: ff 4f sbci r31, 0xFF ; 255 + 4ac2: 80 81 ld r24, Z + 4ac4: 90 e0 ldi r25, 0x00 ; 0 + 4ac6: c7 cf rjmp .-114 ; 0x4a56 + +00004ac8 : + 4ac8: 08 95 ret + +00004aca <__mulsi3>: + 4aca: 62 9f mul r22, r18 + 4acc: d0 01 movw r26, r0 + 4ace: 73 9f mul r23, r19 + 4ad0: f0 01 movw r30, r0 + 4ad2: 82 9f mul r24, r18 + 4ad4: e0 0d add r30, r0 + 4ad6: f1 1d adc r31, r1 + 4ad8: 64 9f mul r22, r20 + 4ada: e0 0d add r30, r0 + 4adc: f1 1d adc r31, r1 + 4ade: 92 9f mul r25, r18 + 4ae0: f0 0d add r31, r0 + 4ae2: 83 9f mul r24, r19 + 4ae4: f0 0d add r31, r0 + 4ae6: 74 9f mul r23, r20 + 4ae8: f0 0d add r31, r0 + 4aea: 65 9f mul r22, r21 + 4aec: f0 0d add r31, r0 + 4aee: 99 27 eor r25, r25 + 4af0: 72 9f mul r23, r18 + 4af2: b0 0d add r27, r0 + 4af4: e1 1d adc r30, r1 + 4af6: f9 1f adc r31, r25 + 4af8: 63 9f mul r22, r19 + 4afa: b0 0d add r27, r0 + 4afc: e1 1d adc r30, r1 + 4afe: f9 1f adc r31, r25 + 4b00: bd 01 movw r22, r26 + 4b02: cf 01 movw r24, r30 + 4b04: 11 24 eor r1, r1 + 4b06: 08 95 ret + +00004b08 : + 4b08: 8f 92 push r8 + 4b0a: 9f 92 push r9 + 4b0c: af 92 push r10 + 4b0e: bf 92 push r11 + 4b10: cf 92 push r12 + 4b12: df 92 push r13 + 4b14: ef 92 push r14 + 4b16: ff 92 push r15 + 4b18: cf 93 push r28 + 4b1a: df 93 push r29 + 4b1c: ec 01 movw r28, r24 + 4b1e: 88 81 ld r24, Y + 4b20: 99 81 ldd r25, Y+1 ; 0x01 + 4b22: aa 81 ldd r26, Y+2 ; 0x02 + 4b24: bb 81 ldd r27, Y+3 ; 0x03 + 4b26: 00 97 sbiw r24, 0x00 ; 0 + 4b28: a1 05 cpc r26, r1 + 4b2a: b1 05 cpc r27, r1 + 4b2c: 21 f4 brne .+8 ; 0x4b36 + 4b2e: 84 e2 ldi r24, 0x24 ; 36 + 4b30: 99 ed ldi r25, 0xD9 ; 217 + 4b32: ab e5 ldi r26, 0x5B ; 91 + 4b34: b7 e0 ldi r27, 0x07 ; 7 + 4b36: bc 01 movw r22, r24 + 4b38: cd 01 movw r24, r26 + 4b3a: 2d e1 ldi r18, 0x1D ; 29 + 4b3c: 33 ef ldi r19, 0xF3 ; 243 + 4b3e: 41 e0 ldi r20, 0x01 ; 1 + 4b40: 50 e0 ldi r21, 0x00 ; 0 + 4b42: 3d d3 rcall .+1658 ; 0x51be <__divmodsi4> + 4b44: 49 01 movw r8, r18 + 4b46: 5a 01 movw r10, r20 + 4b48: 27 ea ldi r18, 0xA7 ; 167 + 4b4a: 31 e4 ldi r19, 0x41 ; 65 + 4b4c: 40 e0 ldi r20, 0x00 ; 0 + 4b4e: 50 e0 ldi r21, 0x00 ; 0 + 4b50: bc df rcall .-136 ; 0x4aca <__mulsi3> + 4b52: 6b 01 movw r12, r22 + 4b54: 7c 01 movw r14, r24 + 4b56: c5 01 movw r24, r10 + 4b58: b4 01 movw r22, r8 + 4b5a: 2c ee ldi r18, 0xEC ; 236 + 4b5c: 34 ef ldi r19, 0xF4 ; 244 + 4b5e: 4f ef ldi r20, 0xFF ; 255 + 4b60: 5f ef ldi r21, 0xFF ; 255 + 4b62: b3 df rcall .-154 ; 0x4aca <__mulsi3> + 4b64: dc 01 movw r26, r24 + 4b66: cb 01 movw r24, r22 + 4b68: c8 0e add r12, r24 + 4b6a: d9 1e adc r13, r25 + 4b6c: ea 1e adc r14, r26 + 4b6e: fb 1e adc r15, r27 + 4b70: f7 fe sbrs r15, 7 + 4b72: 08 c0 rjmp .+16 ; 0x4b84 + 4b74: 8f ef ldi r24, 0xFF ; 255 + 4b76: 9f ef ldi r25, 0xFF ; 255 + 4b78: af ef ldi r26, 0xFF ; 255 + 4b7a: bf e7 ldi r27, 0x7F ; 127 + 4b7c: c8 0e add r12, r24 + 4b7e: d9 1e adc r13, r25 + 4b80: ea 1e adc r14, r26 + 4b82: fb 1e adc r15, r27 + 4b84: c8 82 st Y, r12 + 4b86: d9 82 std Y+1, r13 ; 0x01 + 4b88: ea 82 std Y+2, r14 ; 0x02 + 4b8a: fb 82 std Y+3, r15 ; 0x03 + 4b8c: c6 01 movw r24, r12 + 4b8e: 9f 77 andi r25, 0x7F ; 127 + 4b90: df 91 pop r29 + 4b92: cf 91 pop r28 + 4b94: ff 90 pop r15 + 4b96: ef 90 pop r14 + 4b98: df 90 pop r13 + 4b9a: cf 90 pop r12 + 4b9c: bf 90 pop r11 + 4b9e: af 90 pop r10 + 4ba0: 9f 90 pop r9 + 4ba2: 8f 90 pop r8 + 4ba4: 08 95 ret + +00004ba6 : + 4ba6: b0 cf rjmp .-160 ; 0x4b08 + +00004ba8 : + 4ba8: 8d e9 ldi r24, 0x9D ; 157 + 4baa: 90 e2 ldi r25, 0x20 ; 32 + 4bac: ad cf rjmp .-166 ; 0x4b08 + +00004bae : + 4bae: a0 e0 ldi r26, 0x00 ; 0 + 4bb0: b0 e0 ldi r27, 0x00 ; 0 + 4bb2: 80 93 9d 20 sts 0x209D, r24 + 4bb6: 90 93 9e 20 sts 0x209E, r25 + 4bba: a0 93 9f 20 sts 0x209F, r26 + 4bbe: b0 93 a0 20 sts 0x20A0, r27 + 4bc2: 08 95 ret + +00004bc4 : + 4bc4: fb 01 movw r30, r22 + 4bc6: dc 01 movw r26, r24 + 4bc8: 02 c0 rjmp .+4 ; 0x4bce + 4bca: 05 90 lpm r0, Z+ + 4bcc: 0d 92 st X+, r0 + 4bce: 41 50 subi r20, 0x01 ; 1 + 4bd0: 50 40 sbci r21, 0x00 ; 0 + 4bd2: d8 f7 brcc .-10 ; 0x4bca + 4bd4: 08 95 ret + +00004bd6 : + 4bd6: fb 01 movw r30, r22 + 4bd8: dc 01 movw r26, r24 + 4bda: 8d 91 ld r24, X+ + 4bdc: 05 90 lpm r0, Z+ + 4bde: 80 19 sub r24, r0 + 4be0: 01 10 cpse r0, r1 + 4be2: d9 f3 breq .-10 ; 0x4bda + 4be4: 99 0b sbc r25, r25 + 4be6: 08 95 ret + +00004be8 : + 4be8: fb 01 movw r30, r22 + 4bea: dc 01 movw r26, r24 + 4bec: 41 50 subi r20, 0x01 ; 1 + 4bee: 50 40 sbci r21, 0x00 ; 0 + 4bf0: 48 f0 brcs .+18 ; 0x4c04 + 4bf2: 05 90 lpm r0, Z+ + 4bf4: 0d 92 st X+, r0 + 4bf6: 00 20 and r0, r0 + 4bf8: c9 f7 brne .-14 ; 0x4bec + 4bfa: 01 c0 rjmp .+2 ; 0x4bfe + 4bfc: 1d 92 st X+, r1 + 4bfe: 41 50 subi r20, 0x01 ; 1 + 4c00: 50 40 sbci r21, 0x00 ; 0 + 4c02: e0 f7 brcc .-8 ; 0x4bfc + 4c04: 08 95 ret + +00004c06 : + 4c06: fb 01 movw r30, r22 + 4c08: dc 01 movw r26, r24 + 4c0a: 02 c0 rjmp .+4 ; 0x4c10 + 4c0c: 01 90 ld r0, Z+ + 4c0e: 0d 92 st X+, r0 + 4c10: 41 50 subi r20, 0x01 ; 1 + 4c12: 50 40 sbci r21, 0x00 ; 0 + 4c14: d8 f7 brcc .-10 ; 0x4c0c + 4c16: 08 95 ret + +00004c18 : + 4c18: ae e0 ldi r26, 0x0E ; 14 + 4c1a: b0 e0 ldi r27, 0x00 ; 0 + 4c1c: e1 e1 ldi r30, 0x11 ; 17 + 4c1e: f6 e2 ldi r31, 0x26 ; 38 + 4c20: f7 c2 rjmp .+1518 ; 0x5210 <__prologue_saves__+0x1c> + 4c22: 0d 89 ldd r16, Y+21 ; 0x15 + 4c24: 1e 89 ldd r17, Y+22 ; 0x16 + 4c26: 8f 89 ldd r24, Y+23 ; 0x17 + 4c28: 98 8d ldd r25, Y+24 ; 0x18 + 4c2a: 2e e0 ldi r18, 0x0E ; 14 + 4c2c: 2c 83 std Y+4, r18 ; 0x04 + 4c2e: 09 83 std Y+1, r16 ; 0x01 + 4c30: 1a 83 std Y+2, r17 ; 0x02 + 4c32: 97 ff sbrs r25, 7 + 4c34: 02 c0 rjmp .+4 ; 0x4c3a + 4c36: 80 e0 ldi r24, 0x00 ; 0 + 4c38: 90 e8 ldi r25, 0x80 ; 128 + 4c3a: 01 97 sbiw r24, 0x01 ; 1 + 4c3c: 8d 83 std Y+5, r24 ; 0x05 + 4c3e: 9e 83 std Y+6, r25 ; 0x06 + 4c40: ae 01 movw r20, r28 + 4c42: 45 5e subi r20, 0xE5 ; 229 + 4c44: 5f 4f sbci r21, 0xFF ; 255 + 4c46: ce 01 movw r24, r28 + 4c48: 01 96 adiw r24, 0x01 ; 1 + 4c4a: 69 8d ldd r22, Y+25 ; 0x19 + 4c4c: 7a 8d ldd r23, Y+26 ; 0x1a + 4c4e: 11 d0 rcall .+34 ; 0x4c72 + 4c50: 4d 81 ldd r20, Y+5 ; 0x05 + 4c52: 5e 81 ldd r21, Y+6 ; 0x06 + 4c54: 57 fd sbrc r21, 7 + 4c56: 0a c0 rjmp .+20 ; 0x4c6c + 4c58: 2f 81 ldd r18, Y+7 ; 0x07 + 4c5a: 38 85 ldd r19, Y+8 ; 0x08 + 4c5c: 42 17 cp r20, r18 + 4c5e: 53 07 cpc r21, r19 + 4c60: 0c f4 brge .+2 ; 0x4c64 + 4c62: 9a 01 movw r18, r20 + 4c64: 02 0f add r16, r18 + 4c66: 13 1f adc r17, r19 + 4c68: f8 01 movw r30, r16 + 4c6a: 10 82 st Z, r1 + 4c6c: 2e 96 adiw r28, 0x0e ; 14 + 4c6e: e4 e0 ldi r30, 0x04 ; 4 + 4c70: e8 c2 rjmp .+1488 ; 0x5242 <__epilogue_restores__+0x1c> + +00004c72 : + 4c72: ad e0 ldi r26, 0x0D ; 13 + 4c74: b0 e0 ldi r27, 0x00 ; 0 + 4c76: ee e3 ldi r30, 0x3E ; 62 + 4c78: f6 e2 ldi r31, 0x26 ; 38 + 4c7a: bc c2 rjmp .+1400 ; 0x51f4 <__prologue_saves__> + 4c7c: 3c 01 movw r6, r24 + 4c7e: 6c 87 std Y+12, r22 ; 0x0c + 4c80: 7d 87 std Y+13, r23 ; 0x0d + 4c82: 5a 01 movw r10, r20 + 4c84: fc 01 movw r30, r24 + 4c86: 16 82 std Z+6, r1 ; 0x06 + 4c88: 17 82 std Z+7, r1 ; 0x07 + 4c8a: 83 81 ldd r24, Z+3 ; 0x03 + 4c8c: 81 ff sbrs r24, 1 + 4c8e: bb c1 rjmp .+886 ; 0x5006 + 4c90: 2e 01 movw r4, r28 + 4c92: 08 94 sec + 4c94: 41 1c adc r4, r1 + 4c96: 51 1c adc r5, r1 + 4c98: f3 01 movw r30, r6 + 4c9a: 93 81 ldd r25, Z+3 ; 0x03 + 4c9c: ec 85 ldd r30, Y+12 ; 0x0c + 4c9e: fd 85 ldd r31, Y+13 ; 0x0d + 4ca0: 93 fd sbrc r25, 3 + 4ca2: 85 91 lpm r24, Z+ + 4ca4: 93 ff sbrs r25, 3 + 4ca6: 81 91 ld r24, Z+ + 4ca8: ec 87 std Y+12, r30 ; 0x0c + 4caa: fd 87 std Y+13, r31 ; 0x0d + 4cac: 88 23 and r24, r24 + 4cae: 09 f4 brne .+2 ; 0x4cb2 + 4cb0: a6 c1 rjmp .+844 ; 0x4ffe + 4cb2: 85 32 cpi r24, 0x25 ; 37 + 4cb4: 41 f4 brne .+16 ; 0x4cc6 + 4cb6: 93 fd sbrc r25, 3 + 4cb8: 85 91 lpm r24, Z+ + 4cba: 93 ff sbrs r25, 3 + 4cbc: 81 91 ld r24, Z+ + 4cbe: ec 87 std Y+12, r30 ; 0x0c + 4cc0: fd 87 std Y+13, r31 ; 0x0d + 4cc2: 85 32 cpi r24, 0x25 ; 37 + 4cc4: 21 f4 brne .+8 ; 0x4cce + 4cc6: 90 e0 ldi r25, 0x00 ; 0 + 4cc8: b3 01 movw r22, r6 + 4cca: ef d1 rcall .+990 ; 0x50aa + 4ccc: e5 cf rjmp .-54 ; 0x4c98 + 4cce: ff 24 eor r15, r15 + 4cd0: ee 24 eor r14, r14 + 4cd2: 10 e0 ldi r17, 0x00 ; 0 + 4cd4: 10 32 cpi r17, 0x20 ; 32 + 4cd6: b0 f4 brcc .+44 ; 0x4d04 + 4cd8: 8b 32 cpi r24, 0x2B ; 43 + 4cda: 69 f0 breq .+26 ; 0x4cf6 + 4cdc: 8c 32 cpi r24, 0x2C ; 44 + 4cde: 28 f4 brcc .+10 ; 0x4cea + 4ce0: 80 32 cpi r24, 0x20 ; 32 + 4ce2: 51 f0 breq .+20 ; 0x4cf8 + 4ce4: 83 32 cpi r24, 0x23 ; 35 + 4ce6: 71 f4 brne .+28 ; 0x4d04 + 4ce8: 0b c0 rjmp .+22 ; 0x4d00 + 4cea: 8d 32 cpi r24, 0x2D ; 45 + 4cec: 39 f0 breq .+14 ; 0x4cfc + 4cee: 80 33 cpi r24, 0x30 ; 48 + 4cf0: 49 f4 brne .+18 ; 0x4d04 + 4cf2: 11 60 ori r17, 0x01 ; 1 + 4cf4: 2c c0 rjmp .+88 ; 0x4d4e + 4cf6: 12 60 ori r17, 0x02 ; 2 + 4cf8: 14 60 ori r17, 0x04 ; 4 + 4cfa: 29 c0 rjmp .+82 ; 0x4d4e + 4cfc: 18 60 ori r17, 0x08 ; 8 + 4cfe: 27 c0 rjmp .+78 ; 0x4d4e + 4d00: 10 61 ori r17, 0x10 ; 16 + 4d02: 25 c0 rjmp .+74 ; 0x4d4e + 4d04: 17 fd sbrc r17, 7 + 4d06: 2e c0 rjmp .+92 ; 0x4d64 + 4d08: 28 2f mov r18, r24 + 4d0a: 20 53 subi r18, 0x30 ; 48 + 4d0c: 2a 30 cpi r18, 0x0A ; 10 + 4d0e: 98 f4 brcc .+38 ; 0x4d36 + 4d10: 16 ff sbrs r17, 6 + 4d12: 08 c0 rjmp .+16 ; 0x4d24 + 4d14: 8f 2d mov r24, r15 + 4d16: 88 0f add r24, r24 + 4d18: f8 2e mov r15, r24 + 4d1a: ff 0c add r15, r15 + 4d1c: ff 0c add r15, r15 + 4d1e: f8 0e add r15, r24 + 4d20: f2 0e add r15, r18 + 4d22: 15 c0 rjmp .+42 ; 0x4d4e + 4d24: 8e 2d mov r24, r14 + 4d26: 88 0f add r24, r24 + 4d28: e8 2e mov r14, r24 + 4d2a: ee 0c add r14, r14 + 4d2c: ee 0c add r14, r14 + 4d2e: e8 0e add r14, r24 + 4d30: e2 0e add r14, r18 + 4d32: 10 62 ori r17, 0x20 ; 32 + 4d34: 0c c0 rjmp .+24 ; 0x4d4e + 4d36: 8e 32 cpi r24, 0x2E ; 46 + 4d38: 21 f4 brne .+8 ; 0x4d42 + 4d3a: 16 fd sbrc r17, 6 + 4d3c: 60 c1 rjmp .+704 ; 0x4ffe + 4d3e: 10 64 ori r17, 0x40 ; 64 + 4d40: 06 c0 rjmp .+12 ; 0x4d4e + 4d42: 8c 36 cpi r24, 0x6C ; 108 + 4d44: 11 f4 brne .+4 ; 0x4d4a + 4d46: 10 68 ori r17, 0x80 ; 128 + 4d48: 02 c0 rjmp .+4 ; 0x4d4e + 4d4a: 88 36 cpi r24, 0x68 ; 104 + 4d4c: 59 f4 brne .+22 ; 0x4d64 + 4d4e: ec 85 ldd r30, Y+12 ; 0x0c + 4d50: fd 85 ldd r31, Y+13 ; 0x0d + 4d52: 93 fd sbrc r25, 3 + 4d54: 85 91 lpm r24, Z+ + 4d56: 93 ff sbrs r25, 3 + 4d58: 81 91 ld r24, Z+ + 4d5a: ec 87 std Y+12, r30 ; 0x0c + 4d5c: fd 87 std Y+13, r31 ; 0x0d + 4d5e: 88 23 and r24, r24 + 4d60: 09 f0 breq .+2 ; 0x4d64 + 4d62: b8 cf rjmp .-144 ; 0x4cd4 + 4d64: 98 2f mov r25, r24 + 4d66: 95 54 subi r25, 0x45 ; 69 + 4d68: 93 30 cpi r25, 0x03 ; 3 + 4d6a: 18 f0 brcs .+6 ; 0x4d72 + 4d6c: 90 52 subi r25, 0x20 ; 32 + 4d6e: 93 30 cpi r25, 0x03 ; 3 + 4d70: 38 f4 brcc .+14 ; 0x4d80 + 4d72: 24 e0 ldi r18, 0x04 ; 4 + 4d74: 30 e0 ldi r19, 0x00 ; 0 + 4d76: a2 0e add r10, r18 + 4d78: b3 1e adc r11, r19 + 4d7a: 3f e3 ldi r19, 0x3F ; 63 + 4d7c: 39 83 std Y+1, r19 ; 0x01 + 4d7e: 0f c0 rjmp .+30 ; 0x4d9e + 4d80: 83 36 cpi r24, 0x63 ; 99 + 4d82: 31 f0 breq .+12 ; 0x4d90 + 4d84: 83 37 cpi r24, 0x73 ; 115 + 4d86: 81 f0 breq .+32 ; 0x4da8 + 4d88: 83 35 cpi r24, 0x53 ; 83 + 4d8a: 09 f0 breq .+2 ; 0x4d8e + 4d8c: 56 c0 rjmp .+172 ; 0x4e3a + 4d8e: 21 c0 rjmp .+66 ; 0x4dd2 + 4d90: f5 01 movw r30, r10 + 4d92: 80 81 ld r24, Z + 4d94: 89 83 std Y+1, r24 ; 0x01 + 4d96: 22 e0 ldi r18, 0x02 ; 2 + 4d98: 30 e0 ldi r19, 0x00 ; 0 + 4d9a: a2 0e add r10, r18 + 4d9c: b3 1e adc r11, r19 + 4d9e: 21 e0 ldi r18, 0x01 ; 1 + 4da0: c2 2e mov r12, r18 + 4da2: d1 2c mov r13, r1 + 4da4: 42 01 movw r8, r4 + 4da6: 13 c0 rjmp .+38 ; 0x4dce + 4da8: 92 e0 ldi r25, 0x02 ; 2 + 4daa: 29 2e mov r2, r25 + 4dac: 31 2c mov r3, r1 + 4dae: 2a 0c add r2, r10 + 4db0: 3b 1c adc r3, r11 + 4db2: f5 01 movw r30, r10 + 4db4: 80 80 ld r8, Z + 4db6: 91 80 ldd r9, Z+1 ; 0x01 + 4db8: 16 ff sbrs r17, 6 + 4dba: 03 c0 rjmp .+6 ; 0x4dc2 + 4dbc: 6f 2d mov r22, r15 + 4dbe: 70 e0 ldi r23, 0x00 ; 0 + 4dc0: 02 c0 rjmp .+4 ; 0x4dc6 + 4dc2: 6f ef ldi r22, 0xFF ; 255 + 4dc4: 7f ef ldi r23, 0xFF ; 255 + 4dc6: c4 01 movw r24, r8 + 4dc8: 65 d1 rcall .+714 ; 0x5094 + 4dca: 6c 01 movw r12, r24 + 4dcc: 51 01 movw r10, r2 + 4dce: 1f 77 andi r17, 0x7F ; 127 + 4dd0: 14 c0 rjmp .+40 ; 0x4dfa + 4dd2: 82 e0 ldi r24, 0x02 ; 2 + 4dd4: 28 2e mov r2, r24 + 4dd6: 31 2c mov r3, r1 + 4dd8: 2a 0c add r2, r10 + 4dda: 3b 1c adc r3, r11 + 4ddc: f5 01 movw r30, r10 + 4dde: 80 80 ld r8, Z + 4de0: 91 80 ldd r9, Z+1 ; 0x01 + 4de2: 16 ff sbrs r17, 6 + 4de4: 03 c0 rjmp .+6 ; 0x4dec + 4de6: 6f 2d mov r22, r15 + 4de8: 70 e0 ldi r23, 0x00 ; 0 + 4dea: 02 c0 rjmp .+4 ; 0x4df0 + 4dec: 6f ef ldi r22, 0xFF ; 255 + 4dee: 7f ef ldi r23, 0xFF ; 255 + 4df0: c4 01 movw r24, r8 + 4df2: 45 d1 rcall .+650 ; 0x507e + 4df4: 6c 01 movw r12, r24 + 4df6: 10 68 ori r17, 0x80 ; 128 + 4df8: 51 01 movw r10, r2 + 4dfa: 13 fd sbrc r17, 3 + 4dfc: 1a c0 rjmp .+52 ; 0x4e32 + 4dfe: 05 c0 rjmp .+10 ; 0x4e0a + 4e00: 80 e2 ldi r24, 0x20 ; 32 + 4e02: 90 e0 ldi r25, 0x00 ; 0 + 4e04: b3 01 movw r22, r6 + 4e06: 51 d1 rcall .+674 ; 0x50aa + 4e08: ea 94 dec r14 + 4e0a: 8e 2d mov r24, r14 + 4e0c: 90 e0 ldi r25, 0x00 ; 0 + 4e0e: c8 16 cp r12, r24 + 4e10: d9 06 cpc r13, r25 + 4e12: b0 f3 brcs .-20 ; 0x4e00 + 4e14: 0e c0 rjmp .+28 ; 0x4e32 + 4e16: f4 01 movw r30, r8 + 4e18: 17 fd sbrc r17, 7 + 4e1a: 85 91 lpm r24, Z+ + 4e1c: 17 ff sbrs r17, 7 + 4e1e: 81 91 ld r24, Z+ + 4e20: 4f 01 movw r8, r30 + 4e22: 90 e0 ldi r25, 0x00 ; 0 + 4e24: b3 01 movw r22, r6 + 4e26: 41 d1 rcall .+642 ; 0x50aa + 4e28: e1 10 cpse r14, r1 + 4e2a: ea 94 dec r14 + 4e2c: 08 94 sec + 4e2e: c1 08 sbc r12, r1 + 4e30: d1 08 sbc r13, r1 + 4e32: c1 14 cp r12, r1 + 4e34: d1 04 cpc r13, r1 + 4e36: 79 f7 brne .-34 ; 0x4e16 + 4e38: df c0 rjmp .+446 ; 0x4ff8 + 4e3a: 84 36 cpi r24, 0x64 ; 100 + 4e3c: 11 f0 breq .+4 ; 0x4e42 + 4e3e: 89 36 cpi r24, 0x69 ; 105 + 4e40: 49 f5 brne .+82 ; 0x4e94 + 4e42: f5 01 movw r30, r10 + 4e44: 17 ff sbrs r17, 7 + 4e46: 07 c0 rjmp .+14 ; 0x4e56 + 4e48: 80 81 ld r24, Z + 4e4a: 91 81 ldd r25, Z+1 ; 0x01 + 4e4c: a2 81 ldd r26, Z+2 ; 0x02 + 4e4e: b3 81 ldd r27, Z+3 ; 0x03 + 4e50: 24 e0 ldi r18, 0x04 ; 4 + 4e52: 30 e0 ldi r19, 0x00 ; 0 + 4e54: 08 c0 rjmp .+16 ; 0x4e66 + 4e56: 80 81 ld r24, Z + 4e58: 91 81 ldd r25, Z+1 ; 0x01 + 4e5a: aa 27 eor r26, r26 + 4e5c: 97 fd sbrc r25, 7 + 4e5e: a0 95 com r26 + 4e60: ba 2f mov r27, r26 + 4e62: 22 e0 ldi r18, 0x02 ; 2 + 4e64: 30 e0 ldi r19, 0x00 ; 0 + 4e66: a2 0e add r10, r18 + 4e68: b3 1e adc r11, r19 + 4e6a: 01 2f mov r16, r17 + 4e6c: 0f 76 andi r16, 0x6F ; 111 + 4e6e: b7 ff sbrs r27, 7 + 4e70: 08 c0 rjmp .+16 ; 0x4e82 + 4e72: b0 95 com r27 + 4e74: a0 95 com r26 + 4e76: 90 95 com r25 + 4e78: 81 95 neg r24 + 4e7a: 9f 4f sbci r25, 0xFF ; 255 + 4e7c: af 4f sbci r26, 0xFF ; 255 + 4e7e: bf 4f sbci r27, 0xFF ; 255 + 4e80: 00 68 ori r16, 0x80 ; 128 + 4e82: bc 01 movw r22, r24 + 4e84: cd 01 movw r24, r26 + 4e86: a2 01 movw r20, r4 + 4e88: 2a e0 ldi r18, 0x0A ; 10 + 4e8a: 30 e0 ldi r19, 0x00 ; 0 + 4e8c: 3a d1 rcall .+628 ; 0x5102 <__ultoa_invert> + 4e8e: d8 2e mov r13, r24 + 4e90: d4 18 sub r13, r4 + 4e92: 3e c0 rjmp .+124 ; 0x4f10 + 4e94: 85 37 cpi r24, 0x75 ; 117 + 4e96: 21 f4 brne .+8 ; 0x4ea0 + 4e98: 1f 7e andi r17, 0xEF ; 239 + 4e9a: 2a e0 ldi r18, 0x0A ; 10 + 4e9c: 30 e0 ldi r19, 0x00 ; 0 + 4e9e: 20 c0 rjmp .+64 ; 0x4ee0 + 4ea0: 19 7f andi r17, 0xF9 ; 249 + 4ea2: 8f 36 cpi r24, 0x6F ; 111 + 4ea4: a9 f0 breq .+42 ; 0x4ed0 + 4ea6: 80 37 cpi r24, 0x70 ; 112 + 4ea8: 20 f4 brcc .+8 ; 0x4eb2 + 4eaa: 88 35 cpi r24, 0x58 ; 88 + 4eac: 09 f0 breq .+2 ; 0x4eb0 + 4eae: a7 c0 rjmp .+334 ; 0x4ffe + 4eb0: 0b c0 rjmp .+22 ; 0x4ec8 + 4eb2: 80 37 cpi r24, 0x70 ; 112 + 4eb4: 21 f0 breq .+8 ; 0x4ebe + 4eb6: 88 37 cpi r24, 0x78 ; 120 + 4eb8: 09 f0 breq .+2 ; 0x4ebc + 4eba: a1 c0 rjmp .+322 ; 0x4ffe + 4ebc: 01 c0 rjmp .+2 ; 0x4ec0 + 4ebe: 10 61 ori r17, 0x10 ; 16 + 4ec0: 14 ff sbrs r17, 4 + 4ec2: 09 c0 rjmp .+18 ; 0x4ed6 + 4ec4: 14 60 ori r17, 0x04 ; 4 + 4ec6: 07 c0 rjmp .+14 ; 0x4ed6 + 4ec8: 14 ff sbrs r17, 4 + 4eca: 08 c0 rjmp .+16 ; 0x4edc + 4ecc: 16 60 ori r17, 0x06 ; 6 + 4ece: 06 c0 rjmp .+12 ; 0x4edc + 4ed0: 28 e0 ldi r18, 0x08 ; 8 + 4ed2: 30 e0 ldi r19, 0x00 ; 0 + 4ed4: 05 c0 rjmp .+10 ; 0x4ee0 + 4ed6: 20 e1 ldi r18, 0x10 ; 16 + 4ed8: 30 e0 ldi r19, 0x00 ; 0 + 4eda: 02 c0 rjmp .+4 ; 0x4ee0 + 4edc: 20 e1 ldi r18, 0x10 ; 16 + 4ede: 32 e0 ldi r19, 0x02 ; 2 + 4ee0: f5 01 movw r30, r10 + 4ee2: 17 ff sbrs r17, 7 + 4ee4: 07 c0 rjmp .+14 ; 0x4ef4 + 4ee6: 60 81 ld r22, Z + 4ee8: 71 81 ldd r23, Z+1 ; 0x01 + 4eea: 82 81 ldd r24, Z+2 ; 0x02 + 4eec: 93 81 ldd r25, Z+3 ; 0x03 + 4eee: 44 e0 ldi r20, 0x04 ; 4 + 4ef0: 50 e0 ldi r21, 0x00 ; 0 + 4ef2: 06 c0 rjmp .+12 ; 0x4f00 + 4ef4: 60 81 ld r22, Z + 4ef6: 71 81 ldd r23, Z+1 ; 0x01 + 4ef8: 80 e0 ldi r24, 0x00 ; 0 + 4efa: 90 e0 ldi r25, 0x00 ; 0 + 4efc: 42 e0 ldi r20, 0x02 ; 2 + 4efe: 50 e0 ldi r21, 0x00 ; 0 + 4f00: a4 0e add r10, r20 + 4f02: b5 1e adc r11, r21 + 4f04: a2 01 movw r20, r4 + 4f06: fd d0 rcall .+506 ; 0x5102 <__ultoa_invert> + 4f08: d8 2e mov r13, r24 + 4f0a: d4 18 sub r13, r4 + 4f0c: 01 2f mov r16, r17 + 4f0e: 0f 77 andi r16, 0x7F ; 127 + 4f10: 06 ff sbrs r16, 6 + 4f12: 09 c0 rjmp .+18 ; 0x4f26 + 4f14: 0e 7f andi r16, 0xFE ; 254 + 4f16: df 14 cp r13, r15 + 4f18: 30 f4 brcc .+12 ; 0x4f26 + 4f1a: 04 ff sbrs r16, 4 + 4f1c: 06 c0 rjmp .+12 ; 0x4f2a + 4f1e: 02 fd sbrc r16, 2 + 4f20: 04 c0 rjmp .+8 ; 0x4f2a + 4f22: 0f 7e andi r16, 0xEF ; 239 + 4f24: 02 c0 rjmp .+4 ; 0x4f2a + 4f26: 1d 2d mov r17, r13 + 4f28: 01 c0 rjmp .+2 ; 0x4f2c + 4f2a: 1f 2d mov r17, r15 + 4f2c: 80 2f mov r24, r16 + 4f2e: 90 e0 ldi r25, 0x00 ; 0 + 4f30: 04 ff sbrs r16, 4 + 4f32: 0c c0 rjmp .+24 ; 0x4f4c + 4f34: fe 01 movw r30, r28 + 4f36: ed 0d add r30, r13 + 4f38: f1 1d adc r31, r1 + 4f3a: 20 81 ld r18, Z + 4f3c: 20 33 cpi r18, 0x30 ; 48 + 4f3e: 11 f4 brne .+4 ; 0x4f44 + 4f40: 09 7e andi r16, 0xE9 ; 233 + 4f42: 09 c0 rjmp .+18 ; 0x4f56 + 4f44: 02 ff sbrs r16, 2 + 4f46: 06 c0 rjmp .+12 ; 0x4f54 + 4f48: 1e 5f subi r17, 0xFE ; 254 + 4f4a: 05 c0 rjmp .+10 ; 0x4f56 + 4f4c: 86 78 andi r24, 0x86 ; 134 + 4f4e: 90 70 andi r25, 0x00 ; 0 + 4f50: 00 97 sbiw r24, 0x00 ; 0 + 4f52: 09 f0 breq .+2 ; 0x4f56 + 4f54: 1f 5f subi r17, 0xFF ; 255 + 4f56: 80 2e mov r8, r16 + 4f58: 99 24 eor r9, r9 + 4f5a: 03 fd sbrc r16, 3 + 4f5c: 11 c0 rjmp .+34 ; 0x4f80 + 4f5e: 00 ff sbrs r16, 0 + 4f60: 0c c0 rjmp .+24 ; 0x4f7a + 4f62: fd 2c mov r15, r13 + 4f64: 1e 15 cp r17, r14 + 4f66: 48 f4 brcc .+18 ; 0x4f7a + 4f68: fe 0c add r15, r14 + 4f6a: f1 1a sub r15, r17 + 4f6c: 1e 2d mov r17, r14 + 4f6e: 05 c0 rjmp .+10 ; 0x4f7a + 4f70: 80 e2 ldi r24, 0x20 ; 32 + 4f72: 90 e0 ldi r25, 0x00 ; 0 + 4f74: b3 01 movw r22, r6 + 4f76: 99 d0 rcall .+306 ; 0x50aa + 4f78: 1f 5f subi r17, 0xFF ; 255 + 4f7a: 1e 15 cp r17, r14 + 4f7c: c8 f3 brcs .-14 ; 0x4f70 + 4f7e: 04 c0 rjmp .+8 ; 0x4f88 + 4f80: 1e 15 cp r17, r14 + 4f82: 10 f4 brcc .+4 ; 0x4f88 + 4f84: e1 1a sub r14, r17 + 4f86: 01 c0 rjmp .+2 ; 0x4f8a + 4f88: ee 24 eor r14, r14 + 4f8a: 84 fe sbrs r8, 4 + 4f8c: 0e c0 rjmp .+28 ; 0x4faa + 4f8e: 80 e3 ldi r24, 0x30 ; 48 + 4f90: 90 e0 ldi r25, 0x00 ; 0 + 4f92: b3 01 movw r22, r6 + 4f94: 8a d0 rcall .+276 ; 0x50aa + 4f96: 82 fe sbrs r8, 2 + 4f98: 1d c0 rjmp .+58 ; 0x4fd4 + 4f9a: 81 fe sbrs r8, 1 + 4f9c: 03 c0 rjmp .+6 ; 0x4fa4 + 4f9e: 88 e5 ldi r24, 0x58 ; 88 + 4fa0: 90 e0 ldi r25, 0x00 ; 0 + 4fa2: 10 c0 rjmp .+32 ; 0x4fc4 + 4fa4: 88 e7 ldi r24, 0x78 ; 120 + 4fa6: 90 e0 ldi r25, 0x00 ; 0 + 4fa8: 0d c0 rjmp .+26 ; 0x4fc4 + 4faa: c4 01 movw r24, r8 + 4fac: 86 78 andi r24, 0x86 ; 134 + 4fae: 90 70 andi r25, 0x00 ; 0 + 4fb0: 00 97 sbiw r24, 0x00 ; 0 + 4fb2: 81 f0 breq .+32 ; 0x4fd4 + 4fb4: 81 fc sbrc r8, 1 + 4fb6: 02 c0 rjmp .+4 ; 0x4fbc + 4fb8: 80 e2 ldi r24, 0x20 ; 32 + 4fba: 01 c0 rjmp .+2 ; 0x4fbe + 4fbc: 8b e2 ldi r24, 0x2B ; 43 + 4fbe: 07 fd sbrc r16, 7 + 4fc0: 8d e2 ldi r24, 0x2D ; 45 + 4fc2: 90 e0 ldi r25, 0x00 ; 0 + 4fc4: b3 01 movw r22, r6 + 4fc6: 71 d0 rcall .+226 ; 0x50aa + 4fc8: 05 c0 rjmp .+10 ; 0x4fd4 + 4fca: 80 e3 ldi r24, 0x30 ; 48 + 4fcc: 90 e0 ldi r25, 0x00 ; 0 + 4fce: b3 01 movw r22, r6 + 4fd0: 6c d0 rcall .+216 ; 0x50aa + 4fd2: fa 94 dec r15 + 4fd4: df 14 cp r13, r15 + 4fd6: c8 f3 brcs .-14 ; 0x4fca + 4fd8: da 94 dec r13 + 4fda: f2 01 movw r30, r4 + 4fdc: ed 0d add r30, r13 + 4fde: f1 1d adc r31, r1 + 4fe0: 80 81 ld r24, Z + 4fe2: 90 e0 ldi r25, 0x00 ; 0 + 4fe4: b3 01 movw r22, r6 + 4fe6: 61 d0 rcall .+194 ; 0x50aa + 4fe8: dd 20 and r13, r13 + 4fea: b1 f7 brne .-20 ; 0x4fd8 + 4fec: 05 c0 rjmp .+10 ; 0x4ff8 + 4fee: 80 e2 ldi r24, 0x20 ; 32 + 4ff0: 90 e0 ldi r25, 0x00 ; 0 + 4ff2: b3 01 movw r22, r6 + 4ff4: 5a d0 rcall .+180 ; 0x50aa + 4ff6: ea 94 dec r14 + 4ff8: ee 20 and r14, r14 + 4ffa: c9 f7 brne .-14 ; 0x4fee + 4ffc: 4d ce rjmp .-870 ; 0x4c98 + 4ffe: f3 01 movw r30, r6 + 5000: 86 81 ldd r24, Z+6 ; 0x06 + 5002: 97 81 ldd r25, Z+7 ; 0x07 + 5004: 02 c0 rjmp .+4 ; 0x500a + 5006: 8f ef ldi r24, 0xFF ; 255 + 5008: 9f ef ldi r25, 0xFF ; 255 + 500a: 2d 96 adiw r28, 0x0d ; 13 + 500c: e2 e1 ldi r30, 0x12 ; 18 + 500e: 0b c1 rjmp .+534 ; 0x5226 <__epilogue_restores__> + +00005010 <__eerd_block_x32a4u>: + 5010: e0 ec ldi r30, 0xC0 ; 192 + 5012: f1 e0 ldi r31, 0x01 ; 1 + 5014: a7 85 ldd r26, Z+15 ; 0x0f + 5016: a7 fd sbrc r26, 7 + 5018: fd cf rjmp .-6 ; 0x5014 <__eerd_block_x32a4u+0x4> + 501a: a4 85 ldd r26, Z+12 ; 0x0c + 501c: a8 60 ori r26, 0x08 ; 8 + 501e: a4 87 std Z+12, r26 ; 0x0c + 5020: 60 50 subi r22, 0x00 ; 0 + 5022: 70 4f sbci r23, 0xF0 ; 240 + 5024: f0 cd rjmp .-1056 ; 0x4c06 + +00005026 <__eewr_block_x32a4u>: + 5026: dc 01 movw r26, r24 + 5028: cb 01 movw r24, r22 + 502a: 02 c0 rjmp .+4 ; 0x5030 <__eewr_block_x32a4u+0xa> + 502c: 2d 91 ld r18, X+ + 502e: 05 d0 rcall .+10 ; 0x503a <__eewr_r18_x32a4u> + 5030: 41 50 subi r20, 0x01 ; 1 + 5032: 50 40 sbci r21, 0x00 ; 0 + 5034: d8 f7 brcc .-10 ; 0x502c <__eewr_block_x32a4u+0x6> + 5036: 08 95 ret + +00005038 <__eewr_byte_x32a4u>: + 5038: 26 2f mov r18, r22 + +0000503a <__eewr_r18_x32a4u>: + 503a: e0 ec ldi r30, 0xC0 ; 192 + 503c: f1 e0 ldi r31, 0x01 ; 1 + 503e: 37 85 ldd r19, Z+15 ; 0x0f + 5040: 37 fd sbrc r19, 7 + 5042: fd cf rjmp .-6 ; 0x503e <__eewr_r18_x32a4u+0x4> + 5044: 34 85 ldd r19, Z+12 ; 0x0c + 5046: 37 7f andi r19, 0xF7 ; 247 + 5048: 34 87 std Z+12, r19 ; 0x0c + 504a: 37 85 ldd r19, Z+15 ; 0x0f + 504c: 31 ff sbrs r19, 1 + 504e: 09 c0 rjmp .+18 ; 0x5062 <__eewr_r18_x32a4u+0x28> + 5050: 36 e3 ldi r19, 0x36 ; 54 + 5052: 32 87 std Z+10, r19 ; 0x0a + 5054: 38 ed ldi r19, 0xD8 ; 216 + 5056: 34 bf out 0x34, r19 ; 52 + 5058: 31 e0 ldi r19, 0x01 ; 1 + 505a: 33 87 std Z+11, r19 ; 0x0b + 505c: 37 85 ldd r19, Z+15 ; 0x0f + 505e: 37 fd sbrc r19, 7 + 5060: fd cf rjmp .-6 ; 0x505c <__eewr_r18_x32a4u+0x22> + 5062: 33 e3 ldi r19, 0x33 ; 51 + 5064: 32 87 std Z+10, r19 ; 0x0a + 5066: 80 83 st Z, r24 + 5068: 91 83 std Z+1, r25 ; 0x01 + 506a: 12 82 std Z+2, r1 ; 0x02 + 506c: 24 83 std Z+4, r18 ; 0x04 + 506e: 25 e3 ldi r18, 0x35 ; 53 + 5070: 22 87 std Z+10, r18 ; 0x0a + 5072: 28 ed ldi r18, 0xD8 ; 216 + 5074: 31 e0 ldi r19, 0x01 ; 1 + 5076: 24 bf out 0x34, r18 ; 52 + 5078: 33 87 std Z+11, r19 ; 0x0b + 507a: 01 96 adiw r24, 0x01 ; 1 + 507c: 08 95 ret + +0000507e : + 507e: fc 01 movw r30, r24 + 5080: 05 90 lpm r0, Z+ + 5082: 61 50 subi r22, 0x01 ; 1 + 5084: 70 40 sbci r23, 0x00 ; 0 + 5086: 01 10 cpse r0, r1 + 5088: d8 f7 brcc .-10 ; 0x5080 + 508a: 80 95 com r24 + 508c: 90 95 com r25 + 508e: 8e 0f add r24, r30 + 5090: 9f 1f adc r25, r31 + 5092: 08 95 ret + +00005094 : + 5094: fc 01 movw r30, r24 + 5096: 61 50 subi r22, 0x01 ; 1 + 5098: 70 40 sbci r23, 0x00 ; 0 + 509a: 01 90 ld r0, Z+ + 509c: 01 10 cpse r0, r1 + 509e: d8 f7 brcc .-10 ; 0x5096 + 50a0: 80 95 com r24 + 50a2: 90 95 com r25 + 50a4: 8e 0f add r24, r30 + 50a6: 9f 1f adc r25, r31 + 50a8: 08 95 ret + +000050aa : + 50aa: 0f 93 push r16 + 50ac: 1f 93 push r17 + 50ae: cf 93 push r28 + 50b0: df 93 push r29 + 50b2: 8c 01 movw r16, r24 + 50b4: eb 01 movw r28, r22 + 50b6: 8b 81 ldd r24, Y+3 ; 0x03 + 50b8: 81 ff sbrs r24, 1 + 50ba: 1b c0 rjmp .+54 ; 0x50f2 + 50bc: 82 ff sbrs r24, 2 + 50be: 0d c0 rjmp .+26 ; 0x50da + 50c0: 2e 81 ldd r18, Y+6 ; 0x06 + 50c2: 3f 81 ldd r19, Y+7 ; 0x07 + 50c4: 8c 81 ldd r24, Y+4 ; 0x04 + 50c6: 9d 81 ldd r25, Y+5 ; 0x05 + 50c8: 28 17 cp r18, r24 + 50ca: 39 07 cpc r19, r25 + 50cc: 64 f4 brge .+24 ; 0x50e6 + 50ce: e8 81 ld r30, Y + 50d0: f9 81 ldd r31, Y+1 ; 0x01 + 50d2: 01 93 st Z+, r16 + 50d4: e8 83 st Y, r30 + 50d6: f9 83 std Y+1, r31 ; 0x01 + 50d8: 06 c0 rjmp .+12 ; 0x50e6 + 50da: e8 85 ldd r30, Y+8 ; 0x08 + 50dc: f9 85 ldd r31, Y+9 ; 0x09 + 50de: 80 2f mov r24, r16 + 50e0: 09 95 icall + 50e2: 00 97 sbiw r24, 0x00 ; 0 + 50e4: 31 f4 brne .+12 ; 0x50f2 + 50e6: 8e 81 ldd r24, Y+6 ; 0x06 + 50e8: 9f 81 ldd r25, Y+7 ; 0x07 + 50ea: 01 96 adiw r24, 0x01 ; 1 + 50ec: 8e 83 std Y+6, r24 ; 0x06 + 50ee: 9f 83 std Y+7, r25 ; 0x07 + 50f0: 02 c0 rjmp .+4 ; 0x50f6 + 50f2: 0f ef ldi r16, 0xFF ; 255 + 50f4: 1f ef ldi r17, 0xFF ; 255 + 50f6: c8 01 movw r24, r16 + 50f8: df 91 pop r29 + 50fa: cf 91 pop r28 + 50fc: 1f 91 pop r17 + 50fe: 0f 91 pop r16 + 5100: 08 95 ret + +00005102 <__ultoa_invert>: + 5102: fa 01 movw r30, r20 + 5104: aa 27 eor r26, r26 + 5106: 28 30 cpi r18, 0x08 ; 8 + 5108: 51 f1 breq .+84 ; 0x515e <__ultoa_invert+0x5c> + 510a: 20 31 cpi r18, 0x10 ; 16 + 510c: 81 f1 breq .+96 ; 0x516e <__ultoa_invert+0x6c> + 510e: e8 94 clt + 5110: 6f 93 push r22 + 5112: 6e 7f andi r22, 0xFE ; 254 + 5114: 6e 5f subi r22, 0xFE ; 254 + 5116: 7f 4f sbci r23, 0xFF ; 255 + 5118: 8f 4f sbci r24, 0xFF ; 255 + 511a: 9f 4f sbci r25, 0xFF ; 255 + 511c: af 4f sbci r26, 0xFF ; 255 + 511e: b1 e0 ldi r27, 0x01 ; 1 + 5120: 3e d0 rcall .+124 ; 0x519e <__ultoa_invert+0x9c> + 5122: b4 e0 ldi r27, 0x04 ; 4 + 5124: 3c d0 rcall .+120 ; 0x519e <__ultoa_invert+0x9c> + 5126: 67 0f add r22, r23 + 5128: 78 1f adc r23, r24 + 512a: 89 1f adc r24, r25 + 512c: 9a 1f adc r25, r26 + 512e: a1 1d adc r26, r1 + 5130: 68 0f add r22, r24 + 5132: 79 1f adc r23, r25 + 5134: 8a 1f adc r24, r26 + 5136: 91 1d adc r25, r1 + 5138: a1 1d adc r26, r1 + 513a: 6a 0f add r22, r26 + 513c: 71 1d adc r23, r1 + 513e: 81 1d adc r24, r1 + 5140: 91 1d adc r25, r1 + 5142: a1 1d adc r26, r1 + 5144: 20 d0 rcall .+64 ; 0x5186 <__ultoa_invert+0x84> + 5146: 09 f4 brne .+2 ; 0x514a <__ultoa_invert+0x48> + 5148: 68 94 set + 514a: 3f 91 pop r19 + 514c: 2a e0 ldi r18, 0x0A ; 10 + 514e: 26 9f mul r18, r22 + 5150: 11 24 eor r1, r1 + 5152: 30 19 sub r19, r0 + 5154: 30 5d subi r19, 0xD0 ; 208 + 5156: 31 93 st Z+, r19 + 5158: de f6 brtc .-74 ; 0x5110 <__ultoa_invert+0xe> + 515a: cf 01 movw r24, r30 + 515c: 08 95 ret + 515e: 46 2f mov r20, r22 + 5160: 47 70 andi r20, 0x07 ; 7 + 5162: 40 5d subi r20, 0xD0 ; 208 + 5164: 41 93 st Z+, r20 + 5166: b3 e0 ldi r27, 0x03 ; 3 + 5168: 0f d0 rcall .+30 ; 0x5188 <__ultoa_invert+0x86> + 516a: c9 f7 brne .-14 ; 0x515e <__ultoa_invert+0x5c> + 516c: f6 cf rjmp .-20 ; 0x515a <__ultoa_invert+0x58> + 516e: 46 2f mov r20, r22 + 5170: 4f 70 andi r20, 0x0F ; 15 + 5172: 40 5d subi r20, 0xD0 ; 208 + 5174: 4a 33 cpi r20, 0x3A ; 58 + 5176: 18 f0 brcs .+6 ; 0x517e <__ultoa_invert+0x7c> + 5178: 49 5d subi r20, 0xD9 ; 217 + 517a: 31 fd sbrc r19, 1 + 517c: 40 52 subi r20, 0x20 ; 32 + 517e: 41 93 st Z+, r20 + 5180: 02 d0 rcall .+4 ; 0x5186 <__ultoa_invert+0x84> + 5182: a9 f7 brne .-22 ; 0x516e <__ultoa_invert+0x6c> + 5184: ea cf rjmp .-44 ; 0x515a <__ultoa_invert+0x58> + 5186: b4 e0 ldi r27, 0x04 ; 4 + 5188: a6 95 lsr r26 + 518a: 97 95 ror r25 + 518c: 87 95 ror r24 + 518e: 77 95 ror r23 + 5190: 67 95 ror r22 + 5192: ba 95 dec r27 + 5194: c9 f7 brne .-14 ; 0x5188 <__ultoa_invert+0x86> + 5196: 00 97 sbiw r24, 0x00 ; 0 + 5198: 61 05 cpc r22, r1 + 519a: 71 05 cpc r23, r1 + 519c: 08 95 ret + 519e: 9b 01 movw r18, r22 + 51a0: ac 01 movw r20, r24 + 51a2: 0a 2e mov r0, r26 + 51a4: 06 94 lsr r0 + 51a6: 57 95 ror r21 + 51a8: 47 95 ror r20 + 51aa: 37 95 ror r19 + 51ac: 27 95 ror r18 + 51ae: ba 95 dec r27 + 51b0: c9 f7 brne .-14 ; 0x51a4 <__ultoa_invert+0xa2> + 51b2: 62 0f add r22, r18 + 51b4: 73 1f adc r23, r19 + 51b6: 84 1f adc r24, r20 + 51b8: 95 1f adc r25, r21 + 51ba: a0 1d adc r26, r0 + 51bc: 08 95 ret + +000051be <__divmodsi4>: + 51be: 97 fb bst r25, 7 + 51c0: 09 2e mov r0, r25 + 51c2: 05 26 eor r0, r21 + 51c4: 0e d0 rcall .+28 ; 0x51e2 <__divmodsi4_neg1> + 51c6: 57 fd sbrc r21, 7 + 51c8: 04 d0 rcall .+8 ; 0x51d2 <__divmodsi4_neg2> + 51ca: 45 d0 rcall .+138 ; 0x5256 <__udivmodsi4> + 51cc: 0a d0 rcall .+20 ; 0x51e2 <__divmodsi4_neg1> + 51ce: 00 1c adc r0, r0 + 51d0: 38 f4 brcc .+14 ; 0x51e0 <__divmodsi4_exit> + +000051d2 <__divmodsi4_neg2>: + 51d2: 50 95 com r21 + 51d4: 40 95 com r20 + 51d6: 30 95 com r19 + 51d8: 21 95 neg r18 + 51da: 3f 4f sbci r19, 0xFF ; 255 + 51dc: 4f 4f sbci r20, 0xFF ; 255 + 51de: 5f 4f sbci r21, 0xFF ; 255 + +000051e0 <__divmodsi4_exit>: + 51e0: 08 95 ret + +000051e2 <__divmodsi4_neg1>: + 51e2: f6 f7 brtc .-4 ; 0x51e0 <__divmodsi4_exit> + 51e4: 90 95 com r25 + 51e6: 80 95 com r24 + 51e8: 70 95 com r23 + 51ea: 61 95 neg r22 + 51ec: 7f 4f sbci r23, 0xFF ; 255 + 51ee: 8f 4f sbci r24, 0xFF ; 255 + 51f0: 9f 4f sbci r25, 0xFF ; 255 + 51f2: 08 95 ret + +000051f4 <__prologue_saves__>: + 51f4: 2f 92 push r2 + 51f6: 3f 92 push r3 + 51f8: 4f 92 push r4 + 51fa: 5f 92 push r5 + 51fc: 6f 92 push r6 + 51fe: 7f 92 push r7 + 5200: 8f 92 push r8 + 5202: 9f 92 push r9 + 5204: af 92 push r10 + 5206: bf 92 push r11 + 5208: cf 92 push r12 + 520a: df 92 push r13 + 520c: ef 92 push r14 + 520e: ff 92 push r15 + 5210: 0f 93 push r16 + 5212: 1f 93 push r17 + 5214: cf 93 push r28 + 5216: df 93 push r29 + 5218: cd b7 in r28, 0x3d ; 61 + 521a: de b7 in r29, 0x3e ; 62 + 521c: ca 1b sub r28, r26 + 521e: db 0b sbc r29, r27 + 5220: cd bf out 0x3d, r28 ; 61 + 5222: de bf out 0x3e, r29 ; 62 + 5224: 09 94 ijmp + +00005226 <__epilogue_restores__>: + 5226: 2a 88 ldd r2, Y+18 ; 0x12 + 5228: 39 88 ldd r3, Y+17 ; 0x11 + 522a: 48 88 ldd r4, Y+16 ; 0x10 + 522c: 5f 84 ldd r5, Y+15 ; 0x0f + 522e: 6e 84 ldd r6, Y+14 ; 0x0e + 5230: 7d 84 ldd r7, Y+13 ; 0x0d + 5232: 8c 84 ldd r8, Y+12 ; 0x0c + 5234: 9b 84 ldd r9, Y+11 ; 0x0b + 5236: aa 84 ldd r10, Y+10 ; 0x0a + 5238: b9 84 ldd r11, Y+9 ; 0x09 + 523a: c8 84 ldd r12, Y+8 ; 0x08 + 523c: df 80 ldd r13, Y+7 ; 0x07 + 523e: ee 80 ldd r14, Y+6 ; 0x06 + 5240: fd 80 ldd r15, Y+5 ; 0x05 + 5242: 0c 81 ldd r16, Y+4 ; 0x04 + 5244: 1b 81 ldd r17, Y+3 ; 0x03 + 5246: aa 81 ldd r26, Y+2 ; 0x02 + 5248: b9 81 ldd r27, Y+1 ; 0x01 + 524a: ce 0f add r28, r30 + 524c: d1 1d adc r29, r1 + 524e: cd bf out 0x3d, r28 ; 61 + 5250: de bf out 0x3e, r29 ; 62 + 5252: ed 01 movw r28, r26 + 5254: 08 95 ret + +00005256 <__udivmodsi4>: + 5256: a1 e2 ldi r26, 0x21 ; 33 + 5258: 1a 2e mov r1, r26 + 525a: aa 1b sub r26, r26 + 525c: bb 1b sub r27, r27 + 525e: fd 01 movw r30, r26 + 5260: 0d c0 rjmp .+26 ; 0x527c <__udivmodsi4_ep> + +00005262 <__udivmodsi4_loop>: + 5262: aa 1f adc r26, r26 + 5264: bb 1f adc r27, r27 + 5266: ee 1f adc r30, r30 + 5268: ff 1f adc r31, r31 + 526a: a2 17 cp r26, r18 + 526c: b3 07 cpc r27, r19 + 526e: e4 07 cpc r30, r20 + 5270: f5 07 cpc r31, r21 + 5272: 20 f0 brcs .+8 ; 0x527c <__udivmodsi4_ep> + 5274: a2 1b sub r26, r18 + 5276: b3 0b sbc r27, r19 + 5278: e4 0b sbc r30, r20 + 527a: f5 0b sbc r31, r21 + +0000527c <__udivmodsi4_ep>: + 527c: 66 1f adc r22, r22 + 527e: 77 1f adc r23, r23 + 5280: 88 1f adc r24, r24 + 5282: 99 1f adc r25, r25 + 5284: 1a 94 dec r1 + 5286: 69 f7 brne .-38 ; 0x5262 <__udivmodsi4_loop> + 5288: 60 95 com r22 + 528a: 70 95 com r23 + 528c: 80 95 com r24 + 528e: 90 95 com r25 + 5290: 9b 01 movw r18, r22 + 5292: ac 01 movw r20, r24 + 5294: bd 01 movw r22, r26 + 5296: cf 01 movw r24, r30 + 5298: 08 95 ret + +0000529a <_exit>: + 529a: f8 94 cli + +0000529c <__stop_program>: + 529c: ff cf rjmp .-2 ; 0x529c <__stop_program> diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.map b/Firmware/Chameleon-Mini/Chameleon-Mini.map new file mode 100644 index 00000000..826547a1 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.map @@ -0,0 +1,2807 @@ +Archive member included because of file (symbol) + +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + Bin/Commands.o (__mulsi3) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o (exit) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + Bin/Chameleon-Mini.o (__do_copy_data) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + Bin/Chameleon-Mini.o (__do_clear_bss) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/Random.o (rand) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + Bin/Configuration.o (memcpy_P) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + Bin/Button.o (strcmp_P) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + Bin/Button.o (strncpy_P) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + Bin/HIDClassDevice.o (memcmp) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + Bin/HIDClassDevice.o (memcpy) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + Bin/HIDClassDevice.o (memset) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + Bin/Commands.o (snprintf_P) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (vfprintf) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/Settings.o (__eerd_block_x32a4u) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o (__eerd_byte_x32a4u) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o (__eeupd_byte_x32a4u) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + Bin/Settings.o (__eewr_block_x32a4u) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) (__eewr_r18_x32a4u) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (strnlen_P) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (strnlen) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (fputc) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) (__ultoa_invert) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) (__divmodsi4) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (__prologue_saves__) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) (__epilogue_restores__) +c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) (__udivmodsi4) + +Allocating common symbols +Common symbol size file + +USB_IsInitialized 0x1 Bin/USBTask.o +USB_EndpointTable 0x63 Bin/USBController_XMEGA.o +TerminalBuffer 0x100 Bin/Terminal.o +USB_Endpoint_SelectedFIFO + 0x2 Bin/Endpoint_XMEGA.o +ActiveConfiguration + 0x25 Bin/Configuration.o +USB_DeviceState 0x1 Bin/USBTask.o +USB_Device_ConfigurationNumber + 0x1 Bin/DeviceStandardReq.o +USB_Endpoint_SelectedHandle + 0x2 Bin/Endpoint_XMEGA.o +USB_Device_CurrentlySelfPowered + 0x1 Bin/DeviceStandardReq.o +CodecBuffer 0x100 Bin/Codec.o +GlobalSettings 0x13 Bin/Settings.o +USB_Endpoint_SelectedEndpoint + 0x1 Bin/Endpoint_XMEGA.o +USB_ControlRequest 0x8 Bin/USBTask.o +USB_Endpoint_FIFOs 0x318 Bin/Endpoint_XMEGA.o +USB_Device_RemoteWakeupEnabled + 0x1 Bin/DeviceStandardReq.o + +Discarded input sections + + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .text 0x00000000 0x0 Bin/Chameleon-Mini.o + .bss 0x00000000 0x0 Bin/Chameleon-Mini.o + .text 0x00000000 0x0 Bin/LUFADescriptors.o + .bss 0x00000000 0x0 Bin/LUFADescriptors.o + .text 0x00000000 0x0 Bin/System.o + .bss 0x00000000 0x0 Bin/System.o + .text 0x00000000 0x0 Bin/Configuration.o + .bss 0x00000000 0x0 Bin/Configuration.o + .text 0x00000000 0x0 Bin/Random.o + .bss 0x00000000 0x0 Bin/Random.o + .text 0x00000000 0x0 Bin/Common.o + .bss 0x00000000 0x0 Bin/Common.o + .text 0x00000000 0x0 Bin/Memory.o + .bss 0x00000000 0x0 Bin/Memory.o + .text 0x00000000 0x0 Bin/Button.o + .text 0x00000000 0x0 Bin/Settings.o + .bss 0x00000000 0x0 Bin/Settings.o + .text 0x00000000 0x0 Bin/LED.o + .text 0x00000000 0x0 Bin/Terminal.o + .text 0x00000000 0x0 Bin/Commands.o + .bss 0x00000000 0x0 Bin/Commands.o + .text 0x00000000 0x0 Bin/XModem.o + .text 0x00000000 0x0 Bin/CommandLine.o + .text.CommandLineInit + 0x00000000 0xa Bin/CommandLine.o + .text 0x00000000 0x0 Bin/Codec.o + .bss 0x00000000 0x0 Bin/Codec.o + .text 0x00000000 0x0 Bin/ISO14443-2A.o + .text 0x00000000 0x0 Bin/MifareClassic.o + .text 0x00000000 0x0 Bin/ISO14443-3A.o + .bss 0x00000000 0x0 Bin/ISO14443-3A.o + .text 0x00000000 0x0 Bin/Crypto1.o + .text 0x00000000 0x0 Bin/HIDParser.o + .bss 0x00000000 0x0 Bin/HIDParser.o + .text.USB_ProcessHIDReport + 0x00000000 0x8b6 Bin/HIDParser.o + .progmem.gcc_sw_table + 0x00000000 0x17a Bin/HIDParser.o + .text.USB_GetHIDReportItemInfo + 0x00000000 0xe8 Bin/HIDParser.o + .text.USB_SetHIDReportItemInfo + 0x00000000 0xe4 Bin/HIDParser.o + .text.USB_GetHIDReportSize + 0x00000000 0x14a Bin/HIDParser.o + .text 0x00000000 0x0 Bin/ConfigDescriptors.o + .bss 0x00000000 0x0 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfType + 0x00000000 0x50 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfTypeBefore + 0x00000000 0x60 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorOfTypeAfter + 0x00000000 0x34 Bin/ConfigDescriptors.o + .text.USB_GetNextDescriptorComp + 0x00000000 0x8e Bin/ConfigDescriptors.o + .text 0x00000000 0x0 Bin/DeviceStandardReq.o + .bss 0x00000000 0x0 Bin/DeviceStandardReq.o + .text 0x00000000 0x0 Bin/Events.o + .bss 0x00000000 0x0 Bin/Events.o + .text 0x00000000 0x0 Bin/HostStandardReq.o + .bss 0x00000000 0x0 Bin/HostStandardReq.o + .text 0x00000000 0x0 Bin/USBTask.o + .bss 0x00000000 0x0 Bin/USBTask.o + .text 0x00000000 0x0 Bin/Device_XMEGA.o + .bss 0x00000000 0x0 Bin/Device_XMEGA.o + .text.USB_Device_SendRemoteWakeup + 0x00000000 0xc Bin/Device_XMEGA.o + .text 0x00000000 0x0 Bin/EndpointStream_XMEGA.o + .bss 0x00000000 0x0 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Discard_Stream + 0x00000000 0xd2 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Null_Stream + 0x00000000 0xca Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Stream_BE + 0x00000000 0xfe Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Stream_LE + 0x00000000 0xe8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Stream_BE + 0x00000000 0xfe Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_PStream_LE + 0x00000000 0xf2 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_PStream_BE + 0x00000000 0xfe Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_EStream_LE + 0x00000000 0xf8 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_EStream_BE + 0x00000000 0x104 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_EStream_LE + 0x00000000 0x104 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_EStream_BE + 0x00000000 0x110 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_Stream_BE + 0x00000000 0x17a Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_Stream_LE + 0x00000000 0xfe Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_Stream_BE + 0x00000000 0xe4 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_PStream_BE + 0x00000000 0x17a Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_EStream_LE + 0x00000000 0x178 Bin/EndpointStream_XMEGA.o + .text.Endpoint_Write_Control_EStream_BE + 0x00000000 0x17c Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_EStream_LE + 0x00000000 0xfc Bin/EndpointStream_XMEGA.o + .text.Endpoint_Read_Control_EStream_BE + 0x00000000 0xe8 Bin/EndpointStream_XMEGA.o + .text 0x00000000 0x0 Bin/Endpoint_XMEGA.o + .bss 0x00000000 0x0 Bin/Endpoint_XMEGA.o + .text 0x00000000 0x0 Bin/Host_XMEGA.o + .bss 0x00000000 0x0 Bin/Host_XMEGA.o + .text 0x00000000 0x0 Bin/PipeStream_XMEGA.o + .bss 0x00000000 0x0 Bin/PipeStream_XMEGA.o + .text 0x00000000 0x0 Bin/Pipe_XMEGA.o + .bss 0x00000000 0x0 Bin/Pipe_XMEGA.o + .text 0x00000000 0x0 Bin/USBController_XMEGA.o + .bss 0x00000000 0x0 Bin/USBController_XMEGA.o + .text 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o + .bss 0x00000000 0x0 Bin/USBInterrupt_XMEGA.o + .text 0x00000000 0x0 Bin/AudioClassDevice.o + .bss 0x00000000 0x0 Bin/AudioClassDevice.o + .text.Audio_Device_ProcessControlRequest + 0x00000000 0x2ca Bin/AudioClassDevice.o + .text.Audio_Device_ConfigureEndpoints + 0x00000000 0x34 Bin/AudioClassDevice.o + .text.Audio_Device_Event_Stub + 0x00000000 0x2 Bin/AudioClassDevice.o + .text 0x00000000 0x0 Bin/CDCClassDevice.o + .bss 0x00000000 0x0 Bin/CDCClassDevice.o + .text.CDC_Device_putchar + 0x00000000 0x1e Bin/CDCClassDevice.o + .text.CDC_Device_BytesReceived + 0x00000000 0xa6 Bin/CDCClassDevice.o + .text.CDC_Device_getchar_Blocking + 0x00000000 0x38 Bin/CDCClassDevice.o + .text.CDC_Device_getchar + 0x00000000 0x14 Bin/CDCClassDevice.o + .text.CDC_Device_SendControlLineStateChange + 0x00000000 0x7c Bin/CDCClassDevice.o + .text.CDC_Device_CreateStream + 0x00000000 0x26 Bin/CDCClassDevice.o + .text.CDC_Device_CreateBlockingStream + 0x00000000 0x26 Bin/CDCClassDevice.o + .text 0x00000000 0x0 Bin/HIDClassDevice.o + .bss 0x00000000 0x0 Bin/HIDClassDevice.o + .text.HID_Device_ProcessControlRequest + 0x00000000 0x24e Bin/HIDClassDevice.o + .text.HID_Device_ConfigureEndpoints + 0x00000000 0x34 Bin/HIDClassDevice.o + .text.HID_Device_USBTask + 0x00000000 0x1be Bin/HIDClassDevice.o + .text 0x00000000 0x0 Bin/MassStorageClassDevice.o + .bss 0x00000000 0x0 Bin/MassStorageClassDevice.o + .text.MS_Device_ProcessControlRequest + 0x00000000 0x6e Bin/MassStorageClassDevice.o + .text.MS_Device_ConfigureEndpoints + 0x00000000 0x40 Bin/MassStorageClassDevice.o + .text.MS_Device_USBTask + 0x00000000 0x2e4 Bin/MassStorageClassDevice.o + .text 0x00000000 0x0 Bin/MIDIClassDevice.o + .bss 0x00000000 0x0 Bin/MIDIClassDevice.o + .text.MIDI_Device_ConfigureEndpoints + 0x00000000 0x34 Bin/MIDIClassDevice.o + .text.MIDI_Device_SendEventPacket + 0x00000000 0x66 Bin/MIDIClassDevice.o + .text.MIDI_Device_Flush + 0x00000000 0x5e Bin/MIDIClassDevice.o + .text.MIDI_Device_USBTask + 0x00000000 0x2a Bin/MIDIClassDevice.o + .text.MIDI_Device_ReceiveEventPacket + 0x00000000 0x80 Bin/MIDIClassDevice.o + .text 0x00000000 0x0 Bin/PrinterClassDevice.o + .bss 0x00000000 0x0 Bin/PrinterClassDevice.o + .text.PRNT_Device_ProcessControlRequest + 0x00000000 0xea Bin/PrinterClassDevice.o + .text.PRNT_Device_ConfigureEndpoints + 0x00000000 0x3a Bin/PrinterClassDevice.o + .text.PRNT_Device_SendString + 0x00000000 0x4e Bin/PrinterClassDevice.o + .text.PRNT_Device_SendData + 0x00000000 0x48 Bin/PrinterClassDevice.o + .text.PRNT_Device_SendByte + 0x00000000 0x5c Bin/PrinterClassDevice.o + .text.PRNT_Device_putchar + 0x00000000 0x1e Bin/PrinterClassDevice.o + .text.PRNT_Device_Flush + 0x00000000 0x88 Bin/PrinterClassDevice.o + .text.PRNT_Device_USBTask + 0x00000000 0x106 Bin/PrinterClassDevice.o + .text.PRNT_Device_BytesReceived + 0x00000000 0x90 Bin/PrinterClassDevice.o + .text.PRNT_Device_ReceiveByte + 0x00000000 0xc0 Bin/PrinterClassDevice.o + .text.PRNT_Device_getchar_Blocking + 0x00000000 0x38 Bin/PrinterClassDevice.o + .text.PRNT_Device_getchar + 0x00000000 0x14 Bin/PrinterClassDevice.o + .text.PRNT_Device_CreateStream + 0x00000000 0x26 Bin/PrinterClassDevice.o + .text.PRNT_Device_CreateBlockingStream + 0x00000000 0x26 Bin/PrinterClassDevice.o + .text.PRNT_Device_Event_Stub + 0x00000000 0x2 Bin/PrinterClassDevice.o + .text 0x00000000 0x0 Bin/RNDISClassDevice.o + .bss 0x00000000 0x0 Bin/RNDISClassDevice.o + .text.RNDIS_Device_ProcessControlRequest + 0x00000000 0x5cc Bin/RNDISClassDevice.o + .text.RNDIS_Device_ConfigureEndpoints + 0x00000000 0x52 Bin/RNDISClassDevice.o + .text.RNDIS_Device_USBTask + 0x00000000 0x74 Bin/RNDISClassDevice.o + .text.RNDIS_Device_IsPacketReceived + 0x00000000 0x2a Bin/RNDISClassDevice.o + .text.RNDIS_Device_ReadPacket + 0x00000000 0xa8 Bin/RNDISClassDevice.o + .text.RNDIS_Device_SendPacket + 0x00000000 0xca Bin/RNDISClassDevice.o + .progmem.data 0x00000000 0x6c Bin/RNDISClassDevice.o + .text 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o + .bss 0x00000000 0x0 Bin/AndroidAccessoryClassHost.o + .text 0x00000000 0x0 Bin/AudioClassHost.o + .bss 0x00000000 0x0 Bin/AudioClassHost.o + .text 0x00000000 0x0 Bin/CDCClassHost.o + .bss 0x00000000 0x0 Bin/CDCClassHost.o + .text 0x00000000 0x0 Bin/HIDClassHost.o + .bss 0x00000000 0x0 Bin/HIDClassHost.o + .text 0x00000000 0x0 Bin/MassStorageClassHost.o + .bss 0x00000000 0x0 Bin/MassStorageClassHost.o + .text 0x00000000 0x0 Bin/MIDIClassHost.o + .bss 0x00000000 0x0 Bin/MIDIClassHost.o + .text 0x00000000 0x0 Bin/PrinterClassHost.o + .bss 0x00000000 0x0 Bin/PrinterClassHost.o + .text 0x00000000 0x0 Bin/RNDISClassHost.o + .bss 0x00000000 0x0 Bin/RNDISClassHost.o + .text 0x00000000 0x0 Bin/StillImageClassHost.o + .bss 0x00000000 0x0 Bin/StillImageClassHost.o + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .text.libgcc 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .text.libgcc 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .text.libgcc 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .text.avr-libc + 0x00000000 0x1a c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .text.avr-libc + 0x00000000 0xe c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .text.avr-libc + 0x00000000 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .text.avr-libc + 0x00000000 0x16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .text 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + .bss 0x00000000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + +Memory Configuration + +Name Origin Length Attributes +text 0x00000000 0x00100000 xr +data 0x00802000 0x0000ffa0 rw !x +eeprom 0x00810000 0x00010000 rw !x +fuse 0x00820000 0x00000400 rw !x +lock 0x00830000 0x00000400 rw !x +signature 0x00840000 0x00000400 rw !x +*default* 0x00000000 0xffffffff + +Linker script and memory map + +LOAD c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +LOAD Bin/Chameleon-Mini.o +LOAD Bin/LUFADescriptors.o +LOAD Bin/System.o +LOAD Bin/Configuration.o +LOAD Bin/Random.o +LOAD Bin/Common.o +LOAD Bin/Memory.o +LOAD Bin/Button.o +LOAD Bin/Settings.o +LOAD Bin/LED.o +LOAD Bin/Terminal.o +LOAD Bin/Commands.o +LOAD Bin/XModem.o +LOAD Bin/CommandLine.o +LOAD Bin/Codec.o +LOAD Bin/ISO14443-2A.o +LOAD Bin/MifareClassic.o +LOAD Bin/ISO14443-3A.o +LOAD Bin/Crypto1.o +LOAD Bin/HIDParser.o +LOAD Bin/ConfigDescriptors.o +LOAD Bin/DeviceStandardReq.o +LOAD Bin/Events.o +LOAD Bin/HostStandardReq.o +LOAD Bin/USBTask.o +LOAD Bin/Device_XMEGA.o +LOAD Bin/EndpointStream_XMEGA.o +LOAD Bin/Endpoint_XMEGA.o +LOAD Bin/Host_XMEGA.o +LOAD Bin/PipeStream_XMEGA.o +LOAD Bin/Pipe_XMEGA.o +LOAD Bin/USBController_XMEGA.o +LOAD Bin/USBInterrupt_XMEGA.o +LOAD Bin/AudioClassDevice.o +LOAD Bin/CDCClassDevice.o +LOAD Bin/HIDClassDevice.o +LOAD Bin/MassStorageClassDevice.o +LOAD Bin/MIDIClassDevice.o +LOAD Bin/PrinterClassDevice.o +LOAD Bin/RNDISClassDevice.o +LOAD Bin/AndroidAccessoryClassHost.o +LOAD Bin/AudioClassHost.o +LOAD Bin/CDCClassHost.o +LOAD Bin/HIDClassHost.o +LOAD Bin/MassStorageClassHost.o +LOAD Bin/MIDIClassHost.o +LOAD Bin/PrinterClassHost.o +LOAD Bin/RNDISClassHost.o +LOAD Bin/StillImageClassHost.o +LOAD c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libm.a +LOAD c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a +LOAD c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a +LOAD c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a + +.hash + *(.hash) + +.dynsym + *(.dynsym) + +.dynstr + *(.dynstr) + +.gnu.version + *(.gnu.version) + +.gnu.version_d + *(.gnu.version_d) + +.gnu.version_r + *(.gnu.version_r) + +.rel.init + *(.rel.init) + +.rela.init + *(.rela.init) + +.rel.text + *(.rel.text) + *(.rel.text.*) + *(.rel.gnu.linkonce.t*) + +.rela.text + *(.rela.text) + *(.rela.text.*) + *(.rela.gnu.linkonce.t*) + +.rel.fini + *(.rel.fini) + +.rela.fini + *(.rela.fini) + +.rel.rodata + *(.rel.rodata) + *(.rel.rodata.*) + *(.rel.gnu.linkonce.r*) + +.rela.rodata + *(.rela.rodata) + *(.rela.rodata.*) + *(.rela.gnu.linkonce.r*) + +.rel.data + *(.rel.data) + *(.rel.data.*) + *(.rel.gnu.linkonce.d*) + +.rela.data + *(.rela.data) + *(.rela.data.*) + *(.rela.gnu.linkonce.d*) + +.rel.ctors + *(.rel.ctors) + +.rela.ctors + *(.rela.ctors) + +.rel.dtors + *(.rel.dtors) + +.rela.dtors + *(.rela.dtors) + +.rel.got + *(.rel.got) + +.rela.got + *(.rela.got) + +.rel.bss + *(.rel.bss) + +.rela.bss + *(.rela.bss) + +.rel.plt + *(.rel.plt) + +.rela.plt + *(.rela.plt) + +.text 0x00000000 0x529e + *(.vectors) + .vectors 0x00000000 0x1fc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x00000000 __vectors + *(.vectors) + *(.progmem.gcc*) + *(.progmem*) + .progmem.data 0x000001fc 0x8c Bin/LUFADescriptors.o + 0x000001fc ProductString + 0x0000021a ManufacturerString + 0x00000234 LanguageString + 0x00000238 ConfigurationDescriptor + 0x00000276 DeviceDescriptor + .progmem.data 0x00000288 0x6f Bin/Configuration.o + .progmem.data 0x000002f7 0xc0 Bin/Button.o + .progmem.data 0x000003b7 0x64 Bin/Commands.o + .progmem.data 0x0000041b 0x22c Bin/CommandLine.o + 0x0000041b CommandTable + 0x00000648 . = ALIGN (0x2) + *fill* 0x00000647 0x1 00 + 0x00000648 __trampolines_start = . + *(.trampolines) + .trampolines 0x00000648 0x0 linker stubs + *(.trampolines*) + 0x00000648 __trampolines_end = . + *(.jumptables) + *(.jumptables*) + *(.lowtext) + *(.lowtext*) + 0x00000648 __ctors_start = . + *(.ctors) + 0x00000648 __ctors_end = . + 0x00000648 __dtors_start = . + *(.dtors) + 0x00000648 __dtors_end = . + SORT(*)(.ctors) + SORT(*)(.dtors) + *(.init0) + .init0 0x00000648 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x00000648 __init + *(.init0) + *(.init1) + *(.init1) + *(.init2) + .init2 0x00000648 0xc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + *(.init2) + *(.init3) + *(.init3) + *(.init4) + .init4 0x00000654 0x16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + 0x00000654 __do_copy_data + .init4 0x0000066a 0x10 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + 0x0000066a __do_clear_bss + *(.init4) + *(.init5) + *(.init5) + *(.init6) + *(.init6) + *(.init7) + *(.init7) + *(.init8) + *(.init8) + *(.init9) + .init9 0x0000067a 0x6 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + *(.init9) + *(.text) + .text 0x00000680 0x2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + 0x00000680 __vector_38 + 0x00000680 __vector_104 + 0x00000680 __vector_63 + 0x00000680 __vector_28 + 0x00000680 __vector_67 + 0x00000680 __vector_1 + 0x00000680 __vector_119 + 0x00000680 __vector_32 + 0x00000680 __vector_75 + 0x00000680 __vector_71 + 0x00000680 __vector_91 + 0x00000680 __vector_62 + 0x00000680 __vector_77 + 0x00000680 __vector_102 + 0x00000680 __vector_24 + 0x00000680 __vector_12 + 0x00000680 __vector_55 + 0x00000680 __vector_69 + 0x00000680 __vector_81 + 0x00000680 __vector_90 + 0x00000680 __vector_46 + 0x00000680 __bad_interrupt + 0x00000680 __vector_122 + 0x00000680 __vector_72 + 0x00000680 __vector_114 + 0x00000680 __vector_6 + 0x00000680 __vector_110 + 0x00000680 __vector_31 + 0x00000680 __vector_92 + 0x00000680 __vector_35 + 0x00000680 __vector_78 + 0x00000680 __vector_74 + 0x00000680 __vector_117 + 0x00000680 __vector_39 + 0x00000680 __vector_107 + 0x00000680 __vector_3 + 0x00000680 __vector_105 + 0x00000680 __vector_98 + 0x00000680 __vector_23 + 0x00000680 __vector_68 + 0x00000680 __vector_30 + 0x00000680 __vector_73 + 0x00000680 __vector_45 + 0x00000680 __vector_25 + 0x00000680 __vector_93 + 0x00000680 __vector_61 + 0x00000680 __vector_11 + 0x00000680 __vector_54 + 0x00000680 __vector_99 + 0x00000680 __vector_13 + 0x00000680 __vector_17 + 0x00000680 __vector_19 + 0x00000680 __vector_56 + 0x00000680 __vector_7 + 0x00000680 __vector_49 + 0x00000680 __vector_123 + 0x00000680 __vector_41 + 0x00000680 __vector_86 + 0x00000680 __vector_100 + 0x00000680 __vector_101 + 0x00000680 __vector_64 + 0x00000680 __vector_88 + 0x00000680 __vector_109 + 0x00000680 __vector_43 + 0x00000680 __vector_27 + 0x00000680 __vector_5 + 0x00000680 __vector_113 + 0x00000680 __vector_33 + 0x00000680 __vector_76 + 0x00000680 __vector_115 + 0x00000680 __vector_47 + 0x00000680 __vector_52 + 0x00000680 __vector_37 + 0x00000680 __vector_95 + 0x00000680 __vector_103 + 0x00000680 __vector_96 + 0x00000680 __vector_89 + 0x00000680 __vector_108 + 0x00000680 __vector_4 + 0x00000680 __vector_44 + 0x00000680 __vector_82 + 0x00000680 __vector_106 + 0x00000680 __vector_118 + 0x00000680 __vector_51 + 0x00000680 __vector_9 + 0x00000680 __vector_2 + 0x00000680 __vector_21 + 0x00000680 __vector_15 + 0x00000680 __vector_66 + 0x00000680 __vector_36 + 0x00000680 __vector_79 + 0x00000680 __vector_58 + 0x00000680 __vector_70 + 0x00000680 __vector_29 + 0x00000680 __vector_60 + 0x00000680 __vector_121 + 0x00000680 __vector_40 + 0x00000680 __vector_85 + 0x00000680 __vector_94 + 0x00000680 __vector_126 + 0x00000680 __vector_8 + 0x00000680 __vector_26 + 0x00000680 __vector_48 + 0x00000680 __vector_124 + 0x00000680 __vector_116 + 0x00000680 __vector_112 + 0x00000680 __vector_111 + 0x00000680 __vector_80 + 0x00000680 __vector_14 + 0x00000680 __vector_84 + 0x00000680 __vector_57 + 0x00000680 __vector_53 + 0x00000680 __vector_10 + 0x00000680 __vector_50 + 0x00000680 __vector_16 + 0x00000680 __vector_59 + 0x00000680 __vector_18 + 0x00000680 __vector_97 + 0x00000680 __vector_20 + 0x00000680 __vector_42 + 0x00000680 __vector_87 + 0x00000680 __vector_65 + 0x00000680 __vector_120 + 0x00000682 . = ALIGN (0x2) + *(.text.*) + .text.startup.main + 0x00000682 0x72 Bin/Chameleon-Mini.o + 0x00000682 main + .text.CALLBACK_USB_GetDescriptor + 0x000006f4 0x6c Bin/LUFADescriptors.o + 0x000006f4 CALLBACK_USB_GetDescriptor + .text.__vector_default + 0x00000760 0xc Bin/System.o + 0x00000760 __vector_default + .text.SystemInit + 0x0000076c 0x74 Bin/System.o + 0x0000076c SystemInit + .text.SystemReset + 0x000007e0 0xe Bin/System.o + 0x000007e0 SystemReset + .text.SystemEnterBootloader + 0x000007ee 0xc Bin/System.o + 0x000007ee SystemEnterBootloader + .text.SystemStartUSBClock + 0x000007fa 0x36 Bin/System.o + 0x000007fa SystemStartUSBClock + .text.SystemStopUSBClock + 0x00000830 0x1c Bin/System.o + 0x00000830 SystemStopUSBClock + .text.SystemInterruptInit + 0x0000084c 0xc Bin/System.o + 0x0000084c SystemInterruptInit + .text.CodecInitDummy + 0x00000858 0x2 Bin/Configuration.o + .text.CodecTaskDummy + 0x0000085a 0x2 Bin/Configuration.o + .text.ApplicationInitDummy + 0x0000085c 0x2 Bin/Configuration.o + .text.ApplicationResetDummy + 0x0000085e 0x2 Bin/Configuration.o + .text.ApplicationTaskDummy + 0x00000860 0x2 Bin/Configuration.o + .text.ApplicationProcessDummy + 0x00000862 0x6 Bin/Configuration.o + .text.ApplicationGetUidDummy + 0x00000868 0x2 Bin/Configuration.o + .text.ApplicationSetUidDummy + 0x0000086a 0x2 Bin/Configuration.o + .text.ConfigurationSetById + 0x0000086c 0x52 Bin/Configuration.o + 0x0000086c ConfigurationSetById + .text.ConfigurationInit + 0x000008be 0xc Bin/Configuration.o + 0x000008be ConfigurationInit + .text.ConfigurationSetByName + 0x000008ca 0x90 Bin/Configuration.o + 0x000008ca ConfigurationSetByName + .text.ConfigurationGetList + 0x0000095a 0x74 Bin/Configuration.o + 0x0000095a ConfigurationGetList + .text.RandomInit + 0x000009ce 0x2 Bin/Random.o + 0x000009ce RandomInit + .text.RandomGetByte + 0x000009d0 0x6 Bin/Random.o + 0x000009d0 RandomGetByte + .text.RandomGetBuffer + 0x000009d6 0x2e Bin/Random.o + 0x000009d6 RandomGetBuffer + .text.RandomTick + 0x00000a04 0x10 Bin/Random.o + 0x00000a04 RandomTick + .text.BufferToHexString + 0x00000a14 0x7a Bin/Common.o + 0x00000a14 BufferToHexString + .text.HexStringToBuffer + 0x00000a8e 0x9e Bin/Common.o + 0x00000a8e HexStringToBuffer + .text.MemoryInit + 0x00000b2c 0x10e Bin/Memory.o + 0x00000b2c MemoryInit + .text.MemoryReadBlock + 0x00000c3a 0x116 Bin/Memory.o + 0x00000c3a MemoryReadBlock + .text.MemoryWriteBlock + 0x00000d50 0x2a8 Bin/Memory.o + 0x00000d50 MemoryWriteBlock + .text.MemoryClear + 0x00000ff8 0xcc Bin/Memory.o + 0x00000ff8 MemoryClear + .text.MemoryUploadBlock + 0x000010c4 0x5c Bin/Memory.o + 0x000010c4 MemoryUploadBlock + .text.MemoryDownloadBlock + 0x00001120 0x5e Bin/Memory.o + 0x00001120 MemoryDownloadBlock + .text.ButtonInit + 0x0000117e 0xe Bin/Button.o + 0x0000117e ButtonInit + .text.ButtonTick + 0x0000118c 0x1ba Bin/Button.o + 0x0000118c ButtonTick + .text.ButtonGetActionList + 0x00001346 0x60 Bin/Button.o + 0x00001346 ButtonGetActionList + .text.ButtonSetActionById + 0x000013a6 0xc Bin/Button.o + 0x000013a6 ButtonSetActionById + .text.ButtonGetActionByName + 0x000013b2 0x26 Bin/Button.o + 0x000013b2 ButtonGetActionByName + .text.ButtonSetActionByName + 0x000013d8 0x92 Bin/Button.o + 0x000013d8 ButtonSetActionByName + .text.SettingsLoad + 0x0000146a 0x10 Bin/Settings.o + 0x0000146a SettingsLoad + .text.SettingsSave + 0x0000147a 0x10 Bin/Settings.o + 0x0000147a SettingsSave + .text.SettingsSetActiveById + 0x0000148a 0x1e Bin/Settings.o + 0x0000148a SettingsSetActiveById + .text.SettingsCycle + 0x000014a8 0xda Bin/Settings.o + 0x000014a8 SettingsCycle + .text.SettingsGetActiveById + 0x00001582 0x6 Bin/Settings.o + 0x00001582 SettingsGetActiveById + .text.SettingsGetActiveByName + 0x00001588 0x14 Bin/Settings.o + 0x00001588 SettingsGetActiveByName + .text.SettingsSetActiveByName + 0x0000159c 0x1e Bin/Settings.o + 0x0000159c SettingsSetActiveByName + .text.TerminalSendString + 0x000015ba 0xa Bin/Terminal.o + 0x000015ba TerminalSendString + .text.TerminalSendStringP + 0x000015c4 0x28 Bin/Terminal.o + 0x000015c4 TerminalSendStringP + .text.TerminalSendBlock + 0x000015ec 0xe Bin/Terminal.o + 0x000015ec TerminalSendBlock + .text.TerminalInit + 0x000015fa 0xa Bin/Terminal.o + 0x000015fa TerminalInit + .text.TerminalTask + 0x00001604 0x42 Bin/Terminal.o + 0x00001604 TerminalTask + .text.TerminalTick + 0x00001646 0x7e Bin/Terminal.o + 0x00001646 TerminalTick + .text.EVENT_USB_Device_Connect + 0x000016c4 0xa Bin/Terminal.o + 0x000016c4 EVENT_USB_Device_Connect + .text.EVENT_USB_Device_Disconnect + 0x000016ce 0xa Bin/Terminal.o + 0x000016ce EVENT_USB_Device_Disconnect + .text.EVENT_USB_Device_ConfigurationChanged + 0x000016d8 0x8 Bin/Terminal.o + 0x000016d8 EVENT_USB_Device_ConfigurationChanged + .text.EVENT_USB_Device_ControlRequest + 0x000016e0 0x8 Bin/Terminal.o + 0x000016e0 EVENT_USB_Device_ControlRequest + .text.CommandGetVersion + 0x000016e8 0x5a Bin/Commands.o + 0x000016e8 CommandGetVersion + .text.CommandGetConfig + 0x00001742 0x4a Bin/Commands.o + 0x00001742 CommandGetConfig + .text.CommandSetConfig + 0x0000178c 0x10 Bin/Commands.o + 0x0000178c CommandSetConfig + .text.CommandExecConfig + 0x0000179c 0xa Bin/Commands.o + 0x0000179c CommandExecConfig + .text.CommandGetUid + 0x000017a6 0x4c Bin/Commands.o + 0x000017a6 CommandGetUid + .text.CommandSetUid + 0x000017f2 0xa8 Bin/Commands.o + 0x000017f2 CommandSetUid + .text.CommandGetReadOnly + 0x0000189a 0x1e Bin/Commands.o + 0x0000189a CommandGetReadOnly + .text.CommandSetReadOnly + 0x000018b8 0x2c Bin/Commands.o + 0x000018b8 CommandSetReadOnly + .text.CommandExecUpload + 0x000018e4 0xa Bin/Commands.o + 0x000018e4 CommandExecUpload + .text.CommandExecDownload + 0x000018ee 0xa Bin/Commands.o + 0x000018ee CommandExecDownload + .text.CommandExecReset + 0x000018f8 0x16 Bin/Commands.o + 0x000018f8 CommandExecReset + .text.CommandExecUpgrade + 0x0000190e 0x16 Bin/Commands.o + 0x0000190e CommandExecUpgrade + .text.CommandGetMemSize + 0x00001924 0x4e Bin/Commands.o + 0x00001924 CommandGetMemSize + .text.CommandGetUidSize + 0x00001972 0x4a Bin/Commands.o + 0x00001972 CommandGetUidSize + .text.CommandExecButton + 0x000019bc 0xa Bin/Commands.o + 0x000019bc CommandExecButton + .text.CommandGetButton + 0x000019c6 0xa Bin/Commands.o + 0x000019c6 CommandGetButton + .text.CommandSetButton + 0x000019d0 0x10 Bin/Commands.o + 0x000019d0 CommandSetButton + .text.CommandGetSetting + 0x000019e0 0xa Bin/Commands.o + 0x000019e0 CommandGetSetting + .text.CommandSetSetting + 0x000019ea 0x10 Bin/Commands.o + 0x000019ea CommandSetSetting + .text.CommandExecClear + 0x000019fa 0x6 Bin/Commands.o + 0x000019fa CommandExecClear + .text.CommandExecHelp + 0x00001a00 0x9a Bin/Commands.o + 0x00001a00 CommandExecHelp + .text.CommandGetRssi + 0x00001a9a 0x94 Bin/Commands.o + 0x00001a9a CommandGetRssi + .text.CalcChecksum.constprop.0 + 0x00001b2e 0x14 Bin/XModem.o + .text.XModemReceive + 0x00001b42 0x30 Bin/XModem.o + 0x00001b42 XModemReceive + .text.XModemSend + 0x00001b72 0x26 Bin/XModem.o + 0x00001b72 XModemSend + .text.XModemProcessByte + 0x00001b98 0x2b2 Bin/XModem.o + 0x00001b98 XModemProcessByte + .text.XModemTick + 0x00001e4a 0x5c Bin/XModem.o + 0x00001e4a XModemTick + .text.CommandLineProcessByte + 0x00001ea6 0x346 Bin/CommandLine.o + 0x00001ea6 CommandLineProcessByte + .text.CommandLineTick + 0x000021ec 0x2 Bin/CommandLine.o + 0x000021ec CommandLineTick + .text.StartDemod + 0x000021ee 0x3e Bin/ISO14443-2A.o + .text.__vector_34 + 0x0000222c 0x88 Bin/ISO14443-2A.o + 0x0000222c __vector_34 + .text.__vector_22 + 0x000022b4 0x148 Bin/ISO14443-2A.o + 0x000022b4 __vector_22 + .text.__vector_83 + 0x000023fc 0x212 Bin/ISO14443-2A.o + 0x000023fc __vector_83 + .text.ISO14443ACodecInit + 0x0000260e 0x70 Bin/ISO14443-2A.o + 0x0000260e ISO14443ACodecInit + .text.ISO14443ACodecTask + 0x0000267e 0xf2 Bin/ISO14443-2A.o + 0x0000267e ISO14443ACodecTask + .text.MifareClassicAppInit1K + 0x00002770 0x1a Bin/MifareClassic.o + 0x00002770 MifareClassicAppInit1K + .text.MifareClassicAppInit4K + 0x0000278a 0x1a Bin/MifareClassic.o + 0x0000278a MifareClassicAppInit4K + .text.MifareClassicAppReset + 0x000027a4 0x8 Bin/MifareClassic.o + 0x000027a4 MifareClassicAppReset + .text.MifareClassicAppTask + 0x000027ac 0x2 Bin/MifareClassic.o + 0x000027ac MifareClassicAppTask + .text.MifareClassicAppProcess + 0x000027ae 0x9bc Bin/MifareClassic.o + 0x000027ae MifareClassicAppProcess + .text.MifareClassicGetUid + 0x0000316a 0xc Bin/MifareClassic.o + 0x0000316a MifareClassicGetUid + .text.MifareClassicSetUid + 0x00003176 0x42 Bin/MifareClassic.o + 0x00003176 MifareClassicSetUid + .text.ISO14443AAppendCRCA + 0x000031b8 0x7c Bin/ISO14443-3A.o + 0x000031b8 ISO14443AAppendCRCA + .text.ISO14443ACheckCRCA + 0x00003234 0x9c Bin/ISO14443-3A.o + 0x00003234 ISO14443ACheckCRCA + .text.Crypto1LFSR + 0x000032d0 0xce Bin/Crypto1.o + .text.Crypto1FilterOutput + 0x0000339e 0x68 Bin/Crypto1.o + 0x0000339e Crypto1FilterOutput + .text.Crypto1Setup + 0x00003406 0x38c Bin/Crypto1.o + 0x00003406 Crypto1Setup + .text.Crypto1Auth + 0x00003792 0x7e Bin/Crypto1.o + 0x00003792 Crypto1Auth + .text.Crypto1Byte + 0x00003810 0x82 Bin/Crypto1.o + 0x00003810 Crypto1Byte + .text.Crypto1Nibble + 0x00003892 0x48 Bin/Crypto1.o + 0x00003892 Crypto1Nibble + .text.Crypto1PRNG + 0x000038da 0xfc Bin/Crypto1.o + 0x000038da Crypto1PRNG + .text.USB_Device_ProcessControlRequest + 0x000039d6 0x2b0 Bin/DeviceStandardReq.o + 0x000039d6 USB_Device_ProcessControlRequest + .text.USB_Event_Stub + 0x00003c86 0x2 Bin/Events.o + 0x00003c86 USB_Event_Stub + 0x00003c86 EVENT_USB_Device_Suspend + 0x00003c86 EVENT_USB_Device_StartOfFrame + 0x00003c86 EVENT_USB_Device_Reset + 0x00003c86 EVENT_USB_Device_WakeUp + .text.USB_USBTask + 0x00003c88 0x28 Bin/USBTask.o + 0x00003c88 USB_USBTask + .text.Endpoint_Write_Stream_LE + 0x00003cb0 0xd8 Bin/EndpointStream_XMEGA.o + 0x00003cb0 Endpoint_Write_Stream_LE + .text.Endpoint_Write_Control_Stream_LE + 0x00003d88 0x14a Bin/EndpointStream_XMEGA.o + 0x00003d88 Endpoint_Write_Control_Stream_LE + .text.Endpoint_Write_Control_PStream_LE + 0x00003ed2 0x160 Bin/EndpointStream_XMEGA.o + 0x00003ed2 Endpoint_Write_Control_PStream_LE + .text.Endpoint_ClearIN + 0x00004032 0x32 Bin/Endpoint_XMEGA.o + 0x00004032 Endpoint_ClearIN + .text.Endpoint_ClearOUT + 0x00004064 0x1e Bin/Endpoint_XMEGA.o + 0x00004064 Endpoint_ClearOUT + .text.Endpoint_Read_8 + 0x00004082 0x1e Bin/Endpoint_XMEGA.o + 0x00004082 Endpoint_Read_8 + .text.Endpoint_Write_8 + 0x000040a0 0x1e Bin/Endpoint_XMEGA.o + 0x000040a0 Endpoint_Write_8 + .text.Endpoint_SelectEndpoint + 0x000040be 0x78 Bin/Endpoint_XMEGA.o + 0x000040be Endpoint_SelectEndpoint + .text.Endpoint_StallTransaction + 0x00004136 0x38 Bin/Endpoint_XMEGA.o + 0x00004136 Endpoint_StallTransaction + .text.Endpoint_ClearSETUP + 0x0000416e 0x58 Bin/Endpoint_XMEGA.o + 0x0000416e Endpoint_ClearSETUP + .text.Endpoint_IsSETUPReceived + 0x000041c6 0x30 Bin/Endpoint_XMEGA.o + 0x000041c6 Endpoint_IsSETUPReceived + .text.Endpoint_IsOUTReceived + 0x000041f6 0x30 Bin/Endpoint_XMEGA.o + 0x000041f6 Endpoint_IsOUTReceived + .text.Endpoint_IsINReady + 0x00004226 0x1a Bin/Endpoint_XMEGA.o + 0x00004226 Endpoint_IsINReady + .text.Endpoint_ConfigureEndpoint_PRV + 0x00004240 0x9a Bin/Endpoint_XMEGA.o + 0x00004240 Endpoint_ConfigureEndpoint_PRV + .text.Endpoint_ConfigureEndpointTable + 0x000042da 0xd8 Bin/Endpoint_XMEGA.o + 0x000042da Endpoint_ConfigureEndpointTable + .text.Endpoint_ClearEndpoints + 0x000043b2 0x70 Bin/Endpoint_XMEGA.o + 0x000043b2 Endpoint_ClearEndpoints + .text.Endpoint_ClearStatusStage + 0x00004422 0x2c Bin/Endpoint_XMEGA.o + 0x00004422 Endpoint_ClearStatusStage + .text.Endpoint_WaitUntilReady + 0x0000444e 0xa2 Bin/Endpoint_XMEGA.o + 0x0000444e Endpoint_WaitUntilReady + .text.USB_Disable + 0x000044f0 0x1a Bin/USBController_XMEGA.o + 0x000044f0 USB_Disable + .text.USB_ResetInterface + 0x0000450a 0x5c Bin/USBController_XMEGA.o + 0x0000450a USB_ResetInterface + .text.USB_Init + 0x00004566 0x54 Bin/USBController_XMEGA.o + 0x00004566 USB_Init + .text.USB_INT_DisableAllInterrupts + 0x000045ba 0xe Bin/USBInterrupt_XMEGA.o + 0x000045ba USB_INT_DisableAllInterrupts + .text.USB_INT_ClearAllInterrupts + 0x000045c8 0xc Bin/USBInterrupt_XMEGA.o + 0x000045c8 USB_INT_ClearAllInterrupts + .text.__vector_125 + 0x000045d4 0xe0 Bin/USBInterrupt_XMEGA.o + 0x000045d4 __vector_125 + .text.CDC_Device_ProcessControlRequest + 0x000046b4 0x156 Bin/CDCClassDevice.o + 0x000046b4 CDC_Device_ProcessControlRequest + .text.CDC_Device_ConfigureEndpoints + 0x0000480a 0x4c Bin/CDCClassDevice.o + 0x0000480a CDC_Device_ConfigureEndpoints + .text.CDC_Device_SendString + 0x00004856 0x48 Bin/CDCClassDevice.o + 0x00004856 CDC_Device_SendString + .text.CDC_Device_SendData + 0x0000489e 0x44 Bin/CDCClassDevice.o + 0x0000489e CDC_Device_SendData + .text.CDC_Device_SendByte + 0x000048e2 0x56 Bin/CDCClassDevice.o + 0x000048e2 CDC_Device_SendByte + .text.CDC_Device_Flush + 0x00004938 0x92 Bin/CDCClassDevice.o + 0x00004938 CDC_Device_Flush + .text.CDC_Device_USBTask + 0x000049ca 0x34 Bin/CDCClassDevice.o + 0x000049ca CDC_Device_USBTask + .text.CDC_Device_ReceiveByte + 0x000049fe 0xca Bin/CDCClassDevice.o + 0x000049fe CDC_Device_ReceiveByte + .text.CDC_Device_Event_Stub + 0x00004ac8 0x2 Bin/CDCClassDevice.o + 0x00004ac8 EVENT_CDC_Device_ControLineStateChanged + 0x00004ac8 EVENT_CDC_Device_BreakSent + 0x00004ac8 CDC_Device_Event_Stub + 0x00004ac8 EVENT_CDC_Device_LineEncodingChanged + .text.libgcc 0x00004aca 0x3e c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + 0x00004aca __mulsi3 + .text.avr-libc + 0x00004b08 0xbc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + 0x00004ba6 rand_r + 0x00004ba8 rand + 0x00004bae srand + .text.avr-libc + 0x00004bc4 0x12 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + 0x00004bc4 memcpy_P + .text.avr-libc + 0x00004bd6 0x12 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + 0x00004bd6 strcmp_P + .text.avr-libc + 0x00004be8 0x1e c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + 0x00004be8 strncpy_P + .text.avr-libc + 0x00004c06 0x12 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + 0x00004c06 memcpy + .text.avr-libc + 0x00004c18 0x5a c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + 0x00004c18 snprintf_P + .text.avr-libc + 0x00004c72 0x39e c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + 0x00004c72 vfprintf + .text.avr-libc + 0x00005010 0x16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + 0x00005010 __eerd_block_x32a4u + .text.avr-libc + 0x00005026 0x12 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + 0x00005026 __eewr_block_x32a4u + .text.avr-libc + 0x00005038 0x46 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + 0x00005038 __eewr_byte_x32a4u + 0x0000503a __eewr_r18_x32a4u + .text.avr-libc + 0x0000507e 0x16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + 0x0000507e strnlen_P + .text.avr-libc + 0x00005094 0x16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + 0x00005094 strnlen + .text.avr-libc + 0x000050aa 0x58 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + 0x000050aa fputc + .text.avr-libc + 0x00005102 0xbc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + 0x00005102 __ultoa_invert + .text.libgcc 0x000051be 0x36 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + 0x000051be __divmodsi4 + .text.libgcc 0x000051f4 0x32 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + 0x000051f4 __prologue_saves__ + .text.libgcc 0x00005226 0x30 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + 0x00005226 __epilogue_restores__ + .text.libgcc 0x00005256 0x44 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + 0x00005256 __udivmodsi4 + 0x0000529a . = ALIGN (0x2) + *(.fini9) + .fini9 0x0000529a 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + 0x0000529a _exit + 0x0000529a exit + *(.fini9) + *(.fini8) + *(.fini8) + *(.fini7) + *(.fini7) + *(.fini6) + *(.fini6) + *(.fini5) + *(.fini5) + *(.fini4) + *(.fini4) + *(.fini3) + *(.fini3) + *(.fini2) + *(.fini2) + *(.fini1) + *(.fini1) + *(.fini0) + .fini0 0x0000529a 0x4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + *(.fini0) + 0x0000529e _etext = . + +.data 0x00802000 0xa2 load address 0x0000529e + 0x00802000 PROVIDE (__data_start, .) + *(.data) + .data 0x00802000 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .data 0x00802000 0x0 Bin/Chameleon-Mini.o + .data 0x00802000 0x0 Bin/LUFADescriptors.o + .data 0x00802000 0x0 Bin/System.o + .data 0x00802000 0x0 Bin/Configuration.o + .data 0x00802000 0x0 Bin/Random.o + .data 0x00802000 0x0 Bin/Common.o + .data 0x00802000 0x0 Bin/Memory.o + .data 0x00802000 0x0 Bin/Button.o + .data 0x00802000 0x0 Bin/Settings.o + .data 0x00802000 0x0 Bin/LED.o + .data 0x00802000 0x1c Bin/Terminal.o + 0x00802000 TerminalHandle + .data 0x0080201c 0x1 Bin/Commands.o + .data 0x0080201d 0x0 Bin/XModem.o + .data 0x0080201d 0x0 Bin/CommandLine.o + .data 0x0080201d 0x0 Bin/Codec.o + .data 0x0080201d 0x0 Bin/ISO14443-2A.o + .data 0x0080201d 0x0 Bin/MifareClassic.o + .data 0x0080201d 0x0 Bin/ISO14443-3A.o + .data 0x0080201d 0x70 Bin/Crypto1.o + .data 0x0080208d 0x0 Bin/HIDParser.o + .data 0x0080208d 0x0 Bin/ConfigDescriptors.o + .data 0x0080208d 0x0 Bin/DeviceStandardReq.o + .data 0x0080208d 0x0 Bin/Events.o + .data 0x0080208d 0x0 Bin/HostStandardReq.o + .data 0x0080208d 0x0 Bin/USBTask.o + .data 0x0080208d 0x0 Bin/Device_XMEGA.o + .data 0x0080208d 0x0 Bin/EndpointStream_XMEGA.o + .data 0x0080208d 0x0 Bin/Endpoint_XMEGA.o + .data 0x0080208d 0x0 Bin/Host_XMEGA.o + .data 0x0080208d 0x0 Bin/PipeStream_XMEGA.o + .data 0x0080208d 0x0 Bin/Pipe_XMEGA.o + .data 0x0080208d 0x0 Bin/USBController_XMEGA.o + .data 0x0080208d 0x0 Bin/USBInterrupt_XMEGA.o + .data 0x0080208d 0x0 Bin/AudioClassDevice.o + .data 0x0080208d 0x8 Bin/CDCClassDevice.o + .data 0x00802095 0x0 Bin/HIDClassDevice.o + .data 0x00802095 0x0 Bin/MassStorageClassDevice.o + .data 0x00802095 0x0 Bin/MIDIClassDevice.o + .data 0x00802095 0x0 Bin/PrinterClassDevice.o + .data 0x00802095 0x8 Bin/RNDISClassDevice.o + .data 0x0080209d 0x0 Bin/AndroidAccessoryClassHost.o + .data 0x0080209d 0x0 Bin/AudioClassHost.o + .data 0x0080209d 0x0 Bin/CDCClassHost.o + .data 0x0080209d 0x0 Bin/HIDClassHost.o + .data 0x0080209d 0x0 Bin/MassStorageClassHost.o + .data 0x0080209d 0x0 Bin/MIDIClassHost.o + .data 0x0080209d 0x0 Bin/PrinterClassHost.o + .data 0x0080209d 0x0 Bin/RNDISClassHost.o + .data 0x0080209d 0x0 Bin/StillImageClassHost.o + .data 0x0080209d 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .data 0x0080209d 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .data 0x0080209d 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .data 0x0080209d 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .data 0x0080209d 0x4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .data 0x008020a1 0x0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + *(.data*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.d*) + 0x008020a2 . = ALIGN (0x2) + *fill* 0x008020a1 0x1 00 + 0x008020a2 _edata = . + 0x008020a2 PROVIDE (__data_end, .) + +.bss 0x008020a2 0x60b + 0x008020a2 PROVIDE (__bss_start, .) + *(.bss) + .bss 0x008020a2 0x1 Bin/Button.o + .bss 0x008020a3 0x1 Bin/LED.o + 0x008020a3 LEDPulseMask + .bss 0x008020a4 0x1 Bin/Terminal.o + 0x008020a4 TerminalState + .bss 0x008020a5 0xe Bin/XModem.o + .bss 0x008020b3 0x2 Bin/CommandLine.o + .bss 0x008020b5 0x10 Bin/ISO14443-2A.o + .bss 0x008020c5 0x1d Bin/MifareClassic.o + .bss 0x008020e2 0x6 Bin/Crypto1.o + *(.bss*) + *(COMMON) + COMMON 0x008020e8 0x25 Bin/Configuration.o + 0x008020e8 ActiveConfiguration + COMMON 0x0080210d 0x13 Bin/Settings.o + 0x0080210d GlobalSettings + COMMON 0x00802120 0x100 Bin/Terminal.o + 0x00802120 TerminalBuffer + COMMON 0x00802220 0x100 Bin/Codec.o + 0x00802220 CodecBuffer + COMMON 0x00802320 0x3 Bin/DeviceStandardReq.o + 0x00802320 USB_Device_ConfigurationNumber + 0x00802321 USB_Device_CurrentlySelfPowered + 0x00802322 USB_Device_RemoteWakeupEnabled + COMMON 0x00802323 0xa Bin/USBTask.o + 0x00802323 USB_IsInitialized + 0x00802324 USB_DeviceState + 0x00802325 USB_ControlRequest + COMMON 0x0080232d 0x31d Bin/Endpoint_XMEGA.o + 0x0080232d USB_Endpoint_SelectedFIFO + 0x0080232f USB_Endpoint_SelectedHandle + 0x00802331 USB_Endpoint_SelectedEndpoint + 0x00802332 USB_Endpoint_FIFOs + COMMON 0x0080264a 0x63 Bin/USBController_XMEGA.o + 0x0080264a USB_EndpointTable + 0x008026ad PROVIDE (__bss_end, .) + 0x0000529e __data_load_start = LOADADDR (.data) + 0x00005340 __data_load_end = (__data_load_start + SIZEOF (.data)) + +.noinit 0x008026ad 0x0 + 0x008026ad PROVIDE (__noinit_start, .) + *(.noinit*) + 0x008026ad PROVIDE (__noinit_end, .) + 0x008026ad _end = . + 0x008026ad PROVIDE (__heap_start, .) + +.eeprom 0x00810000 0x13 + *(.eeprom*) + .eeprom 0x00810000 0x13 Bin/Settings.o + 0x00810000 StoredSettings + 0x00810013 __eeprom_end = . + +.fuse + *(.fuse) + *(.lfuse) + *(.hfuse) + *(.efuse) + +.lock + *(.lock*) + +.signature + *(.signature*) + +.stab 0x00000000 0x14d0 + *(.stab) + .stab 0x00000000 0x6cc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + .stab 0x000006cc 0x84 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + 0x90 (size before relaxing) + .stab 0x00000750 0x84 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + 0x90 (size before relaxing) + .stab 0x000007d4 0xcc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + 0xd8 (size before relaxing) + .stab 0x000008a0 0xb4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + 0xc0 (size before relaxing) + .stab 0x00000954 0x84 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + 0x90 (size before relaxing) + .stab 0x000009d8 0x6c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + 0x78 (size before relaxing) + .stab 0x00000a44 0xb4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + 0xc0 (size before relaxing) + .stab 0x00000af8 0xfc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + 0x108 (size before relaxing) + .stab 0x00000bf4 0xa8 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + 0xb4 (size before relaxing) + .stab 0x00000c9c 0x9c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + 0xa8 (size before relaxing) + .stab 0x00000d38 0x1e0 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + 0x1ec (size before relaxing) + .stab 0x00000f18 0x9c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + 0xa8 (size before relaxing) + .stab 0x00000fb4 0x9c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + 0xa8 (size before relaxing) + .stab 0x00001050 0x480 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + 0x48c (size before relaxing) + +.stabstr 0x00000000 0x601 + *(.stabstr) + .stabstr 0x00000000 0x601 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o + +.stab.excl + *(.stab.excl) + +.stab.exclstr + *(.stab.exclstr) + +.stab.index + *(.stab.index) + +.stab.indexstr + *(.stab.indexstr) + +.comment + *(.comment) + +.debug + *(.debug) + +.line + *(.line) + +.debug_srcinfo + *(.debug_srcinfo) + +.debug_sfnames + *(.debug_sfnames) + +.debug_aranges 0x00000000 0xb78 + *(.debug_aranges) + .debug_aranges + 0x00000000 0x20 Bin/Chameleon-Mini.o + .debug_aranges + 0x00000020 0x20 Bin/LUFADescriptors.o + .debug_aranges + 0x00000040 0x50 Bin/System.o + .debug_aranges + 0x00000090 0x78 Bin/Configuration.o + .debug_aranges + 0x00000108 0x38 Bin/Random.o + .debug_aranges + 0x00000140 0x28 Bin/Common.o + .debug_aranges + 0x00000168 0x48 Bin/Memory.o + .debug_aranges + 0x000001b0 0x48 Bin/Button.o + .debug_aranges + 0x000001f8 0x50 Bin/Settings.o + .debug_aranges + 0x00000248 0x68 Bin/Terminal.o + .debug_aranges + 0x000002b0 0xc8 Bin/Commands.o + .debug_aranges + 0x00000378 0x40 Bin/XModem.o + .debug_aranges + 0x000003b8 0x30 Bin/CommandLine.o + .debug_aranges + 0x000003e8 0x48 Bin/ISO14443-2A.o + .debug_aranges + 0x00000430 0x50 Bin/MifareClassic.o + .debug_aranges + 0x00000480 0x28 Bin/ISO14443-3A.o + .debug_aranges + 0x000004a8 0x50 Bin/Crypto1.o + .debug_aranges + 0x000004f8 0x38 Bin/HIDParser.o + .debug_aranges + 0x00000530 0x38 Bin/ConfigDescriptors.o + .debug_aranges + 0x00000568 0x20 Bin/DeviceStandardReq.o + .debug_aranges + 0x00000588 0x20 Bin/Events.o + .debug_aranges + 0x000005a8 0x20 Bin/USBTask.o + .debug_aranges + 0x000005c8 0x20 Bin/Device_XMEGA.o + .debug_aranges + 0x000005e8 0xc8 Bin/EndpointStream_XMEGA.o + .debug_aranges + 0x000006b0 0x90 Bin/Endpoint_XMEGA.o + .debug_aranges + 0x00000740 0x30 Bin/USBController_XMEGA.o + .debug_aranges + 0x00000770 0x30 Bin/USBInterrupt_XMEGA.o + .debug_aranges + 0x000007a0 0x30 Bin/AudioClassDevice.o + .debug_aranges + 0x000007d0 0x98 Bin/CDCClassDevice.o + .debug_aranges + 0x00000868 0x30 Bin/HIDClassDevice.o + .debug_aranges + 0x00000898 0x30 Bin/MassStorageClassDevice.o + .debug_aranges + 0x000008c8 0x40 Bin/MIDIClassDevice.o + .debug_aranges + 0x00000908 0x90 Bin/PrinterClassDevice.o + .debug_aranges + 0x00000998 0x48 Bin/RNDISClassDevice.o + .debug_aranges + 0x000009e0 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .debug_aranges + 0x00000a00 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .debug_aranges + 0x00000a20 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .debug_aranges + 0x00000a40 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .debug_aranges + 0x00000a60 0x38 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_aranges + 0x00000a98 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_aranges + 0x00000ab8 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_aranges + 0x00000ad8 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .debug_aranges + 0x00000af8 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .debug_aranges + 0x00000b18 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .debug_aranges + 0x00000b38 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .debug_aranges + 0x00000b58 0x20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + +.debug_pubnames + *(.debug_pubnames) + +.debug_info 0x00000000 0x159d0 + *(.debug_info) + .debug_info 0x00000000 0x12ec Bin/Chameleon-Mini.o + .debug_info 0x000012ec 0x9cb Bin/LUFADescriptors.o + .debug_info 0x00001cb7 0xdc3 Bin/System.o + .debug_info 0x00002a7a 0x5c0 Bin/Configuration.o + .debug_info 0x0000303a 0x106 Bin/Random.o + .debug_info 0x00003140 0x1ad Bin/Common.o + .debug_info 0x000032ed 0xf4c Bin/Memory.o + .debug_info 0x00004239 0x7e1 Bin/Button.o + .debug_info 0x00004a1a 0x40e Bin/Settings.o + .debug_info 0x00004e28 0x88 Bin/LED.o + .debug_info 0x00004eb0 0x8f9 Bin/Terminal.o + .debug_info 0x000057a9 0x13fd Bin/Commands.o + .debug_info 0x00006ba6 0x89d Bin/XModem.o + .debug_info 0x00007443 0x953 Bin/CommandLine.o + .debug_info 0x00007d96 0x1ff Bin/Codec.o + .debug_info 0x00007f95 0x185a Bin/ISO14443-2A.o + .debug_info 0x000097ef 0x8eb Bin/MifareClassic.o + .debug_info 0x0000a0da 0x170 Bin/ISO14443-3A.o + .debug_info 0x0000a24a 0x3b3 Bin/Crypto1.o + .debug_info 0x0000a5fd 0x6f4 Bin/HIDParser.o + .debug_info 0x0000acf1 0x5a4 Bin/ConfigDescriptors.o + .debug_info 0x0000b295 0xf1b Bin/DeviceStandardReq.o + .debug_info 0x0000c1b0 0x77 Bin/Events.o + .debug_info 0x0000c227 0x5e Bin/HostStandardReq.o + .debug_info 0x0000c285 0x3f2 Bin/USBTask.o + .debug_info 0x0000c677 0x680 Bin/Device_XMEGA.o + .debug_info 0x0000ccf7 0x1100 Bin/EndpointStream_XMEGA.o + .debug_info 0x0000ddf7 0xc66 Bin/Endpoint_XMEGA.o + .debug_info 0x0000ea5d 0x5e Bin/Host_XMEGA.o + .debug_info 0x0000eabb 0x5e Bin/PipeStream_XMEGA.o + .debug_info 0x0000eb19 0x5e Bin/Pipe_XMEGA.o + .debug_info 0x0000eb77 0xd06 Bin/USBController_XMEGA.o + .debug_info 0x0000f87d 0x9ee Bin/USBInterrupt_XMEGA.o + .debug_info 0x0001026b 0x6f4 Bin/AudioClassDevice.o + .debug_info 0x0001095f 0xb5b Bin/CDCClassDevice.o + .debug_info 0x000114ba 0xb21 Bin/HIDClassDevice.o + .debug_info 0x00011fdb 0x7dd Bin/MassStorageClassDevice.o + .debug_info 0x000127b8 0x60f Bin/MIDIClassDevice.o + .debug_info 0x00012dc7 0xab2 Bin/PrinterClassDevice.o + .debug_info 0x00013879 0xf61 Bin/RNDISClassDevice.o + .debug_info 0x000147da 0x5e Bin/AndroidAccessoryClassHost.o + .debug_info 0x00014838 0x5e Bin/AudioClassHost.o + .debug_info 0x00014896 0x5e Bin/CDCClassHost.o + .debug_info 0x000148f4 0x5e Bin/HIDClassHost.o + .debug_info 0x00014952 0x5e Bin/MassStorageClassHost.o + .debug_info 0x000149b0 0x5e Bin/MIDIClassHost.o + .debug_info 0x00014a0e 0x5e Bin/PrinterClassHost.o + .debug_info 0x00014a6c 0x5e Bin/RNDISClassHost.o + .debug_info 0x00014aca 0x5e Bin/StillImageClassHost.o + .debug_info 0x00014b28 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .debug_info 0x00014c0a 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .debug_info 0x00014cec 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .debug_info 0x00014dce 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .debug_info 0x00014eb0 0x120 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_info 0x00014fd0 0x1cf c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_info 0x0001519f 0x342 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_info 0x000154e1 0x167 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .debug_info 0x00015648 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .debug_info 0x0001572a 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .debug_info 0x0001580c 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .debug_info 0x000158ee 0xe2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + *(.gnu.linkonce.wi.*) + +.debug_abbrev 0x00000000 0x4a41 + *(.debug_abbrev) + .debug_abbrev 0x00000000 0x1b3 Bin/Chameleon-Mini.o + .debug_abbrev 0x000001b3 0x1b8 Bin/LUFADescriptors.o + .debug_abbrev 0x0000036b 0x13e Bin/System.o + .debug_abbrev 0x000004a9 0x20e Bin/Configuration.o + .debug_abbrev 0x000006b7 0xaa Bin/Random.o + .debug_abbrev 0x00000761 0xa2 Bin/Common.o + .debug_abbrev 0x00000803 0x260 Bin/Memory.o + .debug_abbrev 0x00000a63 0x224 Bin/Button.o + .debug_abbrev 0x00000c87 0x171 Bin/Settings.o + .debug_abbrev 0x00000df8 0x59 Bin/LED.o + .debug_abbrev 0x00000e51 0x277 Bin/Terminal.o + .debug_abbrev 0x000010c8 0x2c9 Bin/Commands.o + .debug_abbrev 0x00001391 0x259 Bin/XModem.o + .debug_abbrev 0x000015ea 0x253 Bin/CommandLine.o + .debug_abbrev 0x0000183d 0xc8 Bin/Codec.o + .debug_abbrev 0x00001905 0x2a8 Bin/ISO14443-2A.o + .debug_abbrev 0x00001bad 0x29a Bin/MifareClassic.o + .debug_abbrev 0x00001e47 0xa0 Bin/ISO14443-3A.o + .debug_abbrev 0x00001ee7 0x17d Bin/Crypto1.o + .debug_abbrev 0x00002064 0x1d4 Bin/HIDParser.o + .debug_abbrev 0x00002238 0x1ef Bin/ConfigDescriptors.o + .debug_abbrev 0x00002427 0x2bd Bin/DeviceStandardReq.o + .debug_abbrev 0x000026e4 0x41 Bin/Events.o + .debug_abbrev 0x00002725 0x2a Bin/HostStandardReq.o + .debug_abbrev 0x0000274f 0x1a3 Bin/USBTask.o + .debug_abbrev 0x000028f2 0x11b Bin/Device_XMEGA.o + .debug_abbrev 0x00002a0d 0x1b0 Bin/EndpointStream_XMEGA.o + .debug_abbrev 0x00002bbd 0x299 Bin/Endpoint_XMEGA.o + .debug_abbrev 0x00002e56 0x2a Bin/Host_XMEGA.o + .debug_abbrev 0x00002e80 0x2a Bin/PipeStream_XMEGA.o + .debug_abbrev 0x00002eaa 0x2a Bin/Pipe_XMEGA.o + .debug_abbrev 0x00002ed4 0x2a7 Bin/USBController_XMEGA.o + .debug_abbrev 0x0000317b 0x202 Bin/USBInterrupt_XMEGA.o + .debug_abbrev 0x0000337d 0x1c8 Bin/AudioClassDevice.o + .debug_abbrev 0x00003545 0x33b Bin/CDCClassDevice.o + .debug_abbrev 0x00003880 0x1ef Bin/HIDClassDevice.o + .debug_abbrev 0x00003a6f 0x24f Bin/MassStorageClassDevice.o + .debug_abbrev 0x00003cbe 0x1bb Bin/MIDIClassDevice.o + .debug_abbrev 0x00003e79 0x2ec Bin/PrinterClassDevice.o + .debug_abbrev 0x00004165 0x2af Bin/RNDISClassDevice.o + .debug_abbrev 0x00004414 0x2a Bin/AndroidAccessoryClassHost.o + .debug_abbrev 0x0000443e 0x2a Bin/AudioClassHost.o + .debug_abbrev 0x00004468 0x2a Bin/CDCClassHost.o + .debug_abbrev 0x00004492 0x2a Bin/HIDClassHost.o + .debug_abbrev 0x000044bc 0x2a Bin/MassStorageClassHost.o + .debug_abbrev 0x000044e6 0x2a Bin/MIDIClassHost.o + .debug_abbrev 0x00004510 0x2a Bin/PrinterClassHost.o + .debug_abbrev 0x0000453a 0x2a Bin/RNDISClassHost.o + .debug_abbrev 0x00004564 0x2a Bin/StillImageClassHost.o + .debug_abbrev 0x0000458e 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .debug_abbrev 0x000045a2 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .debug_abbrev 0x000045b6 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .debug_abbrev 0x000045ca 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .debug_abbrev 0x000045de 0xcd c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_abbrev 0x000046ab 0x10c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_abbrev 0x000047b7 0x161 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_abbrev 0x00004918 0xd9 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .debug_abbrev 0x000049f1 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .debug_abbrev 0x00004a05 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .debug_abbrev 0x00004a19 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .debug_abbrev 0x00004a2d 0x14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + +.debug_line 0x00000000 0x75a6 + *(.debug_line) + .debug_line 0x00000000 0x2f5 Bin/Chameleon-Mini.o + .debug_line 0x000002f5 0x2a0 Bin/LUFADescriptors.o + .debug_line 0x00000595 0x1aa Bin/System.o + .debug_line 0x0000073f 0x21c Bin/Configuration.o + .debug_line 0x0000095b 0xdd Bin/Random.o + .debug_line 0x00000a38 0x16a Bin/Common.o + .debug_line 0x00000ba2 0x354 Bin/Memory.o + .debug_line 0x00000ef6 0x28c Bin/Button.o + .debug_line 0x00001182 0x16b Bin/Settings.o + .debug_line 0x000012ed 0x94 Bin/LED.o + .debug_line 0x00001381 0x344 Bin/Terminal.o + .debug_line 0x000016c5 0x532 Bin/Commands.o + .debug_line 0x00001bf7 0x3b7 Bin/XModem.o + .debug_line 0x00001fae 0x2e7 Bin/CommandLine.o + .debug_line 0x00002295 0xaf Bin/Codec.o + .debug_line 0x00002344 0x302 Bin/ISO14443-2A.o + .debug_line 0x00002646 0x394 Bin/MifareClassic.o + .debug_line 0x000029da 0xfa Bin/ISO14443-3A.o + .debug_line 0x00002ad4 0x293 Bin/Crypto1.o + .debug_line 0x00002d67 0x2ce Bin/HIDParser.o + .debug_line 0x00003035 0x23d Bin/ConfigDescriptors.o + .debug_line 0x00003272 0x331 Bin/DeviceStandardReq.o + .debug_line 0x000035a3 0x4f Bin/Events.o + .debug_line 0x000035f2 0x1a Bin/HostStandardReq.o + .debug_line 0x0000360c 0x1c8 Bin/USBTask.o + .debug_line 0x000037d4 0x180 Bin/Device_XMEGA.o + .debug_line 0x00003954 0xae0 Bin/EndpointStream_XMEGA.o + .debug_line 0x00004434 0x4b2 Bin/Endpoint_XMEGA.o + .debug_line 0x000048e6 0x1a Bin/Host_XMEGA.o + .debug_line 0x00004900 0x1a Bin/PipeStream_XMEGA.o + .debug_line 0x0000491a 0x1a Bin/Pipe_XMEGA.o + .debug_line 0x00004934 0x30c Bin/USBController_XMEGA.o + .debug_line 0x00004c40 0x2f6 Bin/USBInterrupt_XMEGA.o + .debug_line 0x00004f36 0x31b Bin/AudioClassDevice.o + .debug_line 0x00005251 0x504 Bin/CDCClassDevice.o + .debug_line 0x00005755 0x3ae Bin/HIDClassDevice.o + .debug_line 0x00005b03 0x390 Bin/MassStorageClassDevice.o + .debug_line 0x00005e93 0x317 Bin/MIDIClassDevice.o + .debug_line 0x000061aa 0x4cd Bin/PrinterClassDevice.o + .debug_line 0x00006677 0x406 Bin/RNDISClassDevice.o + .debug_line 0x00006a7d 0x1a Bin/AndroidAccessoryClassHost.o + .debug_line 0x00006a97 0x1a Bin/AudioClassHost.o + .debug_line 0x00006ab1 0x1a Bin/CDCClassHost.o + .debug_line 0x00006acb 0x1a Bin/HIDClassHost.o + .debug_line 0x00006ae5 0x1a Bin/MassStorageClassHost.o + .debug_line 0x00006aff 0x1a Bin/MIDIClassHost.o + .debug_line 0x00006b19 0x1a Bin/PrinterClassHost.o + .debug_line 0x00006b33 0x1a Bin/RNDISClassHost.o + .debug_line 0x00006b4d 0x1a Bin/StillImageClassHost.o + .debug_line 0x00006b67 0xa5 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + .debug_line 0x00006c0c 0x88 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + .debug_line 0x00006c94 0x91 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + .debug_line 0x00006d25 0x8e c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + .debug_line 0x00006db3 0x91 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_line 0x00006e44 0x169 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_line 0x00006fad 0x290 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_line 0x0000723d 0xe1 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + .debug_line 0x0000731e 0xa1 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + .debug_line 0x000073bf 0xa1 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + .debug_line 0x00007460 0x9e c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + .debug_line 0x000074fe 0xa8 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + +.debug_frame 0x00000000 0x1e1c + *(.debug_frame) + .debug_frame 0x00000000 0x24 Bin/Chameleon-Mini.o + .debug_frame 0x00000024 0x24 Bin/LUFADescriptors.o + .debug_frame 0x00000048 0x90 Bin/System.o + .debug_frame 0x000000d8 0xf4 Bin/Configuration.o + .debug_frame 0x000001cc 0x68 Bin/Random.o + .debug_frame 0x00000234 0x4c Bin/Common.o + .debug_frame 0x00000280 0x120 Bin/Memory.o + .debug_frame 0x000003a0 0xac Bin/Button.o + .debug_frame 0x0000044c 0x90 Bin/Settings.o + .debug_frame 0x000004dc 0xcc Bin/Terminal.o + .debug_frame 0x000005a8 0x1fc Bin/Commands.o + .debug_frame 0x000007a4 0x6c Bin/XModem.o + .debug_frame 0x00000810 0x54 Bin/CommandLine.o + .debug_frame 0x00000864 0xf8 Bin/ISO14443-2A.o + .debug_frame 0x0000095c 0xd4 Bin/MifareClassic.o + .debug_frame 0x00000a30 0x6c Bin/ISO14443-3A.o + .debug_frame 0x00000a9c 0x13c Bin/Crypto1.o + .debug_frame 0x00000bd8 0x124 Bin/HIDParser.o + .debug_frame 0x00000cfc 0xbc Bin/ConfigDescriptors.o + .debug_frame 0x00000db8 0x38 Bin/DeviceStandardReq.o + .debug_frame 0x00000df0 0x24 Bin/Events.o + .debug_frame 0x00000e14 0x2c Bin/USBTask.o + .debug_frame 0x00000e40 0x24 Bin/Device_XMEGA.o + .debug_frame 0x00000e64 0x52c Bin/EndpointStream_XMEGA.o + .debug_frame 0x00001390 0x15c Bin/Endpoint_XMEGA.o + .debug_frame 0x000014ec 0x5c Bin/USBController_XMEGA.o + .debug_frame 0x00001548 0x8c Bin/USBInterrupt_XMEGA.o + .debug_frame 0x000015d4 0xa8 Bin/AudioClassDevice.o + .debug_frame 0x0000167c 0x1c4 Bin/CDCClassDevice.o + .debug_frame 0x00001840 0xf4 Bin/HIDClassDevice.o + .debug_frame 0x00001934 0x80 Bin/MassStorageClassDevice.o + .debug_frame 0x000019b4 0x9c Bin/MIDIClassDevice.o + .debug_frame 0x00001a50 0x198 Bin/PrinterClassDevice.o + .debug_frame 0x00001be8 0xf8 Bin/RNDISClassDevice.o + .debug_frame 0x00001ce0 0x88 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_frame 0x00001d68 0x30 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_frame 0x00001d98 0x4c c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_frame 0x00001de4 0x38 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_str 0x00000000 0x769c + *(.debug_str) + .debug_str 0x00000000 0xc45 Bin/Chameleon-Mini.o + 0xd0a (size before relaxing) + .debug_str 0x00000c45 0x8cc Bin/LUFADescriptors.o + 0xb31 (size before relaxing) + .debug_str 0x00001511 0x767 Bin/System.o + 0xb5d (size before relaxing) + .debug_str 0x00001c78 0x2d0 Bin/Configuration.o + 0x559 (size before relaxing) + .debug_str 0x00001f48 0x3d Bin/Random.o + 0x13f (size before relaxing) + .debug_str 0x00001f85 0x56 Bin/Common.o + 0x167 (size before relaxing) + .debug_str 0x00001fdb 0x2a5 Bin/Memory.o + 0x778 (size before relaxing) + .debug_str 0x00002280 0x1c7 Bin/Button.o + 0x66d (size before relaxing) + .debug_str 0x00002447 0xb3 Bin/Settings.o + 0x476 (size before relaxing) + .debug_str 0x000024fa 0x6 Bin/LED.o + 0xf5 (size before relaxing) + .debug_str 0x00002500 0x1b0 Bin/Terminal.o + 0x60d (size before relaxing) + .debug_str 0x000026b0 0x3b9 Bin/Commands.o + 0xb8a (size before relaxing) + .debug_str 0x00002a69 0x192 Bin/XModem.o + 0x521 (size before relaxing) + .debug_str 0x00002bfb 0xe8 Bin/CommandLine.o + 0x4f4 (size before relaxing) + .debug_str 0x00002ce3 0x1a Bin/Codec.o + 0x265 (size before relaxing) + .debug_str 0x00002cfd 0x12b9 Bin/ISO14443-2A.o + 0x1a34 (size before relaxing) + .debug_str 0x00003fb6 0x236 Bin/MifareClassic.o + 0x4c7 (size before relaxing) + .debug_str 0x000041ec 0x41 Bin/ISO14443-3A.o + 0x15e (size before relaxing) + .debug_str 0x0000422d 0xe8 Bin/Crypto1.o + 0x1ec (size before relaxing) + .debug_str 0x00004315 0x474 Bin/HIDParser.o + 0x5f9 (size before relaxing) + .debug_str 0x00004789 0x22e Bin/ConfigDescriptors.o + 0x445 (size before relaxing) + .debug_str 0x000049b7 0x8f1 Bin/DeviceStandardReq.o + 0xfcf (size before relaxing) + .debug_str 0x000052a8 0x31 Bin/Events.o + 0x10b (size before relaxing) + .debug_str 0x000052d9 0x2b Bin/HostStandardReq.o + 0x105 (size before relaxing) + .debug_str 0x00005304 0x79 Bin/USBTask.o + 0x36c (size before relaxing) + .debug_str 0x0000537d 0x4a Bin/Device_XMEGA.o + 0x529 (size before relaxing) + .debug_str 0x000053c7 0x4c6 Bin/EndpointStream_XMEGA.o + 0x7ec (size before relaxing) + .debug_str 0x0000588d 0x3a9 Bin/Endpoint_XMEGA.o + 0xa44 (size before relaxing) + .debug_str 0x00005c36 0x2c Bin/Host_XMEGA.o + 0x106 (size before relaxing) + .debug_str 0x00005c62 0x32 Bin/PipeStream_XMEGA.o + 0x10c (size before relaxing) + .debug_str 0x00005c94 0x2c Bin/Pipe_XMEGA.o + 0x106 (size before relaxing) + .debug_str 0x00005cc0 0x198 Bin/USBController_XMEGA.o + 0xd7d (size before relaxing) + .debug_str 0x00005e58 0xad Bin/USBInterrupt_XMEGA.o + 0x804 (size before relaxing) + .debug_str 0x00005f05 0x236 Bin/AudioClassDevice.o + 0x5f3 (size before relaxing) + .debug_str 0x0000613b 0x32d Bin/CDCClassDevice.o + 0x944 (size before relaxing) + .debug_str 0x00006468 0x1ea Bin/HIDClassDevice.o + 0x904 (size before relaxing) + .debug_str 0x00006652 0x23a Bin/MassStorageClassDevice.o + 0x711 (size before relaxing) + .debug_str 0x0000688c 0x115 Bin/MIDIClassDevice.o + 0x60c (size before relaxing) + .debug_str 0x000069a1 0x269 Bin/PrinterClassDevice.o + 0x84c (size before relaxing) + .debug_str 0x00006c0a 0x6e5 Bin/RNDISClassDevice.o + 0xc5f (size before relaxing) + .debug_str 0x000072ef 0x3b Bin/AndroidAccessoryClassHost.o + 0x115 (size before relaxing) + .debug_str 0x0000732a 0x30 Bin/AudioClassHost.o + 0x10a (size before relaxing) + .debug_str 0x0000735a 0x2e Bin/CDCClassHost.o + 0x108 (size before relaxing) + .debug_str 0x00007388 0x2e Bin/HIDClassHost.o + 0x108 (size before relaxing) + .debug_str 0x000073b6 0x36 Bin/MassStorageClassHost.o + 0x110 (size before relaxing) + .debug_str 0x000073ec 0x2f Bin/MIDIClassHost.o + 0x109 (size before relaxing) + .debug_str 0x0000741b 0x32 Bin/PrinterClassHost.o + 0x10c (size before relaxing) + .debug_str 0x0000744d 0x30 Bin/RNDISClassHost.o + 0x10a (size before relaxing) + .debug_str 0x0000747d 0x35 Bin/StillImageClassHost.o + 0x10f (size before relaxing) + .debug_str 0x000074b2 0x6f c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + 0xa8 (size before relaxing) + .debug_str 0x00007521 0x88 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + 0x12e (size before relaxing) + .debug_str 0x000075a9 0x9d c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + 0x16b (size before relaxing) + .debug_str 0x00007646 0x56 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + 0xfb (size before relaxing) + +.debug_loc 0x00000000 0xb6e8 + *(.debug_loc) + .debug_loc 0x00000000 0x225 Bin/LUFADescriptors.o + .debug_loc 0x00000225 0x2f Bin/System.o + .debug_loc 0x00000254 0x2a8 Bin/Configuration.o + .debug_loc 0x000004fc 0xc4 Bin/Random.o + .debug_loc 0x000005c0 0x2fa Bin/Common.o + .debug_loc 0x000008ba 0x8a1 Bin/Memory.o + .debug_loc 0x0000115b 0x6c6 Bin/Button.o + .debug_loc 0x00001821 0x185 Bin/Settings.o + .debug_loc 0x000019a6 0x1dc Bin/Terminal.o + .debug_loc 0x00001b82 0x5cc Bin/Commands.o + .debug_loc 0x0000214e 0x226 Bin/XModem.o + .debug_loc 0x00002374 0x628 Bin/CommandLine.o + .debug_loc 0x0000299c 0x437 Bin/ISO14443-2A.o + .debug_loc 0x00002dd3 0xa90 Bin/MifareClassic.o + .debug_loc 0x00003863 0x309 Bin/ISO14443-3A.o + .debug_loc 0x00003b6c 0x960 Bin/Crypto1.o + .debug_loc 0x000044cc 0xced Bin/HIDParser.o + .debug_loc 0x000051b9 0x4e4 Bin/ConfigDescriptors.o + .debug_loc 0x0000569d 0x294 Bin/DeviceStandardReq.o + .debug_loc 0x00005931 0x22 Bin/USBTask.o + .debug_loc 0x00005953 0x279d Bin/EndpointStream_XMEGA.o + .debug_loc 0x000080f0 0x50b Bin/Endpoint_XMEGA.o + .debug_loc 0x000085fb 0xa3 Bin/USBController_XMEGA.o + .debug_loc 0x0000869e 0x200 Bin/USBInterrupt_XMEGA.o + .debug_loc 0x0000889e 0x2c6 Bin/AudioClassDevice.o + .debug_loc 0x00008b64 0x7e8 Bin/CDCClassDevice.o + .debug_loc 0x0000934c 0x49d Bin/HIDClassDevice.o + .debug_loc 0x000097e9 0x283 Bin/MassStorageClassDevice.o + .debug_loc 0x00009a6c 0x27c Bin/MIDIClassDevice.o + .debug_loc 0x00009ce8 0x6cd Bin/PrinterClassDevice.o + .debug_loc 0x0000a3b5 0xbd5 Bin/RNDISClassDevice.o + .debug_loc 0x0000af8a 0x167 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_loc 0x0000b0f1 0x63 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_loc 0x0000b154 0x4fb c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_loc 0x0000b64f 0x99 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +.debug_macinfo + *(.debug_macinfo) +OUTPUT(Chameleon-Mini.elf elf32-avr) +LOAD linker stubs + +.debug_ranges 0x00000000 0x1ae0 + .debug_ranges 0x00000000 0x40 Bin/Chameleon-Mini.o + .debug_ranges 0x00000040 0x10 Bin/LUFADescriptors.o + .debug_ranges 0x00000050 0x40 Bin/System.o + .debug_ranges 0x00000090 0xb8 Bin/Configuration.o + .debug_ranges 0x00000148 0x28 Bin/Random.o + .debug_ranges 0x00000170 0x50 Bin/Common.o + .debug_ranges 0x000001c0 0x208 Bin/Memory.o + .debug_ranges 0x000003c8 0xf8 Bin/Button.o + .debug_ranges 0x000004c0 0x40 Bin/Settings.o + .debug_ranges 0x00000500 0xc8 Bin/Terminal.o + .debug_ranges 0x000005c8 0x128 Bin/Commands.o + .debug_ranges 0x000006f0 0x30 Bin/XModem.o + .debug_ranges 0x00000720 0x150 Bin/CommandLine.o + .debug_ranges 0x00000870 0xb8 Bin/ISO14443-2A.o + .debug_ranges 0x00000928 0x1b0 Bin/MifareClassic.o + .debug_ranges 0x00000ad8 0x18 Bin/ISO14443-3A.o + .debug_ranges 0x00000af0 0x88 Bin/Crypto1.o + .debug_ranges 0x00000b78 0x120 Bin/HIDParser.o + .debug_ranges 0x00000c98 0x40 Bin/ConfigDescriptors.o + .debug_ranges 0x00000cd8 0x1d8 Bin/DeviceStandardReq.o + .debug_ranges 0x00000eb0 0x10 Bin/Events.o + .debug_ranges 0x00000ec0 0x50 Bin/USBTask.o + .debug_ranges 0x00000f10 0x10 Bin/Device_XMEGA.o + .debug_ranges 0x00000f20 0x5d8 Bin/EndpointStream_XMEGA.o + .debug_ranges 0x000014f8 0x110 Bin/Endpoint_XMEGA.o + .debug_ranges 0x00001608 0x20 Bin/USBController_XMEGA.o + .debug_ranges 0x00001628 0x20 Bin/USBInterrupt_XMEGA.o + .debug_ranges 0x00001648 0x38 Bin/AudioClassDevice.o + .debug_ranges 0x00001680 0x100 Bin/CDCClassDevice.o + .debug_ranges 0x00001780 0x38 Bin/HIDClassDevice.o + .debug_ranges 0x000017b8 0x98 Bin/MassStorageClassDevice.o + .debug_ranges 0x00001850 0x48 Bin/MIDIClassDevice.o + .debug_ranges 0x00001898 0x128 Bin/PrinterClassDevice.o + .debug_ranges 0x000019c0 0xc8 Bin/RNDISClassDevice.o + .debug_ranges 0x00001a88 0x28 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + .debug_ranges 0x00001ab0 0x10 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + .debug_ranges 0x00001ac0 0x10 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + .debug_ranges 0x00001ad0 0x10 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + +Cross Reference Table + +Symbol File +ActiveConfiguration Bin/MifareClassic.o + Bin/ISO14443-2A.o + Bin/Commands.o + Bin/Button.o + Bin/Configuration.o + Bin/Chameleon-Mini.o +Audio_Device_ConfigureEndpoints Bin/AudioClassDevice.o +Audio_Device_Event_Stub Bin/AudioClassDevice.o +Audio_Device_ProcessControlRequest Bin/AudioClassDevice.o +BufferToHexString Bin/Common.o + Bin/Commands.o +ButtonGetActionByName Bin/Button.o + Bin/Commands.o +ButtonGetActionList Bin/Button.o + Bin/Commands.o +ButtonInit Bin/Button.o + Bin/Chameleon-Mini.o +ButtonSetActionById Bin/Button.o +ButtonSetActionByName Bin/Button.o + Bin/Commands.o +ButtonTick Bin/Button.o + Bin/Chameleon-Mini.o +CALLBACK_Audio_Device_GetSetEndpointProperty Bin/AudioClassDevice.o +CALLBACK_Audio_Device_GetSetInterfaceProperty Bin/AudioClassDevice.o +CALLBACK_HIDParser_FilterHIDReportItem Bin/HIDParser.o +CALLBACK_HID_Device_CreateHIDReport Bin/HIDClassDevice.o +CALLBACK_HID_Device_ProcessHIDReport Bin/HIDClassDevice.o +CALLBACK_MS_Device_SCSICommandReceived Bin/MassStorageClassDevice.o +CALLBACK_USB_GetDescriptor Bin/LUFADescriptors.o + Bin/DeviceStandardReq.o +CDC_Device_BytesReceived Bin/CDCClassDevice.o +CDC_Device_ConfigureEndpoints Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_CreateBlockingStream Bin/CDCClassDevice.o +CDC_Device_CreateStream Bin/CDCClassDevice.o +CDC_Device_Event_Stub Bin/CDCClassDevice.o +CDC_Device_Flush Bin/CDCClassDevice.o +CDC_Device_ProcessControlRequest Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_ReceiveByte Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_SendByte Bin/CDCClassDevice.o + Bin/XModem.o + Bin/Terminal.o +CDC_Device_SendControlLineStateChange Bin/CDCClassDevice.o +CDC_Device_SendData Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_SendString Bin/CDCClassDevice.o + Bin/Terminal.o +CDC_Device_USBTask Bin/CDCClassDevice.o + Bin/Terminal.o +CodecBuffer Bin/ISO14443-2A.o + Bin/Codec.o +CommandExecButton Bin/Commands.o + Bin/CommandLine.o +CommandExecClear Bin/Commands.o + Bin/CommandLine.o +CommandExecConfig Bin/Commands.o + Bin/CommandLine.o +CommandExecDownload Bin/Commands.o + Bin/CommandLine.o +CommandExecHelp Bin/Commands.o + Bin/CommandLine.o +CommandExecReset Bin/Commands.o + Bin/CommandLine.o +CommandExecUpgrade Bin/Commands.o + Bin/CommandLine.o +CommandExecUpload Bin/Commands.o + Bin/CommandLine.o +CommandGetButton Bin/Commands.o + Bin/CommandLine.o +CommandGetConfig Bin/Commands.o + Bin/CommandLine.o +CommandGetMemSize Bin/Commands.o + Bin/CommandLine.o +CommandGetReadOnly Bin/Commands.o + Bin/CommandLine.o +CommandGetRssi Bin/Commands.o + Bin/CommandLine.o +CommandGetSetting Bin/Commands.o + Bin/CommandLine.o +CommandGetUid Bin/Commands.o + Bin/CommandLine.o +CommandGetUidSize Bin/Commands.o + Bin/CommandLine.o +CommandGetVersion Bin/Commands.o + Bin/CommandLine.o +CommandLineInit Bin/CommandLine.o +CommandLineProcessByte Bin/CommandLine.o + Bin/Terminal.o +CommandLineTick Bin/CommandLine.o + Bin/Terminal.o +CommandSetButton Bin/Commands.o + Bin/CommandLine.o +CommandSetConfig Bin/Commands.o + Bin/CommandLine.o +CommandSetReadOnly Bin/Commands.o + Bin/CommandLine.o +CommandSetSetting Bin/Commands.o + Bin/CommandLine.o +CommandSetUid Bin/Commands.o + Bin/CommandLine.o +CommandTable Bin/CommandLine.o + Bin/Commands.o +ConfigurationDescriptor Bin/LUFADescriptors.o +ConfigurationGetList Bin/Configuration.o + Bin/Commands.o +ConfigurationInit Bin/Configuration.o + Bin/Settings.o + Bin/Chameleon-Mini.o +ConfigurationSetById Bin/Configuration.o +ConfigurationSetByName Bin/Configuration.o + Bin/Commands.o +Crypto1Auth Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Byte Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1FilterOutput Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Nibble Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1PRNG Bin/Crypto1.o + Bin/MifareClassic.o +Crypto1Setup Bin/Crypto1.o + Bin/MifareClassic.o +DeviceDescriptor Bin/LUFADescriptors.o +EVENT_Audio_Device_StreamStartStop Bin/AudioClassDevice.o +EVENT_CDC_Device_BreakSent Bin/CDCClassDevice.o +EVENT_CDC_Device_ControLineStateChanged Bin/CDCClassDevice.o +EVENT_CDC_Device_LineEncodingChanged Bin/CDCClassDevice.o +EVENT_PRNT_Device_SoftReset Bin/PrinterClassDevice.o +EVENT_USB_Device_ConfigurationChanged Bin/Terminal.o + Bin/DeviceStandardReq.o +EVENT_USB_Device_Connect Bin/Terminal.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_ControlRequest Bin/Terminal.o + Bin/DeviceStandardReq.o +EVENT_USB_Device_Disconnect Bin/Terminal.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_Reset Bin/Events.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_StartOfFrame Bin/Events.o + Bin/USBInterrupt_XMEGA.o +EVENT_USB_Device_Suspend Bin/Events.o +EVENT_USB_Device_WakeUp Bin/Events.o +Endpoint_ClearEndpoints Bin/Endpoint_XMEGA.o + Bin/USBInterrupt_XMEGA.o +Endpoint_ClearIN Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_ClearOUT Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_ClearSETUP Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_ClearStatusStage Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_ConfigureEndpointTable Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o +Endpoint_ConfigureEndpoint_PRV Bin/Endpoint_XMEGA.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +Endpoint_Discard_Stream Bin/EndpointStream_XMEGA.o +Endpoint_IsINReady Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_IsOUTReceived Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o +Endpoint_IsSETUPReceived Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +Endpoint_Null_Stream Bin/EndpointStream_XMEGA.o +Endpoint_Read_8 Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Read_Control_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Control_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/HIDClassDevice.o + Bin/AudioClassDevice.o +Endpoint_Read_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Read_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o +Endpoint_SelectEndpoint Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +Endpoint_StallTransaction Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/MassStorageClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_WaitUntilReady Bin/Endpoint_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o +Endpoint_Write_8 Bin/Endpoint_XMEGA.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Write_Control_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_PStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_PStream_LE Bin/EndpointStream_XMEGA.o + Bin/DeviceStandardReq.o +Endpoint_Write_Control_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Control_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/HIDClassDevice.o + Bin/AudioClassDevice.o + Bin/DeviceStandardReq.o +Endpoint_Write_EStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_EStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_PStream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_PStream_LE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Stream_BE Bin/EndpointStream_XMEGA.o +Endpoint_Write_Stream_LE Bin/EndpointStream_XMEGA.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o +GlobalSettings Bin/Settings.o + Bin/Button.o + Bin/Memory.o + Bin/Configuration.o +HID_Device_ConfigureEndpoints Bin/HIDClassDevice.o +HID_Device_ProcessControlRequest Bin/HIDClassDevice.o +HID_Device_USBTask Bin/HIDClassDevice.o +HexStringToBuffer Bin/Common.o + Bin/Commands.o +ISO14443AAppendCRCA Bin/ISO14443-3A.o + Bin/MifareClassic.o +ISO14443ACheckCRCA Bin/ISO14443-3A.o + Bin/MifareClassic.o +ISO14443ACodecInit Bin/ISO14443-2A.o + Bin/Configuration.o +ISO14443ACodecTask Bin/ISO14443-2A.o + Bin/Configuration.o +LEDPulseMask Bin/LED.o + Bin/Terminal.o + Bin/Chameleon-Mini.o +LanguageString Bin/LUFADescriptors.o +MIDI_Device_ConfigureEndpoints Bin/MIDIClassDevice.o +MIDI_Device_Flush Bin/MIDIClassDevice.o +MIDI_Device_ReceiveEventPacket Bin/MIDIClassDevice.o +MIDI_Device_SendEventPacket Bin/MIDIClassDevice.o +MIDI_Device_USBTask Bin/MIDIClassDevice.o +MS_Device_ConfigureEndpoints Bin/MassStorageClassDevice.o +MS_Device_ProcessControlRequest Bin/MassStorageClassDevice.o +MS_Device_USBTask Bin/MassStorageClassDevice.o +ManufacturerString Bin/LUFADescriptors.o +MemoryClear Bin/Memory.o + Bin/Commands.o +MemoryDownloadBlock Bin/Memory.o + Bin/Commands.o +MemoryInit Bin/Memory.o + Bin/Chameleon-Mini.o +MemoryReadBlock Bin/Memory.o + Bin/MifareClassic.o +MemoryUploadBlock Bin/Memory.o + Bin/Commands.o +MemoryWriteBlock Bin/Memory.o + Bin/MifareClassic.o +MifareClassicAppInit1K Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppInit4K Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppProcess Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppReset Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicAppTask Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicGetUid Bin/MifareClassic.o + Bin/Configuration.o +MifareClassicSetUid Bin/MifareClassic.o + Bin/Configuration.o +PRNT_Device_BytesReceived Bin/PrinterClassDevice.o +PRNT_Device_ConfigureEndpoints Bin/PrinterClassDevice.o +PRNT_Device_CreateBlockingStream Bin/PrinterClassDevice.o +PRNT_Device_CreateStream Bin/PrinterClassDevice.o +PRNT_Device_Event_Stub Bin/PrinterClassDevice.o +PRNT_Device_Flush Bin/PrinterClassDevice.o +PRNT_Device_ProcessControlRequest Bin/PrinterClassDevice.o +PRNT_Device_ReceiveByte Bin/PrinterClassDevice.o +PRNT_Device_SendByte Bin/PrinterClassDevice.o +PRNT_Device_SendData Bin/PrinterClassDevice.o +PRNT_Device_SendString Bin/PrinterClassDevice.o +PRNT_Device_USBTask Bin/PrinterClassDevice.o +ProductString Bin/LUFADescriptors.o +RNDIS_Device_ConfigureEndpoints Bin/RNDISClassDevice.o +RNDIS_Device_IsPacketReceived Bin/RNDISClassDevice.o +RNDIS_Device_ProcessControlRequest Bin/RNDISClassDevice.o +RNDIS_Device_ReadPacket Bin/RNDISClassDevice.o +RNDIS_Device_SendPacket Bin/RNDISClassDevice.o +RNDIS_Device_USBTask Bin/RNDISClassDevice.o +RandomGetBuffer Bin/Random.o + Bin/MifareClassic.o +RandomGetByte Bin/Random.o + Bin/Commands.o + Bin/Button.o +RandomInit Bin/Random.o + Bin/Chameleon-Mini.o +RandomTick Bin/Random.o + Bin/Chameleon-Mini.o +SettingsCycle Bin/Settings.o + Bin/Button.o +SettingsGetActiveById Bin/Settings.o +SettingsGetActiveByName Bin/Settings.o + Bin/Commands.o +SettingsLoad Bin/Settings.o + Bin/Chameleon-Mini.o +SettingsSave Bin/Settings.o + Bin/Commands.o +SettingsSetActiveById Bin/Settings.o +SettingsSetActiveByName Bin/Settings.o + Bin/Commands.o +StoredSettings Bin/Settings.o +SystemEnterBootloader Bin/System.o + Bin/Commands.o +SystemInit Bin/System.o + Bin/Chameleon-Mini.o +SystemInterruptInit Bin/System.o + Bin/Chameleon-Mini.o +SystemReset Bin/System.o + Bin/Commands.o +SystemStartUSBClock Bin/System.o + Bin/Terminal.o +SystemStopUSBClock Bin/System.o + Bin/Terminal.o +TerminalBuffer Bin/CommandLine.o + Bin/XModem.o + Bin/Terminal.o +TerminalHandle Bin/Terminal.o + Bin/XModem.o +TerminalInit Bin/Terminal.o + Bin/Chameleon-Mini.o +TerminalSendBlock Bin/Terminal.o + Bin/XModem.o +TerminalSendString Bin/Terminal.o + Bin/CommandLine.o +TerminalSendStringP Bin/Terminal.o + Bin/CommandLine.o +TerminalState Bin/Terminal.o +TerminalTask Bin/Terminal.o + Bin/Chameleon-Mini.o +TerminalTick Bin/Terminal.o + Bin/Chameleon-Mini.o +USB_ControlRequest Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +USB_DeviceState Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o + Bin/DeviceStandardReq.o +USB_Device_ConfigurationNumber Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_CurrentlySelfPowered Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_ProcessControlRequest Bin/DeviceStandardReq.o + Bin/USBTask.o +USB_Device_RemoteWakeupEnabled Bin/USBController_XMEGA.o + Bin/DeviceStandardReq.o +USB_Device_SendRemoteWakeup Bin/Device_XMEGA.o +USB_Disable Bin/USBController_XMEGA.o + Bin/Commands.o + Bin/Terminal.o +USB_EndpointTable Bin/USBController_XMEGA.o +USB_Endpoint_FIFOs Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/DeviceStandardReq.o +USB_Endpoint_SelectedEndpoint Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/CDCClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/USBTask.o +USB_Endpoint_SelectedFIFO Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o +USB_Endpoint_SelectedHandle Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/Endpoint_XMEGA.o + Bin/DeviceStandardReq.o +USB_Event_Stub Bin/Events.o +USB_GetHIDReportItemInfo Bin/HIDParser.o +USB_GetHIDReportSize Bin/HIDParser.o +USB_GetNextDescriptorComp Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfType Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfTypeAfter Bin/ConfigDescriptors.o +USB_GetNextDescriptorOfTypeBefore Bin/ConfigDescriptors.o +USB_INT_ClearAllInterrupts Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +USB_INT_DisableAllInterrupts Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o +USB_Init Bin/USBController_XMEGA.o + Bin/Terminal.o +USB_IsInitialized Bin/USBController_XMEGA.o + Bin/USBTask.o +USB_ProcessHIDReport Bin/HIDParser.o +USB_ResetInterface Bin/USBController_XMEGA.o +USB_SetHIDReportItemInfo Bin/HIDParser.o +USB_USBTask Bin/USBTask.o + Bin/PrinterClassDevice.o + Bin/MassStorageClassDevice.o + Bin/CDCClassDevice.o + Bin/EndpointStream_XMEGA.o + Bin/Terminal.o +XModemProcessByte Bin/XModem.o + Bin/Terminal.o +XModemReceive Bin/XModem.o + Bin/Commands.o +XModemSend Bin/XModem.o + Bin/Commands.o +XModemTick Bin/XModem.o + Bin/Terminal.o +__bad_interrupt c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__bss_end c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) +__bss_start c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) +__data_end c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) +__data_load_start c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) +__data_start c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) +__divmodsi4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +__do_clear_bss c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_clear_bss.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/StillImageClassHost.o + Bin/RNDISClassHost.o + Bin/PrinterClassHost.o + Bin/MIDIClassHost.o + Bin/MassStorageClassHost.o + Bin/HIDClassHost.o + Bin/CDCClassHost.o + Bin/AudioClassHost.o + Bin/AndroidAccessoryClassHost.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/Pipe_XMEGA.o + Bin/PipeStream_XMEGA.o + Bin/Host_XMEGA.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/Device_XMEGA.o + Bin/USBTask.o + Bin/HostStandardReq.o + Bin/Events.o + Bin/DeviceStandardReq.o + Bin/ConfigDescriptors.o + Bin/HIDParser.o + Bin/Crypto1.o + Bin/ISO14443-3A.o + Bin/MifareClassic.o + Bin/ISO14443-2A.o + Bin/Codec.o + Bin/CommandLine.o + Bin/XModem.o + Bin/Commands.o + Bin/Terminal.o + Bin/LED.o + Bin/Settings.o + Bin/Button.o + Bin/Memory.o + Bin/Common.o + Bin/Random.o + Bin/Configuration.o + Bin/System.o + Bin/LUFADescriptors.o + Bin/Chameleon-Mini.o +__do_copy_data c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_copy_data.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/StillImageClassHost.o + Bin/RNDISClassHost.o + Bin/PrinterClassHost.o + Bin/MIDIClassHost.o + Bin/MassStorageClassHost.o + Bin/HIDClassHost.o + Bin/CDCClassHost.o + Bin/AudioClassHost.o + Bin/AndroidAccessoryClassHost.o + Bin/RNDISClassDevice.o + Bin/PrinterClassDevice.o + Bin/MIDIClassDevice.o + Bin/MassStorageClassDevice.o + Bin/HIDClassDevice.o + Bin/CDCClassDevice.o + Bin/AudioClassDevice.o + Bin/USBInterrupt_XMEGA.o + Bin/USBController_XMEGA.o + Bin/Pipe_XMEGA.o + Bin/PipeStream_XMEGA.o + Bin/Host_XMEGA.o + Bin/Endpoint_XMEGA.o + Bin/EndpointStream_XMEGA.o + Bin/Device_XMEGA.o + Bin/USBTask.o + Bin/HostStandardReq.o + Bin/Events.o + Bin/DeviceStandardReq.o + Bin/ConfigDescriptors.o + Bin/HIDParser.o + Bin/Crypto1.o + Bin/ISO14443-3A.o + Bin/MifareClassic.o + Bin/ISO14443-2A.o + Bin/Codec.o + Bin/CommandLine.o + Bin/XModem.o + Bin/Commands.o + Bin/Terminal.o + Bin/LED.o + Bin/Settings.o + Bin/Button.o + Bin/Memory.o + Bin/Common.o + Bin/Random.o + Bin/Configuration.o + Bin/System.o + Bin/LUFADescriptors.o + Bin/Chameleon-Mini.o +__eerd_block_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/Settings.o +__eerd_byte_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o +__eeupd_byte_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) + Bin/EndpointStream_XMEGA.o +__eeupd_r18_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +__eewr_block_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + Bin/Settings.o +__eewr_byte_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) +__eewr_r18_x32a4u c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_byte_atxmega32a4u.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eewr_block_atxmega32a4u.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +__epilogue_restores__ c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_epilogue.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) +__heap_end c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__init c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__mulsi3 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_mulsi3.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/Commands.o +__prologue_saves__ c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_prologue.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) +__stack c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__udivmodsi4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_udivmodsi4.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_divmodsi4.o) +__ultoa_invert c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(ultoa_invert.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +__vector_1 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_10 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_100 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_101 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_102 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_103 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_104 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_105 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_106 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_107 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_108 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_109 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_11 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_110 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_111 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_112 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_113 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_114 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_115 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_116 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_117 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_118 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_119 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_12 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_120 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_121 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_122 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_123 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_124 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_125 Bin/USBInterrupt_XMEGA.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_126 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_13 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_14 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_15 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_16 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_17 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_18 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_19 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_2 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_20 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_21 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_22 Bin/ISO14443-2A.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_23 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_24 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_25 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_26 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_27 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_28 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_29 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_3 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_30 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_31 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_32 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_33 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_34 Bin/ISO14443-2A.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_35 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_36 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_37 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_38 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_39 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_4 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_40 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_41 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_42 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_43 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_44 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_45 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_46 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_47 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_48 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_49 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_5 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_50 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_51 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_52 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_53 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_54 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_55 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_56 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_57 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_58 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_59 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_6 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_60 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_61 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_62 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_63 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_64 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_65 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_66 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_67 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_68 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_69 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_7 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_70 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_71 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_72 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_73 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_74 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_75 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_76 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_77 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_78 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_79 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_8 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_80 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_81 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_82 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_83 Bin/ISO14443-2A.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_84 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_85 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_86 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_87 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_88 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_89 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_9 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_90 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_91 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_92 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_93 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_94 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_95 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_96 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_97 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_98 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_99 c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vector_default Bin/System.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +__vectors c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +_exit c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) +eeprom_mapen c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_byte_atxmega32a4u.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eeupd_byte_atxmega32a4u.o) +exit c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/avrxmega2\libgcc.a(_exit.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +fputc c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(fputc.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +main Bin/Chameleon-Mini.o + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2/crtx32a4u.o +memcmp c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcmp.o) + Bin/HIDClassDevice.o +memcpy c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(eerd_block_atxmega32a4u.o) + Bin/RNDISClassDevice.o + Bin/HIDClassDevice.o +memcpy_P c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memcpy_P.o) + Bin/RNDISClassDevice.o + Bin/Configuration.o +memset c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(memset.o) + Bin/HIDClassDevice.o +rand c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) + Bin/Random.o +rand_r c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +snprintf_P c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) + Bin/Commands.o +srand c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(rand.o) +strcmp_P c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strcmp_P.o) + Bin/CommandLine.o + Bin/Commands.o + Bin/Button.o +strncpy_P c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strncpy_P.o) + Bin/Button.o +strnlen c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +strnlen_P c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(strnlen_P.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) +vfprintf c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(vfprintf_std.o) + c:/programme/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.6.2/../../../../avr/lib/avrxmega2\libc.a(snprintf_p.o) diff --git a/Firmware/Chameleon-Mini/Chameleon-Mini.sym b/Firmware/Chameleon-Mini/Chameleon-Mini.sym new file mode 100644 index 00000000..a97b4e78 --- /dev/null +++ b/Firmware/Chameleon-Mini/Chameleon-Mini.sym @@ -0,0 +1,726 @@ + U CALLBACK_Audio_Device_GetSetEndpointProperty + U CALLBACK_Audio_Device_GetSetInterfaceProperty + U CALLBACK_HIDParser_FilterHIDReportItem + U CALLBACK_HID_Device_CreateHIDReport + U CALLBACK_HID_Device_ProcessHIDReport + U CALLBACK_MS_Device_SCSICommandReceived +00000000 W __heap_end +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 a __tmp_reg__ +00000000 T __vectors +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000001 a __zero_reg__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +00000034 a __CCP__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003d a __SP_L__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003e a __SP_H__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +0000003f a __SREG__ +000001fc T ProductString +0000021a T ManufacturerString +00000234 T LanguageString +00000238 T ConfigurationDescriptor +00000276 T DeviceDescriptor +00000288 t ConfigurationTable +000002f7 t ButtonActionTable +000003b7 t __c.6198 +000003f0 t __c.6200 +000003f7 t __c.6202 +000003fe t __c.6204 +00000404 t __c.6209 +00000407 t __c.6227 +0000040e t __c.6254 +00000411 t __c.6259 +00000414 t __c.6298 +0000041b T CommandTable +0000057b t __c.5994 +0000057e t __c.5996 +00000581 t StatusTable +00000648 T __ctors_end +00000648 T __ctors_start +00000648 T __dtors_end +00000648 T __dtors_start +00000648 W __init +00000648 T __trampolines_end +00000648 T __trampolines_start +00000654 T __do_copy_data +0000066a T __do_clear_bss +00000672 t .do_clear_bss_loop +00000674 t .do_clear_bss_start +00000680 T __bad_interrupt +00000680 W __vector_1 +00000680 W __vector_10 +00000680 W __vector_100 +00000680 W __vector_101 +00000680 W __vector_102 +00000680 W __vector_103 +00000680 W __vector_104 +00000680 W __vector_105 +00000680 W __vector_106 +00000680 W __vector_107 +00000680 W __vector_108 +00000680 W __vector_109 +00000680 W __vector_11 +00000680 W __vector_110 +00000680 W __vector_111 +00000680 W __vector_112 +00000680 W __vector_113 +00000680 W __vector_114 +00000680 W __vector_115 +00000680 W __vector_116 +00000680 W __vector_117 +00000680 W __vector_118 +00000680 W __vector_119 +00000680 W __vector_12 +00000680 W __vector_120 +00000680 W __vector_121 +00000680 W __vector_122 +00000680 W __vector_123 +00000680 W __vector_124 +00000680 W __vector_126 +00000680 W __vector_13 +00000680 W __vector_14 +00000680 W __vector_15 +00000680 W __vector_16 +00000680 W __vector_17 +00000680 W __vector_18 +00000680 W __vector_19 +00000680 W __vector_2 +00000680 W __vector_20 +00000680 W __vector_21 +00000680 W __vector_23 +00000680 W __vector_24 +00000680 W __vector_25 +00000680 W __vector_26 +00000680 W __vector_27 +00000680 W __vector_28 +00000680 W __vector_29 +00000680 W __vector_3 +00000680 W __vector_30 +00000680 W __vector_31 +00000680 W __vector_32 +00000680 W __vector_33 +00000680 W __vector_35 +00000680 W __vector_36 +00000680 W __vector_37 +00000680 W __vector_38 +00000680 W __vector_39 +00000680 W __vector_4 +00000680 W __vector_40 +00000680 W __vector_41 +00000680 W __vector_42 +00000680 W __vector_43 +00000680 W __vector_44 +00000680 W __vector_45 +00000680 W __vector_46 +00000680 W __vector_47 +00000680 W __vector_48 +00000680 W __vector_49 +00000680 W __vector_5 +00000680 W __vector_50 +00000680 W __vector_51 +00000680 W __vector_52 +00000680 W __vector_53 +00000680 W __vector_54 +00000680 W __vector_55 +00000680 W __vector_56 +00000680 W __vector_57 +00000680 W __vector_58 +00000680 W __vector_59 +00000680 W __vector_6 +00000680 W __vector_60 +00000680 W __vector_61 +00000680 W __vector_62 +00000680 W __vector_63 +00000680 W __vector_64 +00000680 W __vector_65 +00000680 W __vector_66 +00000680 W __vector_67 +00000680 W __vector_68 +00000680 W __vector_69 +00000680 W __vector_7 +00000680 W __vector_70 +00000680 W __vector_71 +00000680 W __vector_72 +00000680 W __vector_73 +00000680 W __vector_74 +00000680 W __vector_75 +00000680 W __vector_76 +00000680 W __vector_77 +00000680 W __vector_78 +00000680 W __vector_79 +00000680 W __vector_8 +00000680 W __vector_80 +00000680 W __vector_81 +00000680 W __vector_82 +00000680 W __vector_84 +00000680 W __vector_85 +00000680 W __vector_86 +00000680 W __vector_87 +00000680 W __vector_88 +00000680 W __vector_89 +00000680 W __vector_9 +00000680 W __vector_90 +00000680 W __vector_91 +00000680 W __vector_92 +00000680 W __vector_93 +00000680 W __vector_94 +00000680 W __vector_95 +00000680 W __vector_96 +00000680 W __vector_97 +00000680 W __vector_98 +00000680 W __vector_99 +00000682 T main +000006f4 T CALLBACK_USB_GetDescriptor +00000760 T __vector_default +0000076c T SystemInit +000007e0 T SystemReset +000007ee T SystemEnterBootloader +000007fa T SystemStartUSBClock +00000830 T SystemStopUSBClock +0000084c T SystemInterruptInit +00000858 t CodecInitDummy +0000085a t CodecTaskDummy +0000085c t ApplicationInitDummy +0000085e t ApplicationResetDummy +00000860 t ApplicationTaskDummy +00000862 t ApplicationProcessDummy +00000868 t ApplicationGetUidDummy +0000086a t ApplicationSetUidDummy +0000086c T ConfigurationSetById +000008be T ConfigurationInit +000008ca T ConfigurationSetByName +0000095a T ConfigurationGetList +000009ce T RandomInit +000009d0 T RandomGetByte +000009d6 T RandomGetBuffer +00000a04 T RandomTick +00000a14 T BufferToHexString +00000a8e T HexStringToBuffer +00000b2c T MemoryInit +00000c3a T MemoryReadBlock +00000d50 T MemoryWriteBlock +00000ff8 T MemoryClear +000010c4 T MemoryUploadBlock +00001120 T MemoryDownloadBlock +0000117e T ButtonInit +0000118c T ButtonTick +00001346 T ButtonGetActionList +000013a6 T ButtonSetActionById +000013b2 T ButtonGetActionByName +000013d8 T ButtonSetActionByName +0000146a T SettingsLoad +0000147a T SettingsSave +0000148a T SettingsSetActiveById +000014a8 T SettingsCycle +00001582 T SettingsGetActiveById +00001588 T SettingsGetActiveByName +0000159c T SettingsSetActiveByName +000015ba T TerminalSendString +000015c4 T TerminalSendStringP +000015ec T TerminalSendBlock +000015fa T TerminalInit +00001604 T TerminalTask +00001646 T TerminalTick +000016c4 T EVENT_USB_Device_Connect +000016ce T EVENT_USB_Device_Disconnect +000016d8 T EVENT_USB_Device_ConfigurationChanged +000016e0 T EVENT_USB_Device_ControlRequest +000016e8 T CommandGetVersion +00001742 T CommandGetConfig +0000178c T CommandSetConfig +0000179c T CommandExecConfig +000017a6 T CommandGetUid +000017f2 T CommandSetUid +0000189a T CommandGetReadOnly +000018b8 T CommandSetReadOnly +000018e4 T CommandExecUpload +000018ee T CommandExecDownload +000018f8 T CommandExecReset +0000190e T CommandExecUpgrade +00001924 T CommandGetMemSize +00001972 T CommandGetUidSize +000019bc T CommandExecButton +000019c6 T CommandGetButton +000019d0 T CommandSetButton +000019e0 T CommandGetSetting +000019ea T CommandSetSetting +000019fa T CommandExecClear +00001a00 T CommandExecHelp +00001a9a T CommandGetRssi +00001b2e t CalcChecksum.constprop.0 +00001b42 T XModemReceive +00001b72 T XModemSend +00001b98 T XModemProcessByte +00001e4a T XModemTick +00001ea6 T CommandLineProcessByte +000021ec T CommandLineTick +000021ee t StartDemod +0000222c T __vector_34 +000022b4 T __vector_22 +000023fc T __vector_83 +0000260e T ISO14443ACodecInit +0000267e T ISO14443ACodecTask +00002770 T MifareClassicAppInit1K +0000278a T MifareClassicAppInit4K +000027a4 T MifareClassicAppReset +000027ac T MifareClassicAppTask +000027ae T MifareClassicAppProcess +00002fff W __stack +0000316a T MifareClassicGetUid +00003176 T MifareClassicSetUid +000031b8 T ISO14443AAppendCRCA +00003234 T ISO14443ACheckCRCA +000032d0 t Crypto1LFSR +0000339e T Crypto1FilterOutput +00003406 T Crypto1Setup +00003792 T Crypto1Auth +00003810 T Crypto1Byte +00003892 T Crypto1Nibble +000038da T Crypto1PRNG +000039d6 T USB_Device_ProcessControlRequest +00003c86 W EVENT_USB_Device_Reset +00003c86 W EVENT_USB_Device_StartOfFrame +00003c86 W EVENT_USB_Device_Suspend +00003c86 W EVENT_USB_Device_WakeUp +00003c86 T USB_Event_Stub +00003c88 T USB_USBTask +00003cb0 T Endpoint_Write_Stream_LE +00003d88 T Endpoint_Write_Control_Stream_LE +00003ed2 T Endpoint_Write_Control_PStream_LE +00004032 T Endpoint_ClearIN +00004064 T Endpoint_ClearOUT +00004082 T Endpoint_Read_8 +000040a0 T Endpoint_Write_8 +000040be T Endpoint_SelectEndpoint +00004136 T Endpoint_StallTransaction +0000416e T Endpoint_ClearSETUP +000041c6 T Endpoint_IsSETUPReceived +000041f6 T Endpoint_IsOUTReceived +00004226 T Endpoint_IsINReady +00004240 T Endpoint_ConfigureEndpoint_PRV +000042da T Endpoint_ConfigureEndpointTable +000043b2 T Endpoint_ClearEndpoints +00004422 T Endpoint_ClearStatusStage +0000444e T Endpoint_WaitUntilReady +000044f0 T USB_Disable +0000450a T USB_ResetInterface +00004566 T USB_Init +000045ba T USB_INT_DisableAllInterrupts +000045c8 T USB_INT_ClearAllInterrupts +000045d4 T __vector_125 +000046b4 T CDC_Device_ProcessControlRequest +0000480a T CDC_Device_ConfigureEndpoints +00004856 T CDC_Device_SendString +0000489e T CDC_Device_SendData +000048e2 T CDC_Device_SendByte +00004938 T CDC_Device_Flush +000049ca T CDC_Device_USBTask +000049fe T CDC_Device_ReceiveByte +00004ac8 T CDC_Device_Event_Stub +00004ac8 W EVENT_CDC_Device_BreakSent +00004ac8 W EVENT_CDC_Device_ControLineStateChanged +00004ac8 W EVENT_CDC_Device_LineEncodingChanged +00004aca T __mulsi3 +00004b08 t do_rand +00004ba6 T rand_r +00004ba8 T rand +00004bae T srand +00004bc4 T memcpy_P +00004bd6 T strcmp_P +00004be8 T strncpy_P +00004c06 T memcpy +00004c18 T snprintf_P +00004c72 T vfprintf +00005010 T __eerd_block_x32a4u +00005026 T __eewr_block_x32a4u +00005038 T __eewr_byte_x32a4u +0000503a T __eewr_r18_x32a4u +0000507e T strnlen_P +00005094 T strnlen +000050aa T fputc +00005102 T __ultoa_invert +000051be T __divmodsi4 +000051d2 t __divmodsi4_neg2 +000051e0 t __divmodsi4_exit +000051e2 t __divmodsi4_neg1 +000051f4 T __prologue_saves__ +00005226 T __epilogue_restores__ +00005256 T __udivmodsi4 +00005262 t __udivmodsi4_loop +0000527c t __udivmodsi4_ep +0000529a T _exit +0000529a W exit +0000529c t __stop_program +0000529e A __data_load_start +0000529e T _etext +00005340 A __data_load_end +00802000 D TerminalHandle +00802000 D __data_start +0080201b d TerminalInitDelay +0080201d d TableAB +0080206d d TableC +0080209d d next +008020a2 b LastButtonState.4027 +008020a2 B __bss_start +008020a2 D __data_end +008020a2 D _edata +008020a3 B LEDPulseMask +008020a4 B TerminalState +008020a5 b State +008020a6 b CurrentFrameNumber +008020a7 b RetryCount +008020a8 b RetryTimeout +008020a9 b BlockAddress +008020ad b CallbackFunc +008020af b BufferIdx +008020b1 b Checksum +008020b2 b ReceivedFrameNumber +008020b3 b BufferIdx +008020b5 b SamplePosition +008020b6 b LoadModState +008020b7 b LastBit +008020b8 b IsParityBit +008020b9 b SampleRegister +008020ba b DataRegister +008020bb b BitSent +008020bd b BitCount +008020bf b Flags +008020c1 b CodecBufferPtr +008020c3 b ParityBufferPtr +008020c5 b State +008020c6 b CardATQAValue +008020c8 b CardSAKValue +008020c9 b ReaderResponse +008020cd b CardResponse +008020d1 b CurrentAddress +008020d2 b BlockBuffer +008020e2 b StateOdd +008020e5 b StateEven +008020e8 B ActiveConfiguration +0080210d B GlobalSettings +00802120 B TerminalBuffer +00802220 B CodecBuffer +00802320 B USB_Device_ConfigurationNumber +00802321 B USB_Device_CurrentlySelfPowered +00802322 B USB_Device_RemoteWakeupEnabled +00802323 B USB_IsInitialized +00802324 B USB_DeviceState +00802325 B USB_ControlRequest +0080232d B USB_Endpoint_SelectedFIFO +0080232f B USB_Endpoint_SelectedHandle +00802331 B USB_Endpoint_SelectedEndpoint +00802332 B USB_Endpoint_FIFOs +0080264a B USB_EndpointTable +008026ad B __bss_end +008026ad B _end +00810000 D StoredSettings +00810013 D __eeprom_end diff --git a/Firmware/Chameleon-Mini/Codec/Codec.c b/Firmware/Chameleon-Mini/Codec/Codec.c new file mode 100644 index 00000000..0f309573 --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/Codec.c @@ -0,0 +1,58 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Codec.h" + +uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h new file mode 100644 index 00000000..5b001a75 --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -0,0 +1,122 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef CODEC_H_ +#define CODEC_H_ + +#include +#include +#include +#include "../Common.h" +#include "../Configuration.h" + +#include "ISO14443-2A.h" + +#define CODEC_DEMOD_POWER_PORT PORTB +#define CODEC_DEMOD_POWER_MASK PIN1_bm +#define CODEC_DEMOD_IN_PORT PORTB +#define CODEC_DEMOD_IN_MASK (CODEC_DEMOD_IN_MASK0 | CODEC_DEMOD_IN_MASK1) +#define CODEC_DEMOD_IN_MASK0 PIN0_bm +#define CODEC_DEMOD_IN_MASK1 PIN2_bm +#define CODEC_DEMOD_IN_PINCTRL0 PIN0CTRL +#define CODEC_DEMOD_IN_PINCTRL1 PIN2CTRL +#define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN0_gc +#define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc +#define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect +#define CODEC_LOADMOD_PORT PORTC +#define CODEC_LOADMOD_MASK PIN6_bm +#define CODEC_CARRIER_IN_PORT PORTC +#define CODEC_CARRIER_IN_MASK PIN2_bm +#define CODEC_CARRIER_IN_PINCTRL PIN2CTRL +#define CODEC_CARRIER_IN_EVMUX EVSYS_CHMUX_PORTC_PIN2_gc +#define CODEC_SUBCARRIER_PORT PORTC +#define CODEC_SUBCARRIER_MASK_PSK PIN0_bm +#define CODEC_SUBCARRIER_MASK_OOK PIN1_bm +#define CODEC_SUBCARRIER_MASK (CODEC_SUBCARRIER_MASK_PSK | CODEC_SUBCARRIER_MASK_OOK) +#define CODEC_SUBCARRIER_TIMER TCC0 +#define CODEC_SUBCARRIER_CC_PSK CCA +#define CODEC_SUBCARRIER_CC_OOK CCB +#define CODEC_SUBCARRIER_CCEN_PSK TC0_CCAEN_bm +#define CODEC_SUBCARRIER_CCEN_OOK TC0_CCBEN_bm +#define CODEC_TIMER_SAMPLING TCC1 +#define CODEC_TIMER_SAMPLING_CCA_VECT TCC1_CCA_vect +#define CODEC_TIMER_LOADMOD TCD1 +#define CODEC_TIMER_OVF_VECT TCD1_OVF_vect + +#define CODEC_BUFFER_SIZE 256 /* Byte */ + +#define CODEC_CARRIER_FREQ 13560000 + +extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; + +INLINE void CodecInit(void) { + ActiveConfiguration.CodecInitFunc(); +} + +INLINE void CodecTask(void) { + ActiveConfiguration.CodecTaskFunc(); +} + +INLINE void CodecSetDemodPower(bool bOnOff) { + CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK; + + if (bOnOff) { + CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK; + } else { + CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK; + } +} + +#endif /* CODEC_H_ */ diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c new file mode 100644 index 00000000..6527171a --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c @@ -0,0 +1,485 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "ISO14443-2A.h" +#include "../System.h" +#include "../Application/Application.h" +#include "Codec.h" + +/* Timing definitions for ISO14443A */ +#define ISO14443A_SUBCARRIER_DIVIDER 16 +#define ISO14443A_BIT_GRID_CYCLES 128 +#define ISO14443A_BIT_RATE_CYCLES 128 +#define ISO14443A_FRAME_DELAY_PREV1 (1236 - 24) /* compensate for ISR prolog */ +#define ISO14443A_FRAME_DELAY_PREV0 (1172 - 24) + +/* Sampling is done using internal clock, synchronized to the field modulation. + * For that we need to convert the bit rate for the internal clock. */ +#define SAMPLE_RATE_SYSTEM_CYCLES ((uint16_t) (((uint64_t) F_CPU * ISO14443A_BIT_RATE_CYCLES) / CODEC_CARRIER_FREQ) ) + +static volatile struct { + volatile bool DemodFinished; + volatile bool LoadmodFinished; +} Flags = { 0 }; + +typedef enum { + LOADMOD_FDT, + LOADMOD_START, + LOADMOD_START_BIT0, + LOADMOD_START_BIT1, + LOADMOD_DATA0, + LOADMOD_DATA1, + LOADMOD_PARITY0, + LOADMOD_PARITY1, + LOADMOD_STOP_BIT0, + LOADMOD_STOP_BIT1, + LOADMOD_FINISHED +} LoadModStateType; + +static volatile uint8_t* CodecBufferPtr; +static volatile uint8_t* ParityBufferPtr; +static volatile uint16_t BitCount; +static volatile uint16_t BitSent; +static volatile uint8_t DataRegister; +static volatile uint8_t SampleRegister; +static volatile bool IsParityBit; +static volatile uint8_t LastBit; +static volatile LoadModStateType LoadModState; +static volatile bool SamplePosition; + +static void Initialize(void) { + /* Configure CARRIER input pin and route it to EVSYS */ + CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK; + CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc; + EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX; + + /* Configure two DEMOD pins for input. + * Configure event channel 0 for rising edge (begin of modulation pause) + * Configure event channel 1 for falling edge (end of modulation pause) */ + CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK; + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc; + CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc; + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc; + EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0; + EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1; + + /* Configure LOADMOD and SUBCARRIER output pins. + * Disable PSK modulation by setting pin to low. */ + CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK; + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK; + CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK; + + /* Configure subcarrier generation with 50% DC output using OOK */ + CODEC_SUBCARRIER_TIMER.PER = ISO14443A_SUBCARRIER_DIVIDER - 1; + CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = ISO14443A_SUBCARRIER_DIVIDER/2; + CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc; +} + +static void StartDemod(void) { + /* Activate Power for demodulator */ + CodecSetDemodPower(true); + + /* Configure sampling-timer free running and sync to first modulation-pause. */ + CODEC_TIMER_SAMPLING.CNT = 0; + CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; + CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */ + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc; + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc; + + /* Start looking out for modulation pause via interrupt. */ + CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; +} + +ISR(CODEC_DEMOD_IN_INT0_VECT) { + /* This is the first edge of the first modulation-pause after StartDemod. + * Now we have time to prepare our timers and variables to start + * demodulating beginning from one bit-width after this edge. */ + CodecBufferPtr = CodecBuffer; + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + DataRegister = 0; + SampleRegister = 0; + SamplePosition = 0; + BitCount = 0; + IsParityBit = false; + + /* Sampling timer has been preset to sample-rate and has automatically synced + * to THIS first modulation pause. Thus after exactly one bit-width from here, + * an OVF is generated. We want to start sampling with the next bit and use the + * XYZBUF mechanism of the xmega to automatically double the sampling rate on the + * next overflow. For this we have to temporarily deactivate the automatical alignment + * in order to catch next overflow event for updating the BUF registers. + * We want to sample the demodulated data stream in the first quarter of the half-bit + * where the pulsed miller encoded is located. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; + CODEC_TIMER_SAMPLING.PERBUF = SAMPLE_RATE_SYSTEM_CYCLES/2 - 1; /* Half bit width */ + CODEC_TIMER_SAMPLING.CCABUF = SAMPLE_RATE_SYSTEM_CYCLES/8 - 10 - 1; /* Compensate for DIGFILT and ISR prolog */ + + /* Setup Frame Delay Timer and wire to EVSYS. Frame delay time is + * measured from last change in RF field, therefore we use + * the event channel 1 (end of modulation pause) as the restart event. + * The preliminary frame delay time chosen here is irrelevant, because + * the correct FDT gets set automatically after demodulation. */ + CODEC_TIMER_LOADMOD.CNT = 0; + CODEC_TIMER_LOADMOD.PER = 0xFFFF; + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH1_gc; + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; + + /* Disable this interrupt */ + CODEC_DEMOD_IN_PORT.INT0MASK = 0; +} + +ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { + /* This interrupt gets called twice for every bit to sample it. */ + uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK; + uint8_t NewSampleRegister; + + /* Shift sampled bit into sampling register and hold a local copy for fast access. */ + NewSampleRegister = SampleRegister << 1; + NewSampleRegister |= (!SamplePin ? 0x01 : 0x00); + SampleRegister = NewSampleRegister; + + if (SamplePosition) { + /* Analyze the sampling register after 2 samples. */ + if ((NewSampleRegister & 0x07) == 0x07) { + /* No carrier modulation for 3 sample points. EOC! */ + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm; + + /* By this time, the FDT timer is aligned to the last modulation + * edge of the reader. So we disable the auto-synchronization and + * let it count the frame delay time in the background, and generate + * an interrupt once it has reached the FDT. */ + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + + if (LastBit) { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1; + } else { + CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0; + } + + LoadModState = LOADMOD_FDT; + + CODEC_TIMER_LOADMOD.INTFLAGS = TC1_OVFIF_bm; + CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc; + + /* Determine if we did not receive a multiple of 8 bits. + * If this is the case, right-align the remaining data and + * store it into the buffer. */ + uint8_t RemainingBits = BitCount % 8; + if (RemainingBits != 0) { + uint8_t NewDataRegister = DataRegister; + + while (RemainingBits++ < 8) { + /* Pad with zeroes to right-align. */ + NewDataRegister >>= 1; + } + + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr = NewDataRegister; + } + + /* Signal, that we have finished sampling */ + Flags.DemodFinished = 1; + } else { + /* Otherwise, we check the two sample bits from the bit before. */ + uint8_t BitSample = NewSampleRegister & 0xC; + uint8_t Bit = 0; + + if (BitSample != (0x0 << 2)) { + /* We have a valid bit. decode and process it. */ + if (BitSample & (0x1 << 2)) { + /* 01 sequence or 11 sequence -> This is a zero bit */ + Bit = 0; + } else { + /* 10 sequence -> This is a one bit */ + Bit = 1; + } + + LastBit = Bit; + + if (!IsParityBit) { + /* This is a data bit, so shift it into the data register and + * hold a local copy of it. */ + uint8_t NewDataRegister = DataRegister >> 1; + NewDataRegister |= (Bit ? 0x80 : 0x00); + DataRegister = NewDataRegister; + + /* Update bitcount */ + uint16_t NewBitCount = ++BitCount; + if ((NewBitCount & 0x07) == 0) { + /* We have reached a byte boundary! Store the data register. */ + /* TODO: Prevent buffer overflow */ + *CodecBufferPtr++ = NewDataRegister; + + /* Store bit for determining FDT at EOC and enable parity + * handling on next bit. */ + IsParityBit = true; + } + + } else { + /* This is a parity bit. Store it */ + /* TODO: Store parity and prevent overflow */ + //*ParityBufferPtr++ = Bit; + IsParityBit = false; + } + } else { + /* 00 sequence. -> No valid data yet. This also occurs if we just started + * sampling and have sampled less than 2 bits yet. Thus ignore. */ + } + } + } else { + /* On odd sample position just sample. */ + } + + SamplePosition = !SamplePosition; + + /* Make sure the sampling timer gets automatically aligned to the + * modulation pauses by using the RESTART event. + * This can be understood as a "poor mans PLL" and makes sure that we are + * never too far out the bit-grid while sampling. */ + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc; +} + +ISR(CODEC_TIMER_OVF_VECT) { + /* Bit rate timer. Output a half bit on the output. */ + uint8_t Temp8; + uint16_t Temp16; + + switch (LoadModState) { + case LOADMOD_FDT: + /* No data has been produced, but FDT has ended. Switch over to bit-grid aligning. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_GRID_CYCLES - 1; + break; + + case LOADMOD_START: + /* Application produced data. With this interrupt we are aligned to the bit-grid. + * Start subcarrier generation and align to bitrate. */ + CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_RATE_CYCLES / 2 - 1; + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_EVCH6_gc; + + /* Fallthrough to first bit */ + + case LOADMOD_START_BIT0: + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_START_BIT1; + break; + + case LOADMOD_START_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_DATA0; + + /* Fetch first byte */ + DataRegister = *CodecBufferPtr; + break; + + case LOADMOD_DATA0: + if (DataRegister & 1) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } + + LoadModState = LOADMOD_DATA1; + break; + + case LOADMOD_DATA1: + Temp8 = DataRegister; + + if (Temp8 & 1) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } + + DataRegister = Temp8 >> 1; + + Temp16 = BitSent; + BitSent = ++Temp16; + + if ((Temp16 & 0x07) == 0) { + /* Byte boundary. Load parity bit and output it later. */ + LoadModState = LOADMOD_PARITY0; + break; + } + + if (Temp16 == BitCount) { + /* End of transmission without byte boundary. Don't send parity. */ + LoadModState = LOADMOD_STOP_BIT0; + break; + } + + /* Next bit is data */ + LoadModState = LOADMOD_DATA0; + + break; + + case LOADMOD_PARITY0: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } + + LoadModState = LOADMOD_PARITY1; + break; + + case LOADMOD_PARITY1: + if (*ParityBufferPtr) { + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + } else { + CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK; + } + + if (BitSent == BitCount) { + /* No data left */ + LoadModState = LOADMOD_STOP_BIT0; + } else { + /* Fetch next data and continue sending bits. */ + ParityBufferPtr++; + DataRegister = *++CodecBufferPtr; + LoadModState = LOADMOD_DATA0; + } + + break; + + case LOADMOD_STOP_BIT0: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_STOP_BIT1; + break; + + case LOADMOD_STOP_BIT1: + CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK; + LoadModState = LOADMOD_FINISHED; + break; + + case LOADMOD_FINISHED: + /* We have written all of our bits. Deactivate the loadmod + * timer. Also disable the bit-rate interrupt again. And + * stop the subcarrier divider. */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + + /* Signal application that we have finished loadmod */ + Flags.LoadmodFinished = 1; + break; + + default: + break; + } +} + +void ISO14443ACodecInit(void) { + /* Initialize common peripherals and start listening + * for incoming data. */ + Initialize(); + StartDemod(); +} + +void ISO14443ACodecTask(void) { + if (Flags.DemodFinished) { + Flags.DemodFinished = 0; + /* Reception finished. Process the received bytes */ + CodecSetDemodPower(false); + + uint16_t DemodBitCount = BitCount; + uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE; + + if (DemodBitCount > 0) { + /* Call application if we received data */ + AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount); + + if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) { + /* Application has generated it's own parity bits. + * Clear this option bit. */ + AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY; + } else { + /* We have to generate the parity bits ourself */ + for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) { + /* For each whole byte, generate a parity bit. */ + CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] = + ODD_PARITY(CodecBuffer[i]); + } + } + } else { + ApplicationReset(); + } + + if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) { + BitCount = AnswerBitCount; + BitSent = 0; + CodecBufferPtr = CodecBuffer; + ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET]; + LoadModState = LOADMOD_START; + } else { + /* No data to be processed. Disable loadmodding and start listening again */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + + StartDemod(); + } + } + + if (Flags.LoadmodFinished) { + Flags.LoadmodFinished = 0; + /* Load modulation has been finished. Stop it and start to listen + * for incoming data again. */ + StartDemod(); + } +} + diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h new file mode 100644 index 00000000..0fbcaa59 --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h @@ -0,0 +1,72 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef ISO14443_2A_H_ +#define ISO14443_2A_H_ + +#include "Codec.h" + +#define ISO14443A_APP_NO_RESPONSE 0x0000 +#define ISO14443A_APP_CUSTOM_PARITY 0x1000 + +#define ISO14443A_BUFFER_PARITY_OFFSET (CODEC_BUFFER_SIZE/2) + +/* Codec Interface */ +void ISO14443ACodecInit(void); +void ISO14443ACodecTask(void); + + + +#endif diff --git a/Firmware/Chameleon-Mini/Common.c b/Firmware/Chameleon-Mini/Common.c new file mode 100644 index 00000000..24064934 --- /dev/null +++ b/Firmware/Chameleon-Mini/Common.c @@ -0,0 +1,119 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Common.h" + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t CharCount = 0; + + /* Account for '\0' at the end */ + MaxChars--; + + while( (ByteCount > 0) && (MaxChars >= 2) ) { + uint8_t Byte = *ByteBuffer; + + HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F ); + HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F ); + + HexOut += 2; + MaxChars -= 2; + CharCount += 2; + ByteBuffer++; + ByteCount -= 1; + } + + *HexOut = '\0'; + + return CharCount; +} + +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + uint16_t ByteCount = 0; + + while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) { + if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) { + uint8_t Byte = 0; + + Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4; + Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0; + + *ByteBuffer = Byte; + + ByteBuffer++; + MaxBytes--; + ByteCount++; + HexIn += 2; + } else { + /* HEX chars only */ + return 0; + } + } + + if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) { + /* Odd number of characters */ + return 0; + } + + return ByteCount; +} + + + + + diff --git a/Firmware/Chameleon-Mini/Common.h b/Firmware/Chameleon-Mini/Common.h new file mode 100644 index 00000000..0ae38353 --- /dev/null +++ b/Firmware/Chameleon-Mini/Common.h @@ -0,0 +1,81 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef COMMON_H_ +#define COMMON_H_ + +#include +#include +#include +#include +#include + +#define ODD_PARITY(Value) (parity_even_bit(Value) ? 0 : 1) + +#define INLINE \ + static inline __attribute__((always_inline)) + +#define NIBBLE_TO_HEXCHAR(x) ( (x) < 0x0A ? (x) + '0' : (x) + 'A' - 0x0A ) +#define HEXCHAR_TO_NIBBLE(x) ( (x) < 'A' ? (x) - '0' : (x) - 'A' + 0x0A ) +#define VALID_HEXCHAR(x) ( ( (x) >= '0' && (x) <= '9' ) || ( (x) >= 'A' && (x) <= 'F' ) ) +#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) +#define MAX(x,y) ( (x) > (y) ? (x) : (y) ) + +#define BITS_PER_BYTE 8 + +uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount); +uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn); + +#endif /* COMMON_H_ */ diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c new file mode 100644 index 00000000..faf24626 --- /dev/null +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -0,0 +1,215 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Configuration.h" +#include "Settings.h" +#include + +/* Include all Codecs and Applications */ +#include "Codec/Codec.h" +#include "Application/Application.h" + +static void CodecInitDummy(void) { } +static void CodecTaskDummy(void) { } +static void ApplicationInitDummy(void) {} +static void ApplicationResetDummy(void) {} +static void ApplicationTaskDummy(void) {} +static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return 0; } +static void ApplicationGetUidDummy(ConfigurationUidType Uid) { } +static void ApplicationSetUidDummy(ConfigurationUidType Uid) { } + +static const PROGMEM ConfigurationType ConfigurationTable[] = { + [CONFIG_NONE] = { + .ConfigurationID = CONFIG_NONE, + .ConfigurationName = "NONE", + .CodecInitFunc = CodecInitDummy, + .CodecTaskFunc = CodecTaskDummy, + .ApplicationInitFunc = ApplicationInitDummy, + .ApplicationResetFunc = ApplicationResetDummy, + .ApplicationTaskFunc = ApplicationTaskDummy, + .ApplicationProcessFunc = ApplicationProcessDummy, + .ApplicationGetUidFunc = ApplicationGetUidDummy, + .ApplicationSetUidFunc = ApplicationSetUidDummy, + .UidSize = 0, + .MemorySize = 0, + .ReadOnly = true + }, +#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT + [CONFIG_MF_CLASSIC_1K] = { + .ConfigurationID = CONFIG_MF_CLASSIC_1K, + .ConfigurationName = "MF_CLASSIC_1K", + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifareClassicAppInit1K, + .ApplicationResetFunc = MifareClassicAppReset, + .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationProcessFunc = MifareClassicAppProcess, + .ApplicationGetUidFunc = MifareClassicGetUid, + .ApplicationSetUidFunc = MifareClassicSetUid, + .UidSize = MIFARE_CLASSIC_UID_SIZE, + .MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE, + .ReadOnly = false + }, +#endif +#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT + [CONFIG_MF_CLASSIC_4K] = { + .ConfigurationID = CONFIG_MF_CLASSIC_4K, + .ConfigurationName = "MF_CLASSIC_4K", + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifareClassicAppInit4K, + .ApplicationResetFunc = MifareClassicAppReset, + .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationProcessFunc = MifareClassicAppProcess, + .ApplicationGetUidFunc = MifareClassicGetUid, + .ApplicationSetUidFunc = MifareClassicSetUid, + .UidSize = MIFARE_CLASSIC_UID_SIZE, + .MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE, + .ReadOnly = false + }, +#endif +}; + +ConfigurationType ActiveConfiguration; + +void ConfigurationInit(void) +{ + ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration); +} + +void ConfigurationSetById( ConfigurationEnum Configuration ) +{ + GlobalSettings.ActiveSettingPtr->Configuration = Configuration; + + /* Copy struct from PROGMEM to RAM */ + memcpy_P(&ActiveConfiguration, + &ConfigurationTable[Configuration], sizeof(ConfigurationType)); + + + ApplicationInit(); + CodecInit(); +} + +bool ConfigurationSetByName(const char* ConfigurationName) +{ + uint8_t i; + + /* Loop through table trying to find the configuration */ + for (i=0; i<(sizeof(ConfigurationTable) / sizeof(*ConfigurationTable)); i++) { + const char* pTableConfigName = ConfigurationTable[i].ConfigurationName; + const char* pRequestedConfigName = ConfigurationName; + bool StringMismatch = false; + char c = pgm_read_byte(pTableConfigName); + + /* Try to keep running until both strings end at the same point */ + while ( !(c == '\0' && *pRequestedConfigName == '\0') ) { + if ( (c == '\0') || (*pRequestedConfigName == '\0') ) { + /* One String ended before the other did -> unequal length */ + StringMismatch = true; + break; + } + + if (c != *pRequestedConfigName) { + /* Character mismatch */ + StringMismatch = true; + break; + } + + /* Proceed to next character */ + pTableConfigName++; + pRequestedConfigName++; + + c = pgm_read_byte(pTableConfigName); + } + + if (!StringMismatch) { + /* Configuration found */ + ConfigurationSetById(i); + return true; + } + } + + return false; +} + +void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount) +{ + uint8_t i; + + /* Account for '\0' */ + ByteCount--; + + for (i=0; i CONFIGURATION_NAME_LENGTH_MAX) { + /* While not end-of-string and enough buffer to + * put a complete configuration name */ + *ConfigListOut++ = c; + ConfigName++; + ByteCount--; + } + + if ( i < (CONFIG_COUNT - 1) ) { + /* No comma on last configuration */ + *ConfigListOut++ = ','; + ByteCount--; + } + } + + *ConfigListOut = '\0'; +} + diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h new file mode 100644 index 00000000..6c814b80 --- /dev/null +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -0,0 +1,127 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef STANDARDS_H_ +#define STANDARDS_H_ + +#include +#include + +#define CONFIGURATION_NAME_LENGTH_MAX 16 +#define CONFIGURATION_UID_SIZE_MAX 16 + +typedef uint8_t ConfigurationUidType[CONFIGURATION_UID_SIZE_MAX]; + +typedef enum { + /* This HAS to be the first element */ + CONFIG_NONE = 0, + +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT + CONFIG_MF_ULTRALIGHT, +#endif +#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT + CONFIG_MF_CLASSIC_1K, +#endif +#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT + CONFIG_MF_CLASSIC_4K, +#endif +#ifdef CONFIG_ISO15693_GEN_SUPPORT + CONFIG_ISO15693_GEN, +#endif +#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT + CONFIG_ISO14443A_SNIFF, +#endif +#ifdef CONFIG_ISO15693_SNIFF_SUPPORT + CONFIG_ISO15693_SNIFF, +#endif + //CONFIG_MF_DESFIRE, + //CONFIG_ISO14443A_RELAY + + + + /* This HAS to be the last element */ + CONFIG_COUNT +} ConfigurationEnum; + +typedef struct { + ConfigurationEnum ConfigurationID; + char ConfigurationName[CONFIGURATION_NAME_LENGTH_MAX]; + + /* Codec used for this configuration */ + void (*CodecInitFunc) (void); + void (*CodecTaskFunc) (void); + + /* Application used for this configuration */ + void (*ApplicationInitFunc) (void); + void (*ApplicationResetFunc) (void); + void (*ApplicationTaskFunc) (void); + uint16_t (*ApplicationProcessFunc) (uint8_t* ByteBuffer, uint16_t ByteCount); + void (*ApplicationGetUidFunc) (ConfigurationUidType Uid); + void (*ApplicationSetUidFunc) (ConfigurationUidType Uid); + + uint16_t MemorySize; + uint8_t UidSize; + bool ReadOnly; + +} ConfigurationType; + +extern ConfigurationType ActiveConfiguration; + +void ConfigurationInit(void); +void ConfigurationSetById(ConfigurationEnum Configuration); +bool ConfigurationSetByName(const char* ConfigurationName); +void ConfigurationGetList(char* ConfigListOut, uint16_t ByteCount); + +#endif /* STANDARDS_H_ */ diff --git a/Firmware/Chameleon-Mini/LED.c b/Firmware/Chameleon-Mini/LED.c new file mode 100644 index 00000000..d3360d6a --- /dev/null +++ b/Firmware/Chameleon-Mini/LED.c @@ -0,0 +1,58 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "LED.h" + +uint8_t LEDPulseMask = 0; diff --git a/Firmware/Chameleon-Mini/LED.h b/Firmware/Chameleon-Mini/LED.h new file mode 100644 index 00000000..c0e21a39 --- /dev/null +++ b/Firmware/Chameleon-Mini/LED.h @@ -0,0 +1,100 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef LED_H +#define LED_H + +#include + +#define LED_PORT PORTA +#define LED_GREEN PIN5_bm +#define LED_RED PIN4_bm +#define LED_MASK (LED_GREEN | LED_RED) + +extern uint8_t LEDPulseMask; + +static inline +void LEDInit(void) { + LED_PORT.DIRSET = LED_MASK; +} + +static inline +void LEDSetOn(uint8_t Mask) { + LED_PORT.OUTSET = Mask; +} + +static inline +void LEDSetOff(uint8_t Mask) { + LED_PORT.OUTCLR = Mask; +} + +static inline +void LEDToggle(uint8_t Mask) { + LED_PORT.OUTTGL = Mask; +} + +static inline +void LEDPulse(uint8_t Mask) { + LEDPulseMask = Mask; + LED_PORT.OUTSET = Mask; +} + +static inline +void LEDTick(void) { + LED_PORT.OUTCLR = LEDPulseMask; + LEDPulseMask = 0; +} + +#endif /* LED_H */ diff --git a/Firmware/Chameleon-Mini/LUFAConfig.h b/Firmware/Chameleon-Mini/LUFAConfig.h new file mode 100644 index 00000000..38ca90b9 --- /dev/null +++ b/Firmware/Chameleon-Mini/LUFAConfig.h @@ -0,0 +1,78 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Library Configuration Header File + * + * This header file is used to configure LUFA's compile time options, + * as an alternative to the compile time constants supplied through + * a makefile. + * + * For information on what each token does, refer to the LUFA + * manual section "Summary of Compile Tokens". + */ + +#ifndef _LUFA_CONFIG_H_ +#define _LUFA_CONFIG_H_ + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ + #define USE_STATIC_OPTIONS \ + (USB_OPT_BUSEVENT_PRIMED | USB_DEVICE_OPT_FULLSPEED | USB_OPT_PLLCLKSRC /*USB_OPT_RC32MCLKSRC*/) + #define USB_DEVICE_ONLY +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS + #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS +// #define NO_INTERNAL_SERIAL + #define FIXED_CONTROL_ENDPOINT_SIZE 8 +// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} + #define FIXED_NUM_CONFIGURATIONS 1 +// #define CONTROL_ONLY_DEVICE + #define MAX_ENDPOINT_INDEX 5 +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + +#endif diff --git a/Firmware/Chameleon-Mini/LUFADescriptors.c b/Firmware/Chameleon-Mini/LUFADescriptors.c new file mode 100644 index 00000000..a463a03e --- /dev/null +++ b/Firmware/Chameleon-Mini/LUFADescriptors.c @@ -0,0 +1,260 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * USB Device Descriptors, for library use when in USB device mode. Descriptors are special + * computer-readable structures which the host requests upon device enumeration, to determine + * the device's capabilities and functions. + */ + +#include "LUFADescriptors.h" + + +/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall + * device characteristics, including the supported USB version, control endpoint size and the + * number of device configurations. The descriptor is read out by the USB host when the enumeration + * process begins. + */ +const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = +{ + .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, + + .USBSpecification = VERSION_BCD(01.10), + .Class = CDC_CSCP_CDCClass, + .SubClass = CDC_CSCP_NoSpecificSubclass, + .Protocol = CDC_CSCP_NoSpecificProtocol, + + .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, + + .VendorID = 0x03EB, + .ProductID = 0x2044, + .ReleaseNumber = VERSION_BCD(00.01), + + .ManufacturerStrIndex = 0x01, + .ProductStrIndex = 0x02, + .SerialNumStrIndex = USE_INTERNAL_SERIAL, + + .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS +}; + +/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage + * of the device in one of its supported configurations, including information about any device interfaces + * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting + * a configuration so that the host may correctly communicate with the USB device. + */ +const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = +{ + .Config = + { + .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, + + .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), + .TotalInterfaces = 2, + + .ConfigurationNumber = 1, + .ConfigurationStrIndex = NO_DESCRIPTOR, + + .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, + + .CDC_CCI_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = 0, + .AlternateSetting = 0, + + .TotalEndpoints = 1, + + .Class = CDC_CSCP_CDCClass, + .SubClass = CDC_CSCP_ACMSubclass, + .Protocol = CDC_CSCP_ATCommandProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .CDC_Functional_Header = + { + .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface}, + .Subtype = CDC_DSUBTYPE_CSInterface_Header, + + .CDCSpecification = VERSION_BCD(01.10), + }, + + .CDC_Functional_ACM = + { + .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface}, + .Subtype = CDC_DSUBTYPE_CSInterface_ACM, + + .Capabilities = 0x06, + }, + + .CDC_Functional_Union = + { + .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface}, + .Subtype = CDC_DSUBTYPE_CSInterface_Union, + + .MasterInterfaceNumber = 0, + .SlaveInterfaceNumber = 1, + }, + + .CDC_NotificationEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CDC_NOTIFICATION_EPADDR, + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CDC_NOTIFICATION_EPSIZE, + .PollingIntervalMS = 0xFF + }, + + .CDC_DCI_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = 1, + .AlternateSetting = 0, + + .TotalEndpoints = 2, + + .Class = CDC_CSCP_CDCDataClass, + .SubClass = CDC_CSCP_NoDataSubclass, + .Protocol = CDC_CSCP_NoDataProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .CDC_DataOutEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CDC_RX_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CDC_TXRX_EPSIZE, + .PollingIntervalMS = 0x05 + }, + + .CDC_DataInEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CDC_TX_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CDC_TXRX_EPSIZE, + .PollingIntervalMS = 0x05 + } +}; + +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +const USB_Descriptor_String_t PROGMEM LanguageString = +{ + .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, + + .UnicodeString = {LANGUAGE_ID_ENG} +}; + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t PROGMEM ManufacturerString = +{ + .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, + + .UnicodeString = L"Dean Camera" +}; + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t PROGMEM ProductString = +{ + .Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String}, + + .UnicodeString = L"LUFA CDC Demo" +}; + +/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" + * documentation) by the application code so that the address and size of a requested descriptor can be given + * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function + * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the + * USB host. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + { + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + + break; + } + + *DescriptorAddress = Address; + return Size; +} + diff --git a/Firmware/Chameleon-Mini/LUFADescriptors.h b/Firmware/Chameleon-Mini/LUFADescriptors.h new file mode 100644 index 00000000..7a547495 --- /dev/null +++ b/Firmware/Chameleon-Mini/LUFADescriptors.h @@ -0,0 +1,89 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + + /* Includes: */ + #include + + #include + + /* Macros: */ + /** Endpoint address of the CDC device-to-host notification IN endpoint. */ + #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2) + + /** Endpoint address of the CDC device-to-host data IN endpoint. */ + #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3) + + /** Endpoint address of the CDC host-to-device data OUT endpoint. */ + #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4) + + /** Size in bytes of the CDC device-to-host notification IN endpoint. */ + #define CDC_NOTIFICATION_EPSIZE 8 + + /** Size in bytes of the CDC data IN and OUT endpoints. */ + #define CDC_TXRX_EPSIZE 16 + + /* Type Defines: */ + /** Type define for the device configuration descriptor structure. This must be defined in the + * application code, as the configuration descriptor contains several sub-descriptors which + * vary between devices, and which describe the device's usage to the host. + */ + typedef struct + { + USB_Descriptor_Configuration_Header_t Config; + + // CDC Control Interface + USB_Descriptor_Interface_t CDC_CCI_Interface; + USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header; + USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM; + USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union; + USB_Descriptor_Endpoint_t CDC_NotificationEndpoint; + + // CDC Data Interface + USB_Descriptor_Interface_t CDC_DCI_Interface; + USB_Descriptor_Endpoint_t CDC_DataOutEndpoint; + USB_Descriptor_Endpoint_t CDC_DataInEndpoint; + } USB_Descriptor_Configuration_t; + + /* Function Prototypes: */ + uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + +#endif + diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile new file mode 100644 index 00000000..a0361c7a --- /dev/null +++ b/Firmware/Chameleon-Mini/Makefile @@ -0,0 +1,138 @@ +# Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL +# AUTHORS"). All rights reserved. +# +# DEFINITIONS: +# +# "WORK": The material covered by this license includes the schematic +# diagrams, designs, circuit or circuit board layouts, mechanical +# drawings, documentation (in electronic or printed form), source code, +# binary software, data files, assembled devices, and any additional +# material provided by the ORIGINAL AUTHORS in the ChameleonMini project +# (https://github.com/skuep/ChameleonMini). +# +# LICENSE TERMS: +# +# Redistributions and use of this WORK, with or without modification, or +# of substantial portions of this WORK are permitted provided that the +# following conditions are met: +# +# Redistributions and use of this WORK, with or without modification, or +# of substantial portions of this WORK must include the above copyright +# notice, this list of conditions, the below disclaimer, and the following +# attribution: +# +# "Based on ChameleonMini an open-source RFID emulator: +# https://github.com/skuep/ChameleonMini" +# +# The attribution must be clearly visible to a user, for example, by being +# printed on the circuit board and an enclosure, and by being displayed by +# software (both in binary and source code form). +# +# At any time, the majority of the ORIGINAL AUTHORS may decide to give +# written permission to an entity to use or redistribute the WORK (with or +# without modification) WITHOUT having to include the above copyright +# notice, this list of conditions, the below disclaimer, and the above +# attribution. +# +# DISCLAIMER: +# +# THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the hardware, software, and +# documentation should not be interpreted as representing official +# policies, either expressed or implied, of the ORIGINAL AUTHORS. + +#Supported configurations +SETTINGS += -DCONFIG_MF_CLASSIC_1K_SUPPORT +SETTINGS += -DCONFIG_MF_CLASSIC_4K_SUPPORT + +#Support activating firmware upgrade mode through command-line +SETTINGS += -DSUPPORT_FIRMWARE_UPGRADE + +#Default configuration +SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_NONE + +#Default button action +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RANDOM +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_INCREMENT +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_INCREMENT +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_DECREMENT +#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_DECREMENT +SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS + +#Default setting +SETTINGS += -DDEFAULT_SETTING=0 + +#Use EEPROM to store settings +SETTINGS += -DENABLE_EEPROM_SETTINGS + +#Build configuration +BUILD_DATE = $(shell date +'\"%y%m%d\"') +MCU = atxmega32a4u +ARCH = XMEGA +BOARD = NONE +F_CPU = 32000000 +F_USB = 48000000 +TARGET = Chameleon-Mini +OPTIMIZATION = 3 +SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c Button.c Settings.c LED.c +SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c +SRC += Codec/Codec.c Codec/ISO14443-2A.c +SRC += AApplication/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c +SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) +LUFA_PATH = ../LUFA +CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DBUILD_DATE=$(BUILD_DATE) $(SETTINGS) +LD_FLAGS = +OBJDIR = Bin +OBJECT_FILES = + + +#AVRDUDE settings +AVRDUDE_PROGRAMMER = jtag2pdi #avrisp2 +AVRDUDE_MCU = atxmega32a4 #atxmega128a4 +AVRDUDE_PORT = usb +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Default target +all: + +# Include LUFA build script makefiles +include $(LUFA_PATH)/Build/lufa_core.mk +include $(LUFA_PATH)/Build/lufa_sources.mk +include $(LUFA_PATH)/Build/lufa_build.mk +include $(LUFA_PATH)/Build/lufa_cppcheck.mk +# include $(LUFA_PATH)/Build/lufa_doxygen.mk +# include $(LUFA_PATH)/Build/lufa_dfu.mk +# include $(LUFA_PATH)/Build/lufa_hid.mk +# include $(LUFA_PATH)/Build/lufa_avrdude.mk +# include $(LUFA_PATH)/Build/lufa_atprogram.mk + +# Program the device using avrdude +program: $(TARGET).hex $(TARGET).eep + avrdude $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +# Program the device using batchisp and the DFU bootloader +# Note that the device has to be in bootloader mode already +dfu-flip: $(TARGET).hex $(TARGET).eep + cp $(TARGET).eep EEPROM.hex + batchisp -hardware usb -device $(MCU) -operation erase f memory FLASH loadbuffer $(TARGET).hex program verify memory EEPROM loadbuffer EEPROM.hex program verify start reset 0 + rm EEPROM.hex + +# Program the device using dfu-programmer +dfu-prog: $(TARGET).hex $(TARGET).eep + dfu-programmer $(MCU) erase + dfu-programmer $(MCU) flash-eeprom $(TARGET).eep + dfu-programmer $(MCU) flash $(TARGET).hex + dfu-programmer $(MCU) reset diff --git a/Firmware/Chameleon-Mini/Memory.c b/Firmware/Chameleon-Mini/Memory.c new file mode 100644 index 00000000..51e29e97 --- /dev/null +++ b/Firmware/Chameleon-Mini/Memory.c @@ -0,0 +1,285 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Memory.h" +#include "Configuration.h" +#include "Common.h" +#include "Settings.h" + +#define FLASH_CMD_STATUS_REG_READ 0xD7 +#define FLASH_CMD_MEM_TO_BUF1 0x53 +#define FLASH_CMD_MEM_TO_BUF2 0x55 +#define FLASH_CMD_BUF1_WRITE 0x84 +#define FLASH_CMD_BUF2_WRITE 0x87 +#define FLASH_CMD_BUF1_TO_MEM_ERASE 0x83 +#define FLASH_CMD_BUF2_TO_MEM_ERASE 0x86 +#define FLASH_CMD_PAGE_ERASE 0x81 + +#define FLASH_STATUS_REG_READY_BIT (1<<7) +#define FLASH_STATUS_REG_COMP_BIT (1<<6) +#define FLASH_STATUS_REG_PROTECT_BIT (1<<1) +#define FLASH_STATUS_REG_PAGESIZE_BIT (1<<0) + +INLINE uint8_t SPITransferByte(uint8_t Data) +{ + MEMORY_FLASH_USART.DATA = Data; + + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + + return MEMORY_FLASH_USART.DATA; +} + +INLINE void SPIReadBlock(void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = 0; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + *ByteBuffer++ = MEMORY_FLASH_USART.DATA; + } +} + +INLINE void SPIWriteBlock(const void* Buffer, uint16_t ByteCount) +{ + uint8_t* ByteBuffer = (uint8_t*) Buffer; + + while(ByteCount-- > 0) { + MEMORY_FLASH_USART.DATA = *ByteBuffer++; + while (!(MEMORY_FLASH_USART.STATUS & USART_TXCIF_bm)); + MEMORY_FLASH_USART.STATUS = USART_TXCIF_bm; + MEMORY_FLASH_USART.DATA; /* Flush Buffer */ + } +} + +INLINE uint8_t FlashReadStatusRegister(void) +{ + uint8_t Register; + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_STATUS_REG_READ); + Register = SPITransferByte(0); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + + return Register; +} + +INLINE bool FlashIsBusy(void) +{ + return !(FlashReadStatusRegister() & FLASH_STATUS_REG_READY_BIT); +} + +INLINE void FlashConfigurePageSize(void) +{ + uint8_t Sequence[] = {0x3D, 0x2A, 0x80, 0xA6}; + + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPIWriteBlock(Sequence, sizeof(Sequence)); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashMemoryToBuffer(uint16_t PageAddress) +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_MEM_TO_BUF1); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWriteBuffer(const void* Buffer, uint8_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_BUF1_WRITE); + SPITransferByte( 0 ); + SPITransferByte( 0 ); + SPITransferByte( Address ); + SPIWriteBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashBufferToMemory(uint16_t PageAddress) +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_BUF1_TO_MEM_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashRead(void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(0x03); + SPITransferByte( (Address >> 16) & 0xFF ); + SPITransferByte( (Address >> 8) & 0xFF ); + SPITransferByte( (Address >> 0) & 0xFF ); + SPIReadBlock(Buffer, ByteCount); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount) +{ + while(ByteCount > 0) { + uint16_t PageAddress = Address / MEMORY_PAGE_SIZE; + uint8_t ByteAddress = Address % MEMORY_PAGE_SIZE; + uint16_t PageBytes = MIN(MEMORY_PAGE_SIZE - ByteAddress, ByteCount); + + FlashMemoryToBuffer(PageAddress); + FlashWriteBuffer(Buffer, ByteAddress, PageBytes); + FlashBufferToMemory(PageAddress); + + ByteCount -= PageBytes; + Address += PageBytes; + } +} + +INLINE void FlashClearPage(uint16_t PageAddress) +{ + while(FlashIsBusy()); + + MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS; + SPITransferByte(FLASH_CMD_PAGE_ERASE); + SPITransferByte( (PageAddress >> 8) & 0xFF ); + SPITransferByte( (PageAddress >> 0) & 0xFF ); + SPITransferByte( 0 ); + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; +} + +void MemoryInit(void) +{ + /* Configure MEMORY_FLASH_USART for SPI master mode 0 with maximum clock frequency */ + MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS; + MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS; + + MEMORY_FLASH_USART.BAUDCTRLA = 0; + MEMORY_FLASH_USART.BAUDCTRLB = 0; + MEMORY_FLASH_USART.CTRLC = USART_CMODE_MSPI_gc | USART_CHSIZE_8BIT_gc; + MEMORY_FLASH_USART.CTRLB = USART_RXEN_bm | USART_TXEN_bm; + + + if ( !(FlashReadStatusRegister() & FLASH_STATUS_REG_PAGESIZE_BIT) ) { + /* Configure for 256 byte Dataflash if not already done. */ + FlashConfigurePageSize(); + } +} + +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + FlashRead(Buffer, FlashAddress, ByteCount); +} + +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) +{ + uint32_t FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING; + FlashWrite(Buffer, FlashAddress, ByteCount); +} + +void MemoryClear(void) +{ + uint32_t PageAddress = ((uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING) / MEMORY_PAGE_SIZE; + uint16_t PageCount = MEMORY_SIZE_PER_SETTING / MEMORY_PAGE_SIZE; + + while(PageCount > 0) { + FlashClearPage(PageAddress); + PageCount--; + PageAddress++; + } +} + +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* Prevent writing out of bounds by silently ignoring it */ + return true; + } else { + /* Calculate bytes left in memory and start writing */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + MemoryWriteBlock(Buffer, BlockAddress, ByteCount); + return true; + } +} + +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount) +{ + if (BlockAddress >= MEMORY_SIZE_PER_SETTING) { + /* There are bytes out of bounds to be read. Notify that we are done. */ + return false; + } else { + /* Calculate bytes left in memory and issue reading */ + uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress; + ByteCount = MIN(ByteCount, BytesLeft); + MemoryReadBlock(Buffer, BlockAddress, ByteCount); + return true; + } +} + diff --git a/Firmware/Chameleon-Mini/Memory.h b/Firmware/Chameleon-Mini/Memory.h new file mode 100644 index 00000000..a367a7a2 --- /dev/null +++ b/Firmware/Chameleon-Mini/Memory.h @@ -0,0 +1,80 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef MEMORY_H_ +#define MEMORY_H_ + +#include "Common.h" + +#define MEMORY_FLASH_USART USARTD0 +#define MEMORY_FLASH_PORT PORTD +#define MEMORY_FLASH_CS PIN4_bm +#define MEMORY_FLASH_MOSI PIN3_bm +#define MEMORY_FLASH_MISO PIN2_bm +#define MEMORY_FLASH_SCK PIN1_bm + +#define MEMORY_PAGE_SIZE 256 +#define MEMORY_SIZE_PER_SETTING ((uint32_t) 256 * MEMORY_PAGE_SIZE) /* Multiple of memory page size */ + +void MemoryInit(void); +void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount); +void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount); +void MemoryClear(void); + +/* For use with XModem */ +bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount); +bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount); + +#endif /* MEMORY_H_ */ diff --git a/Firmware/Chameleon-Mini/ProgramViaBootloader.bat b/Firmware/Chameleon-Mini/ProgramViaBootloader.bat new file mode 100644 index 00000000..62d4292d --- /dev/null +++ b/Firmware/Chameleon-Mini/ProgramViaBootloader.bat @@ -0,0 +1,17 @@ +@ECHO OFF +SET COMPORT=COM21 +SET BATCHISP=..\..\Tools\batchisp +SET TIMEOUT=5 +SET COMMAND=UPGRADE + +ECHO Trying to set bootloader mode on Chameleon-Mini on %COMPORT% +@MODE %COMPORT% baud=11 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off > nul +@ECHO. > \\.\%COMPORT% +@ECHO %COMMAND% > \\.\%COMPORT% + +ECHO Waiting for DFU Bootloader +ping 127.0.0.1 -n %TIMEOUT% -w 1000 > nul + +ECHO Start Programming +SET PATH=%BATCHISP%;%PATH% +make dfu-flip diff --git a/Firmware/Chameleon-Mini/Random.c b/Firmware/Chameleon-Mini/Random.c new file mode 100644 index 00000000..74bb572a --- /dev/null +++ b/Firmware/Chameleon-Mini/Random.c @@ -0,0 +1,85 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Random.h" + +#include + +void RandomInit(void) +{ + +} + +uint8_t RandomGetByte(void) +{ + return rand() & 0xFF; +} + +void RandomGetBuffer(void* Buffer, uint8_t ByteCount) +{ + uint8_t* BufferPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + *BufferPtr++ = RandomGetByte(); + } +} + +void RandomTick(void) +{ + rand(); + rand(); + rand(); + rand(); +} diff --git a/Firmware/Chameleon-Mini/Random.h b/Firmware/Chameleon-Mini/Random.h new file mode 100644 index 00000000..a40f0865 --- /dev/null +++ b/Firmware/Chameleon-Mini/Random.h @@ -0,0 +1,66 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef RANDOM_H_ +#define RANDOM_H_ + +#include "Common.h" + +void RandomInit(void); +uint8_t RandomGetByte(void); +void RandomGetBuffer(void* Buffer, uint8_t ByteCount); +void RandomTick(void); + +#endif /* RANDOM_H_ */ diff --git a/Firmware/Chameleon-Mini/Settings.c b/Firmware/Chameleon-Mini/Settings.c new file mode 100644 index 00000000..7f89486d --- /dev/null +++ b/Firmware/Chameleon-Mini/Settings.c @@ -0,0 +1,125 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Settings.h" +#include +#include "Configuration.h" + +SettingsType GlobalSettings; +SettingsType EEMEM StoredSettings = { + .ActiveSetting = DEFAULT_SETTING, + .ActiveSettingPtr = &GlobalSettings.Settings[DEFAULT_SETTING], + + .Settings = { [0 ... (SETTINGS_COUNT-1)] = { + .Configuration = DEFAULT_CONFIGURATION, + .ButtonAction = DEFAULT_BUTTON_ACTION, + } } +}; + +void SettingsLoad(void) { + eeprom_read_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); +} + +void SettingsSave(void) { +#if ENABLE_EEPROM_SETTINGS + eeprom_write_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType)); +#endif +} + +void SettingsCycle(void) { + uint8_t i = SETTINGS_COUNT; + uint8_t Setting = GlobalSettings.ActiveSetting; + + while (i-- > 0) { + Setting = (Setting + 1) % SETTINGS_COUNT; + + if (GlobalSettings.Settings[Setting].Configuration != CONFIG_NONE) { + SettingsSetActiveById(Setting); + break; + } + } +} + +void SettingsSetActiveById(uint8_t Setting) { + if (Setting < SETTINGS_COUNT) { + GlobalSettings.ActiveSetting = Setting; + GlobalSettings.ActiveSettingPtr = + &GlobalSettings.Settings[GlobalSettings.ActiveSetting]; + + /* Settings have changed. Progress changes through system */ + ConfigurationInit(); + } +} + +uint8_t SettingsGetActiveById(void) { + return GlobalSettings.ActiveSetting; +} + +void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) { + SettingOut[0] = SettingsGetActiveById() + '0'; + SettingOut[1] = '\0'; +} + +bool SettingsSetActiveByName(const char* Setting) { + uint8_t SettingNr = Setting[0] - '0'; + + if ((Setting[1] == '\0') && (SettingNr < SETTINGS_COUNT)) { + SettingsSetActiveById(SettingNr); + return true; + } else { + return false; + } +} + diff --git a/Firmware/Chameleon-Mini/Settings.h b/Firmware/Chameleon-Mini/Settings.h new file mode 100644 index 00000000..59e675e7 --- /dev/null +++ b/Firmware/Chameleon-Mini/Settings.h @@ -0,0 +1,86 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef SETTINGS_H_ +#define SETTINGS_H_ + +#include "Button.h" +#include "Configuration.h" + +#define SETTINGS_COUNT 8 + +typedef struct { + ButtonActionEnum ButtonAction; + ConfigurationEnum Configuration; +} SettingsEntryType; + +typedef struct { + uint8_t ActiveSetting; + SettingsEntryType* ActiveSettingPtr; + SettingsEntryType Settings[SETTINGS_COUNT]; +} SettingsType; + +extern SettingsType GlobalSettings; + +void SettingsLoad(void); +void SettingsSave(void); + +void SettingsCycle(void); +void SettingsSetActiveById(uint8_t Setting); +uint8_t SettingsGetActiveById(void); +void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize); +bool SettingsSetActiveByName(const char* Setting); + +#endif /* SETTINGS_H_ */ diff --git a/Firmware/Chameleon-Mini/System.c b/Firmware/Chameleon-Mini/System.c new file mode 100644 index 00000000..7c6fe832 --- /dev/null +++ b/Firmware/Chameleon-Mini/System.c @@ -0,0 +1,145 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "System.h" +#include "LED.h" + +ISR(BADISR_vect) +{ + while(1); +} + +void SystemInit(void) +{ + if (RST.STATUS & RST_WDRF_bm) { + /* On Watchdog reset clear WDRF bit, disable watchdog + * and jump into bootloader */ + RST.STATUS = RST_WDRF_bm; + + CCP = CCP_IOREG_gc; + WDT.CTRL = WDT_CEN_bm; + + asm volatile ("jmp %0"::"i" (BOOT_SECTION_START + 0x1FC)); + } + + /* 32MHz system clock using internal RC and 32K DFLL*/ + OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm; + while(!(OSC.STATUS & OSC_RC32MRDY_bm)) + ; + while(!(OSC.STATUS & OSC_RC32KRDY_bm)) + ; + + OSC.DFLLCTRL = OSC_RC32MCREF_RC32K_gc; + DFLLRC32M.CTRL = DFLL_ENABLE_bm; + + CCP = CCP_IOREG_gc; + CLK.CTRL = CLK_SCLKSEL_RC32M_gc; + + /* Use TCE0 as system tick */ + TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1; + TCE0.CTRLA = TC_CLKSEL_DIV256_gc; + + /* Enable RTC with roughly 1kHz clock */ + CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm; + RTC.CTRL = RTC_PRESCALER_DIV1_gc; + + /* Enable EEPROM data memory mapping */ + NVM.CTRLB |= NVM_EEMAPEN_bm; +} + +void SystemReset(void) +{ + CCP = CCP_IOREG_gc; + RST.CTRL = RST_SWRST_bm; + +} + +void SystemEnterBootloader(void) +{ + /* Use Watchdog timer to reset into bootloader. */ + CCP = CCP_IOREG_gc; + WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; +} + + +void SystemStartUSBClock(void) +{ + /* 48MHz USB Clock using 12MHz XTAL */ + OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; + OSC.CTRL |= OSC_XOSCEN_bm; + while(!(OSC.STATUS & OSC_XOSCRDY_bm)) + ; + + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp); + + OSC.CTRL |= OSC_PLLEN_bm; + while(!(OSC.STATUS & OSC_PLLRDY_bm)) + ; +} + +void SystemStopUSBClock(void) +{ + /* Disable USB Clock to minimize power consumption */ + CLK.USBCTRL &= ~CLK_USBSEN_bm; + OSC.CTRL &= ~OSC_PLLEN_bm; + OSC.CTRL &= ~OSC_XOSCEN_bm; +} + +void SystemInterruptInit(void) +{ + /* Enable all interrupt levels */ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + sei(); +} diff --git a/Firmware/Chameleon-Mini/System.h b/Firmware/Chameleon-Mini/System.h new file mode 100644 index 00000000..63f7c74f --- /dev/null +++ b/Firmware/Chameleon-Mini/System.h @@ -0,0 +1,101 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#include +#include +#include +#include +#include +#include "Common.h" + +typedef uint16_t SystemRTCType; + +#define F_RTC 1000 +#define SYSTEM_MILLISECONDS_TO_RTC_CYCLES(x) \ + ( (uint16_t) ( (double) F_RTC * x / 1E3 + 0.5) ) + +#define SYSTEM_TICK_FREQ 10 +#define SYSTEM_TICK_MS (1000/SYSTEM_TICK_FREQ) + +void SystemInit(void); +void SystemReset(void); +void SystemEnterBootloader(void); +void SystemStartUSBClock(void); +void SystemStopUSBClock(void); +void SystemInterruptInit(void); +INLINE bool SystemTick100ms(void); +INLINE SystemRTCType SystemGetRTC(void); + + +INLINE SystemRTCType SystemGetRTC(void) +{ + return RTC.CNT; +} + +INLINE bool SystemTick100ms(void) +{ + if (TCE0.INTFLAGS & TC0_OVFIF_bm) { + TCE0.INTFLAGS = TC0_OVFIF_bm; + + return true; + } + + return false; +} + +#endif /* SYSTEM_H */ diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c new file mode 100644 index 00000000..5c497777 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -0,0 +1,334 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "CommandLine.h" + +#define CHAR_GET_MODE '?' /* ? */ +#define CHAR_SET_MODE '=' /* = */ +#define CHAR_EXEC_MODE '\0' /* */ + +#define IS_COMMAND_DELIMITER(c) ( \ + ((c) == CHAR_EXEC_MODE) || ((c) == CHAR_GET_MODE) || ((c) == CHAR_SET_MODE) \ +) + +#define IS_CHARACTER(c) ( \ + ( ((c) >= 'A') && ((c) <= 'Z') ) || \ + ( ((c) >= 'a') && ((c) <= 'z') ) || \ + ( ((c) >= '0') && ((c) <= '9') ) || \ + ( ((c) == '_') ) || \ + ( ((c) == CHAR_GET_MODE) || ((c) == CHAR_SET_MODE) ) \ +) + +#define IS_LOWERCASE(c) ( ((c) >= 'a') && ((c) <= 'z') ) +#define TO_UPPERCASE(c) ( (c) - 'a' + 'A' ) + +#define NO_FUNCTION ((void*) 0) + +#define STATUS_MESSAGE_TRAILER "\r\n" +#define OPTIONAL_ANSWER_TRAILER "\r\n" + +/* Include all command functions */ +#include "Commands.h" + +const PROGMEM CommandEntryType CommandTable[] = { + { + .Command = COMMAND_VERSION, + .ExecFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = CommandGetVersion, + }, + { + .Command = COMMAND_CONFIG, + .ExecFunc = CommandExecConfig, + .SetFunc = CommandSetConfig, + .GetFunc = CommandGetConfig + }, + { + .Command = COMMAND_UID, + .ExecFunc = NO_FUNCTION, + .SetFunc = CommandSetUid, + .GetFunc = CommandGetUid + }, + { + .Command = COMMAND_READONLY, + .ExecFunc = NO_FUNCTION, + .GetFunc = CommandGetReadOnly, + .SetFunc = CommandSetReadOnly + + }, + { + .Command = COMMAND_UPLOAD, + .ExecFunc = CommandExecUpload, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, + { + .Command = COMMAND_DOWNLOAD, + .ExecFunc = CommandExecDownload, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, + { + .Command = COMMAND_RESET, + .ExecFunc = CommandExecReset, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, +#ifdef SUPPORT_FIRMWARE_UPGRADE + { + .Command = COMMAND_UPGRADE, + .ExecFunc = CommandExecUpgrade, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, +#endif + { + .Command = COMMAND_MEMSIZE, + .ExecFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = CommandGetMemSize + }, + { + .Command = COMMAND_UIDSIZE, + .ExecFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = CommandGetUidSize + }, + { + .Command = COMMAND_BUTTON, + .ExecFunc = CommandExecButton, + .SetFunc = CommandSetButton, + .GetFunc = CommandGetButton + }, + { + .Command = COMMAND_SETTING, + .ExecFunc = NO_FUNCTION, + .SetFunc = CommandSetSetting, + .GetFunc = CommandGetSetting + }, + { + .Command = COMMAND_CLEAR, + .ExecFunc = CommandExecClear, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, + { + .Command = COMMAND_HELP, + .ExecFunc = CommandExecHelp, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, + { + .Command = COMMAND_RSSI, + .ExecFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = CommandGetRssi + }, + + + { /* This has to be last element */ + .Command = COMMAND_LIST_END, + .ExecFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + } +}; + +#define STATUS_TABLE_ENTRY(Id, Text) \ + { Id, STRINGIFY(Id) ":" Text } + +typedef struct { + CommandStatusIdType Id; + CommandStatusMessageType Message; +} CommandStatusType; + +static const CommandStatusType PROGMEM StatusTable[] = { + STATUS_TABLE_ENTRY(COMMAND_INFO_OK_ID, COMMAND_INFO_OK), + STATUS_TABLE_ENTRY(COMMAND_INFO_OK_WITH_TEXT_ID, COMMAND_INFO_OK_WITH_TEXT), + STATUS_TABLE_ENTRY(COMMAND_INFO_XMODEM_WAIT_ID, COMMAND_INFO_XMODEM_WAIT), + STATUS_TABLE_ENTRY(COMMAND_ERR_UNKNOWN_CMD_ID, COMMAND_ERR_UNKNOWN_CMD), + STATUS_TABLE_ENTRY(COMMAND_ERR_INVALID_USAGE_ID, COMMAND_ERR_INVALID_USAGE), + STATUS_TABLE_ENTRY(COMMAND_ERR_INVALID_PARAM_ID, COMMAND_ERR_INVALID_PARAM), +}; + +static uint16_t BufferIdx; + +static const char* GetStatusMessageP(CommandStatusIdType StatusId) +{ + uint8_t i; + + for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) { + if (pgm_read_byte(&StatusTable[i].Id) == StatusId) + return StatusTable[i].Message; + } + + return (void*) 0; +} + +static CommandStatusIdType CallCommandFunc( + const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) { + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Call appropriate function depending on CommandDelimiter */ + if (CommandDelimiter == CHAR_GET_MODE) { + CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc); + if (GetFunc != NO_FUNCTION) { + return GetFunc(pTerminalBuffer); + } + } else if (CommandDelimiter == CHAR_SET_MODE) { + CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc); + if (SetFunc != NO_FUNCTION) { + return SetFunc(pParam); + } + } else if (CommandDelimiter == CHAR_EXEC_MODE){ + CommandExecFuncType ExecFunc = pgm_read_ptr(&CommandEntry->ExecFunc); + if (ExecFunc != NO_FUNCTION) { + return ExecFunc(pTerminalBuffer); + } + } else { + /* This should not happen (TM) */ + } + + /* This delimiter has not been registered with this command */ + return COMMAND_ERR_INVALID_USAGE_ID; +} + +static void DecodeCommand(void) +{ + uint8_t i; + bool CommandFound = false; + CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID; + char* pTerminalBuffer = (char*) TerminalBuffer; + + /* Do some sanity check first */ + if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) { + char* pCommandDelimiter = pTerminalBuffer; + char CommandDelimiter = '\0'; + + /* Search for command delimiter, store it and replace with '\0' */ + while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter))) + pCommandDelimiter++; + + CommandDelimiter = *pCommandDelimiter; + *pCommandDelimiter = '\0'; + + /* Search in command table */ + for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) { + if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) { + /* Command found. Clear buffer, and call appropriate function */ + char* pParam = ++pCommandDelimiter; + + pTerminalBuffer[0] = '\0'; + CommandFound = true; + + StatusId = CallCommandFunc(&CommandTable[i], CommandDelimiter, pParam); + + break; + } + } + } + + /* Send command status message */ + TerminalSendStringP(GetStatusMessageP(StatusId)); + TerminalSendStringP(PSTR(STATUS_MESSAGE_TRAILER)); + + if (CommandFound && (pTerminalBuffer[0] != '\0') ) { + /* Send optional answer */ + TerminalSendString(pTerminalBuffer); + TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER)); + } +} + +void CommandLineInit(void) +{ + BufferIdx = 0; +} + +bool CommandLineProcessByte(uint8_t Byte) { + if (IS_CHARACTER(Byte)){ + /* Store uppercase character */ + if (IS_LOWERCASE(Byte)) { + Byte = TO_UPPERCASE(Byte); + } + + /* Prevent buffer overflow and account for '\0' */ + if (BufferIdx < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) { + TerminalBuffer[BufferIdx++] = Byte; + } + }else if (Byte == '\r') { + /* Process on \r. Terminate string and decode. */ + TerminalBuffer[BufferIdx] = '\0'; + BufferIdx = 0; + + DecodeCommand(); + }else if (Byte == '\b') { + /* Backspace. Delete last character in buffer. */ + if (BufferIdx > 0) { + BufferIdx--; + } + } else if (Byte == 0x1B){ + /* Drop buffer on escape */ + BufferIdx = 0; + } else { + /* Ignore other chars */ + } + + return true; +} + +void CommandLineTick(void) +{ + +} diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.h b/Firmware/Chameleon-Mini/Terminal/CommandLine.h new file mode 100644 index 00000000..aee76dd4 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.h @@ -0,0 +1,66 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef COMMANDLINE_H_ +#define COMMANDLINE_H_ + +#include "Terminal.h" + +void CommandLineInit(void); +bool CommandLineProcessByte(uint8_t Byte); +void CommandLineTick(void); + + +#endif /* COMMANDLINE_H_ */ diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c new file mode 100644 index 00000000..e49f665f --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -0,0 +1,299 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Commands.h" +#include +#include +#include "XModem.h" +#include "../Settings.h" +#include "../Chameleon-Mini.h" +#include "../LUFA/Version.h" +#include "../Configuration.h" +#include "../Random.h" +#include "../Memory.h" +#include "../System.h" +#include "../Button.h" +#include "../AntennaLevel.h" + +extern const PROGMEM CommandEntryType CommandTable[]; + +CommandStatusIdType CommandGetVersion(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR( + "Chameleon-Mini %S using LUFA %S compiled with AVR-GCC %S" + ), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__) + ); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetConfig(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + PSTR("%s"), ActiveConfiguration.ConfigurationName); + + return COMMAND_INFO_OK_WITH_TEXT_ID; + +} + +CommandStatusIdType CommandSetConfig(const char* InParam) +{ + if (ConfigurationSetByName(InParam)) { + SettingsSave(); + return COMMAND_INFO_OK_ID; + } else { + return COMMAND_ERR_INVALID_PARAM_ID; + } +} + +CommandStatusIdType CommandExecConfig(char* OutMessage) +{ + ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetUid(char* OutParam) +{ + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + + ApplicationGetUid(UidBuffer); + + BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, + UidBuffer, UidSize); + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandSetUid(const char* InParam) +{ + uint8_t UidBuffer[COMMAND_UID_BUFSIZE]; + uint16_t UidSize = ActiveConfiguration.UidSize; + + if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) { + /* Load with random bytes */ + for (uint8_t i=0; iCommand) != 0) { + const char* CommandName = EntryPtr->Command; + char c; + + while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) { + *OutMessage++ = c; + CommandName++; + ByteCount--; + } + + *OutMessage++ = ','; + ByteCount--; + + EntryPtr++; + } + + *--OutMessage = '\0'; + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} + +CommandStatusIdType CommandGetRssi(char* OutParam) +{ + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, + PSTR("%5u mV"), AntennaLevelGet()); + + + return COMMAND_INFO_OK_WITH_TEXT_ID; +} diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.h b/Firmware/Chameleon-Mini/Terminal/Commands.h new file mode 100644 index 00000000..2ca30d70 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/Commands.h @@ -0,0 +1,154 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef COMMANDS_H_ +#define COMMANDS_H_ + +#include "../Common.h" + +#define MAX_COMMAND_LENGTH 16 +#define MAX_STATUS_LENGTH 32 + + +#define COMMAND_INFO_OK_ID 100 +#define COMMAND_INFO_OK "OK" +#define COMMAND_INFO_OK_WITH_TEXT_ID 101 +#define COMMAND_INFO_OK_WITH_TEXT "OK WITH TEXT" +#define COMMAND_INFO_XMODEM_WAIT_ID 110 +#define COMMAND_INFO_XMODEM_WAIT "WAITING FOR XMODEM" +#define COMMAND_ERR_UNKNOWN_CMD_ID 200 +#define COMMAND_ERR_UNKNOWN_CMD "UNKNOWN COMMAND" +#define COMMAND_ERR_INVALID_USAGE_ID 201 +#define COMMAND_ERR_INVALID_USAGE "INVALID COMMAND USAGE" +#define COMMAND_ERR_INVALID_PARAM_ID 202 +#define COMMAND_ERR_INVALID_PARAM "INVALID PARAMETER" + + +#define COMMAND_CHAR_TRUE '1' +#define COMMAND_CHAR_FALSE '0' + +#define COMMAND_UID_BUFSIZE 32 + +typedef uint8_t CommandStatusIdType; +typedef const char CommandStatusMessageType[MAX_STATUS_LENGTH]; + +typedef CommandStatusIdType (*CommandExecFuncType) (char* OutMessage); +typedef CommandStatusIdType (*CommandSetFuncType) (const char* InParam); +typedef CommandStatusIdType (*CommandGetFuncType) (char* OutParam); + +typedef struct { + char Command[MAX_COMMAND_LENGTH]; + CommandExecFuncType ExecFunc; + CommandSetFuncType SetFunc; + CommandGetFuncType GetFunc; +} CommandEntryType; + +#define COMMAND_VERSION "VERSION" +CommandStatusIdType CommandGetVersion(char* OutParam); + +#define COMMAND_CONFIG "CONFIG" +CommandStatusIdType CommandExecConfig(char* OutMessage); +CommandStatusIdType CommandGetConfig(char* OutParam); +CommandStatusIdType CommandSetConfig(const char* InParam); + +#define COMMAND_UID "UID" +#define COMMAND_UID_RANDOM "RANDOM" +CommandStatusIdType CommandGetUid(char* OutParam); +CommandStatusIdType CommandSetUid(const char* InParam); + +#define COMMAND_READONLY "READONLY" +CommandStatusIdType CommandGetReadOnly(char* OutParam); +CommandStatusIdType CommandSetReadOnly(const char* InParam); + +#define COMMAND_UPLOAD "UPLOAD" +CommandStatusIdType CommandExecUpload(char* OutMessage); + +#define COMMAND_DOWNLOAD "DOWNLOAD" +CommandStatusIdType CommandExecDownload(char* OutMessage); + +#define COMMAND_RESET "RESET" +CommandStatusIdType CommandExecReset(char* OutMessage); + +#define COMMAND_UPGRADE "UPGRADE" +CommandStatusIdType CommandExecUpgrade(char* OutMessage); + +#define COMMAND_MEMSIZE "MEMSIZE" +CommandStatusIdType CommandGetMemSize(char* OutParam); + +#define COMMAND_UIDSIZE "UIDSIZE" +CommandStatusIdType CommandGetUidSize(char* OutParam); + +#define COMMAND_BUTTON "BUTTON" +CommandStatusIdType CommandExecButton(char* OutMessage); +CommandStatusIdType CommandGetButton(char* OutParam); +CommandStatusIdType CommandSetButton(const char* InParam); + +#define COMMAND_SETTING "SETTING" +CommandStatusIdType CommandGetSetting(char* OutParam); +CommandStatusIdType CommandSetSetting(const char* InParam); + +#define COMMAND_CLEAR "CLEAR" +CommandStatusIdType CommandExecClear(char* OutParam); + +#define COMMAND_HELP "HELP" +CommandStatusIdType CommandExecHelp(char* OutMessage); + +#define COMMAND_RSSI "RSSI" +CommandStatusIdType CommandGetRssi(char* OutParam); + +#define COMMAND_LIST_END "" +/* Defines the end of command list. This is no actual command */ + +#endif /* COMMANDS_H_ */ diff --git a/Firmware/Chameleon-Mini/Terminal/Terminal.c b/Firmware/Chameleon-Mini/Terminal/Terminal.c new file mode 100644 index 00000000..5e20bd02 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/Terminal.c @@ -0,0 +1,220 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "Terminal.h" +#include "../System.h" +#include "../LED.h" + +#include "../LUFADescriptors.h" + +#define INIT_DELAY (2000 / SYSTEM_TICK_MS) + + +USB_ClassInfo_CDC_Device_t TerminalHandle = { + .Config = { + .ControlInterfaceNumber = 0, + .DataINEndpoint = { + .Address = CDC_TX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, .DataOUTEndpoint = { + .Address = CDC_RX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, .NotificationEndpoint = { + .Address = CDC_NOTIFICATION_EPADDR, + .Size = CDC_NOTIFICATION_EPSIZE, + .Banks = 1, + }, + } +}; + +uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE]; +TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED; +static uint8_t TerminalInitDelay = INIT_DELAY; + +void TerminalSendString(const char* s) { + CDC_Device_SendString(&TerminalHandle, s); +} + +void TerminalSendStringP(const char* s) { + char c; + + while( (c = pgm_read_byte(s++)) != '\0' ) { + TerminalSendChar(c); + } +} + +#if 0 +void TerminalSendBuffer(void* Buffer, uint16_t ByteCount) +{ + char* pTerminalBuffer = (char*) TerminalBuffer; + + BufferToHexString(pTerminalBuffer, sizeof(TerminalBuffer), Buffer, ByteCount); + + TerminalSendString(pTerminalBuffer); +} +#endif + + + +void TerminalSendBlock(void* Buffer, uint16_t ByteCount) +{ + CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount); +} + + +static void ProcessByte(void) { + int16_t Byte = CDC_Device_ReceiveByte(&TerminalHandle); + + if (Byte >= 0) { + /* Byte received */ + LEDPulse(LED_RED); + + if (XModemProcessByte(Byte)) { + /* XModem handled the byte */ + } else if (CommandLineProcessByte(Byte)) { + /* CommandLine handled the byte */ + } + } +} + +static void SenseVBus(void) +{ + switch(TerminalState) { + case TERMINAL_UNINITIALIZED: + if (TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK) { + /* Not initialized and VBUS sense high */ + TerminalInitDelay = INIT_DELAY; + TerminalState = TERMINAL_INITIALIZING; + } + break; + + case TERMINAL_INITIALIZING: + if (--TerminalInitDelay == 0) { + SystemStartUSBClock(); + USB_Init(); + TerminalState = TERMINAL_INITIALIZED; + } + break; + + case TERMINAL_INITIALIZED: + if (!(TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK)) { + /* Initialized and VBUS sense low */ + TerminalInitDelay = INIT_DELAY; + TerminalState = TERMINAL_UNITIALIZING; + } + break; + + case TERMINAL_UNITIALIZING: + if (--TerminalInitDelay == 0) { + USB_Disable(); + SystemStopUSBClock(); + TerminalState = TERMINAL_UNINITIALIZED; + } + break; + + default: + break; + } +} + +void TerminalInit(void) +{ + TERMINAL_VBUS_PORT.DIRCLR = TERMINAL_VBUS_MASK; +} + +void TerminalTask(void) +{ + CDC_Device_USBTask(&TerminalHandle); + USB_USBTask(); + + ProcessByte(); +} + +void TerminalTick(void) +{ + SenseVBus(); + + XModemTick(); + CommandLineTick(); +} + +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ + LEDSetOn(LED_GREEN); +} + +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ + LEDSetOff(LED_GREEN); +} + + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + CDC_Device_ConfigureEndpoints(&TerminalHandle); +} + +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&TerminalHandle); +} + + diff --git a/Firmware/Chameleon-Mini/Terminal/Terminal.h b/Firmware/Chameleon-Mini/Terminal/Terminal.h new file mode 100644 index 00000000..840d55e0 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/Terminal.h @@ -0,0 +1,100 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef TERMINAL_H_ +#define TERMINAL_H_ + +#include "../Common.h" +#include "../LUFA/Drivers/USB/USB.h" +#include "XModem.h" +#include "CommandLine.h" + +#define TERMINAL_VBUS_PORT PORTD +#define TERMINAL_VBUS_MASK PIN5_bm + +#define TERMINAL_BUFFER_SIZE 256 + +typedef enum { + TERMINAL_UNINITIALIZED, + TERMINAL_INITIALIZING, + TERMINAL_INITIALIZED, + TERMINAL_UNITIALIZING +} TerminalStateEnum; + +extern uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE]; +extern USB_ClassInfo_CDC_Device_t TerminalHandle; +extern TerminalStateEnum TerminalState; + +void TerminalInit(void); +void TerminalTask(void); +void TerminalTick(void); + +/*void TerminalSendBuffer(void* Buffer, uint16_t ByteCount);*/ +INLINE void TerminalSendByte(uint8_t Byte); +void TerminalSendBlock(void* Buffer, uint16_t ByteCount); + +INLINE void TerminalSendChar(char c); +void TerminalSendString(const char* s); +void TerminalSendStringP(const char* s); + +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); } +INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); } + +#endif /* TERMINAL_H_ */ diff --git a/Firmware/Chameleon-Mini/Terminal/XModem.c b/Firmware/Chameleon-Mini/Terminal/XModem.c new file mode 100644 index 00000000..66074e57 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/XModem.c @@ -0,0 +1,300 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#include "XModem.h" +#include "Terminal.h" + +#define BYTE_NAK 0x15 +#define BYTE_SOH 0x01 +#define BYTE_ACK 0x06 +#define BYTE_CAN 0x18 +#define BYTE_EOF 0x1A +#define BYTE_EOT 0x04 + +#define XMODEM_BLOCK_SIZE 128 + +#define RECV_INIT_TIMEOUT 5 /* x 100ms */ +#define RECV_INIT_COUNT 20 /* 10 secs */ +#define SEND_INIT_TIMEOUT 100 /* x 100ms */ + +#define FIRST_FRAME_NUMBER 1 +#define CHECKSUM_INIT_VALUE 0 + +static enum { + STATE_OFF, + STATE_RECEIVE_INIT, + STATE_RECEIVE_WAIT, + STATE_RECEIVE_FRAMENUM1, + STATE_RECEIVE_FRAMENUM2, + STATE_RECEIVE_DATA, + STATE_RECEIVE_PROCESS, + STATE_SEND_INIT, + STATE_SEND_WAIT, + STATE_SEND_EOT +} State = STATE_OFF; + +static uint8_t CurrentFrameNumber; +static uint8_t ReceivedFrameNumber; +static uint8_t Checksum; +static uint8_t RetryCount; +static uint8_t RetryTimeout; +static uint16_t BufferIdx; +static uint32_t BlockAddress; + +static XModemCallbackType CallbackFunc; + +static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) { + uint8_t Checksum = CHECKSUM_INIT_VALUE; + uint8_t* DataPtr = (uint8_t*) Buffer; + + while(ByteCount--) { + Checksum += *DataPtr++; + } + + return Checksum; +} + +void XModemReceive(XModemCallbackType TheCallbackFunc) +{ + State = STATE_RECEIVE_INIT; + CurrentFrameNumber = FIRST_FRAME_NUMBER; + RetryCount = RECV_INIT_COUNT; + RetryTimeout = RECV_INIT_TIMEOUT; + BlockAddress = 0; + + CallbackFunc = TheCallbackFunc; +} + +void XModemSend(XModemCallbackType TheCallbackFunc) +{ + State = STATE_SEND_INIT; + RetryTimeout = SEND_INIT_TIMEOUT; + BlockAddress = 0; + + CallbackFunc = TheCallbackFunc; +} + +bool XModemProcessByte(uint8_t Byte) +{ + switch(State) { + case STATE_RECEIVE_INIT: + case STATE_RECEIVE_WAIT: + if (Byte == BYTE_SOH) { + /* Next frame incoming */ + BufferIdx = 0; + Checksum = CHECKSUM_INIT_VALUE; + State = STATE_RECEIVE_FRAMENUM1; + } else if (Byte == BYTE_EOT) { + /* Transmission finished */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_CAN) { + /* Cancel transmission */ + State = STATE_OFF; + } else { + /* Ignore other bytes */ + } + + break; + + case STATE_RECEIVE_FRAMENUM1: + /* Store frame number */ + ReceivedFrameNumber = Byte; + State = STATE_RECEIVE_FRAMENUM2; + break; + + case STATE_RECEIVE_FRAMENUM2: + if (Byte == (255 - ReceivedFrameNumber)) { + /* frame-number check passed. */ + State = STATE_RECEIVE_DATA; + } else { + /* Something went wrong. Try to recover by sending NAK */ + TerminalSendByte(BYTE_NAK); + State = STATE_RECEIVE_WAIT; + } + + break; + + case STATE_RECEIVE_DATA: + /* Process byte and update checksum */ + TerminalBuffer[BufferIdx++] = Byte; + + if (BufferIdx == XMODEM_BLOCK_SIZE) { + /* Block full */ + State = STATE_RECEIVE_PROCESS; + } + + break; + + case STATE_RECEIVE_PROCESS: + if (ReceivedFrameNumber == CurrentFrameNumber) { + /* This is the expected frame. Calculate and verify checksum */ + + if (CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE) == Byte) { + /* Checksum is valid. Pass received data to callback function */ + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + /* Proceed to next frame and send ACK */ + CurrentFrameNumber++; + BlockAddress += XMODEM_BLOCK_SIZE; + TerminalSendChar(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + } else { + /* Application signals to cancel the transmission */ + TerminalSendByte(BYTE_CAN); + TerminalSendByte(BYTE_CAN); + State = STATE_OFF; + } + } else { + /* Data seems to be damaged */ + TerminalSendByte(BYTE_NAK); + State = STATE_RECEIVE_WAIT; + } + } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) { + /* This is a retransmission */ + TerminalSendByte(BYTE_ACK); + State = STATE_RECEIVE_WAIT; + } else { + /* This frame is completely out of order. Just cancel */ + TerminalSendByte(BYTE_CAN); + State = STATE_OFF; + } + + break; + + case STATE_SEND_INIT: + /* Start sending on NAK */ + if (Byte == BYTE_NAK) { + CurrentFrameNumber = FIRST_FRAME_NUMBER - 1; + Byte = BYTE_ACK; + } + + /* Fallthrough */ + + case STATE_SEND_WAIT: + if (Byte == BYTE_CAN) { + /* Cancel */ + TerminalSendByte(BYTE_ACK); + State = STATE_OFF; + } else if (Byte == BYTE_ACK) { + /* Acknowledge. Proceed to next frame, get data and calc checksum */ + CurrentFrameNumber++; + + if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) { + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + + BlockAddress += XMODEM_BLOCK_SIZE; + } else { + TerminalSendByte(BYTE_EOT); + State = STATE_SEND_EOT; + } + } else if (Byte == BYTE_NAK){ + /* Resend frame */ + TerminalSendByte(BYTE_SOH); + TerminalSendByte(CurrentFrameNumber); + TerminalSendByte(255 - CurrentFrameNumber); + TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE); + TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE)); + } else { + /* Ignore other chars */ + } + + break; + + case STATE_SEND_EOT: + /* Receive Ack */ + State = STATE_OFF; + break; + + default: + return false; + break; + } + + return true; +} + +void XModemTick(void) +{ + /* Timeouts go here */ + switch(State) { + case STATE_RECEIVE_INIT: + if (RetryTimeout-- == 0) { + if (RetryCount-- > 0) { + /* Put out communication request */ + TerminalSendChar(BYTE_NAK); + } else { + /* Just shut off after some time. */ + State = STATE_OFF; + } + + RetryTimeout = RECV_INIT_TIMEOUT; + } + break; + + case STATE_SEND_INIT: + if (RetryTimeout-- == 0) { + /* Abort */ + State = STATE_OFF; + } + break; + + default: + break; + } +} diff --git a/Firmware/Chameleon-Mini/Terminal/XModem.h b/Firmware/Chameleon-Mini/Terminal/XModem.h new file mode 100644 index 00000000..fa35d204 --- /dev/null +++ b/Firmware/Chameleon-Mini/Terminal/XModem.h @@ -0,0 +1,69 @@ +/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL + * AUTHORS"). All rights reserved. + * + * DEFINITIONS: + * + * "WORK": The material covered by this license includes the schematic + * diagrams, designs, circuit or circuit board layouts, mechanical + * drawings, documentation (in electronic or printed form), source code, + * binary software, data files, assembled devices, and any additional + * material provided by the ORIGINAL AUTHORS in the ChameleonMini project + * (https://github.com/skuep/ChameleonMini). + * + * LICENSE TERMS: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK are permitted provided that the + * following conditions are met: + * + * Redistributions and use of this WORK, with or without modification, or + * of substantial portions of this WORK must include the above copyright + * notice, this list of conditions, the below disclaimer, and the following + * attribution: + * + * "Based on ChameleonMini an open-source RFID emulator: + * https://github.com/skuep/ChameleonMini" + * + * The attribution must be clearly visible to a user, for example, by being + * printed on the circuit board and an enclosure, and by being displayed by + * software (both in binary and source code form). + * + * At any time, the majority of the ORIGINAL AUTHORS may decide to give + * written permission to an entity to use or redistribute the WORK (with or + * without modification) WITHOUT having to include the above copyright + * notice, this list of conditions, the below disclaimer, and the above + * attribution. + * + * DISCLAIMER: + * + * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the hardware, software, and + * documentation should not be interpreted as representing official + * policies, either expressed or implied, of the ORIGINAL AUTHORS. + */ + +#ifndef XMODEM_H_ +#define XMODEM_H_ + +#include "../Common.h" + +typedef bool (*XModemCallbackType) (void* ByteBuffer, uint32_t BlockAddress, uint16_t ByteCount); + +void XModemReceive(XModemCallbackType CallbackFunc); +void XModemSend(XModemCallbackType CallbackFunc); + +bool XModemProcessByte(uint8_t Byte); +void XModemTick(void); + +#endif /* TERMINALXMODEM_H_ */ diff --git a/Firmware/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c b/Firmware/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c new file mode 100644 index 00000000..dd703b5e --- /dev/null +++ b/Firmware/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c @@ -0,0 +1,61 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Special application to extract an EEPROM image stored in FLASH memory, and + * copy it to the device EEPROM. This application is designed to be used with + * the HID build system module of LUFA to program the EEPROM of a target device + * that uses the HID bootloader protocol, which does not have native EEPROM + * programming support. + */ + +#include +#include +#include + +/* References to the binary EEPROM data linked in the AVR's FLASH memory space */ +extern const char _binary_InputEEData_bin_start[]; +extern const char _binary_InputEEData_bin_end[]; +extern const char _binary_InputEEData_bin_size[]; + +/* Friendly names for the embedded binary data stored in FLASH memory space */ +#define InputEEData _binary_InputEEData_bin_start +#define InputEEData_size ((int)_binary_InputEEData_bin_size) + +int main(void) +{ + /* Copy out the embedded EEPROM data from FLASH to EEPROM memory space */ + for (uint16_t i = 0; i < InputEEData_size; i++) + eeprom_update_byte((uint8_t*)i, pgm_read_byte(&InputEEData[i])); + + /* Infinite loop once complete */ + for (;;); +} diff --git a/Firmware/LUFA/Build/HID_EEPROM_Loader/makefile b/Firmware/LUFA/Build/HID_EEPROM_Loader/makefile new file mode 100644 index 00000000..6225b2bf --- /dev/null +++ b/Firmware/LUFA/Build/HID_EEPROM_Loader/makefile @@ -0,0 +1,42 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# -------------------------------------- +# LUFA Project Makefile. +# -------------------------------------- + +# Run "make help" for target help. + +MCU = at90usb1287 +ARCH = AVR8 +F_CPU = 1000000 +F_USB = $(F_CPU) +OPTIMIZATION = s +TARGET = HID_EEPROM_Loader +SRC = $(TARGET).c +LUFA_PATH = ../../../LUFA +CC_FLAGS = +LD_FLAGS = +OBJECT_FILES = InputEEData.o + +# Default target +all: + +# Determine the AVR sub-architecture of the build main application object file +FIND_AVR_SUBARCH = avr$(shell avr-objdump -f $(TARGET).o | grep architecture | cut -d':' -f3 | cut -d',' -f1) + +# Create a linkable object file with the input binary EEPROM data stored in the FLASH section +InputEEData.o: InputEEData.bin $(TARGET).o $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a object file \"$@\" + avr-objcopy -I binary -O elf32-avr -B $(call FIND_AVR_SUBARCH) --rename-section .data=.progmem.data,contents,alloc,readonly,data $< $@ + +# Include LUFA build script makefiles +include $(LUFA_PATH)/Build/lufa_core.mk +include $(LUFA_PATH)/Build/lufa_build.mk +include $(LUFA_PATH)/Build/lufa_cppcheck.mk +include $(LUFA_PATH)/Build/lufa_doxygen.mk +include $(LUFA_PATH)/Build/lufa_hid.mk diff --git a/Firmware/LUFA/Build/lufa_atprogram.mk b/Firmware/LUFA/Build/lufa_atprogram.mk new file mode 100644 index 00000000..eba9b0ad --- /dev/null +++ b/Firmware/LUFA/Build/lufa_atprogram.mk @@ -0,0 +1,103 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += ATPROGRAM +LUFA_BUILD_TARGETS += atprogram atprogram-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += ATPROGRAM_PROGRAMMER ATPROGRAM_INTERFACE ATPROGRAM_PORT +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA ATPROGRAM Programmer Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device using the Atmel atprogram +# utility in AVR Studio 5.x and Atmel Studio 6.0 onwards. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# atprogram - Program target FLASH with application using +# atprogram +# atprogram-ee - Program target EEPROM with application data +# using atprogram +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# ATPROGRAM_PROGRAMMER - Name of programming hardware to use +# ATPROGRAM_INTERFACE - Name of programming interface to use +# ATPROGRAM_PORT - Name of communication port to use +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +ATPROGRAM_PROGRAMMER ?= jtagice3 +ATPROGRAM_INTERFACE ?= jtag +ATPROGRAM_PORT ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, ATPROGRAM_PROGRAMMER) +$(call ERROR_IF_EMPTY, ATPROGRAM_INTERFACE) + +# Output Messages +MSG_ATPROGRAM_CMD := ' [ATPRGRM] :' + +# Construct base atprogram command flags +BASE_ATPROGRAM_FLAGS := --tool $(ATPROGRAM_PROGRAMMER) --interface $(ATPROGRAM_INTERFACE) --device $(MCU) +ifneq ($(ATPROGRAM_PORT),) + BASE_ATPROGRAM_FLAGS += --port $(ATPROGRAM_PORT) +endif + +# Construct the flags to use for the various memory spaces +ifeq ($(ARCH), AVR8) + ATPROGRAM_FLASH_FLAGS := --chiperase --flash + ATPROGRAM_EEPROM_FLAGS := --eeprom +else ifeq ($(ARCH), XMEGA) + ATPROGRAM_FLASH_FLAGS := --erase --flash + ATPROGRAM_EEPROM_FLAGS := --eeprom +else ifeq ($(ARCH), UC3) + ATPROGRAM_FLASH_FLAGS := --erase + ATPROGRAM_EEPROM_FLAGS := --eeprom +else + $(error Unsupported architecture "$(ARCH)") +endif + +# Programs in the target FLASH memory using ATPROGRAM +atprogram: $(TARGET).elf $(MAKEFILE_LIST) + @echo $(MSG_ATPROGRAM_CMD) Programming device \"$(MCU)\" FLASH using \"$(ATPROGRAM_PROGRAMMER)\" + atprogram $(BASE_ATPROGRAM_FLAGS) program $(ATPROGRAM_FLASH_FLAGS) --file $< + +# Programs in the target EEPROM memory using ATPROGRAM +atprogram-ee: $(TARGET).elf $(MAKEFILE_LIST) + @echo $(MSG_ATPROGRAM_CMD) Programming device \"$(MCU)\" EEPROM using \"$(ATPROGRAM_PROGRAMMER)\" + atprogram $(BASE_ATPROGRAM_FLAGS) program $(ATPROGRAM_EEPROM_FLAGS) --file $< + +# Phony build targets for this module +.PHONY: atprogram atprogram-ee diff --git a/Firmware/LUFA/Build/lufa_avrdude.mk b/Firmware/LUFA/Build/lufa_avrdude.mk new file mode 100644 index 00000000..f03854af --- /dev/null +++ b/Firmware/LUFA/Build/lufa_avrdude.mk @@ -0,0 +1,86 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += AVRDUDE +LUFA_BUILD_TARGETS += avrdude avrdude-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += AVRDUDE_PROGRAMMER AVRDUDE_PORT AVRDUDE_FLAGS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA AVRDUDE Programmer Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device using the open source +# avr-dude utility. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# avrdude - Program target FLASH with application using +# avrdude +# avrdude-ee - Program target EEPROM with application data +# using avrdude +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# AVRDUDE_PROGRAMMER - Name of programming hardware to use +# AVRDUDE_PORT - Name of communication port to use +# AVRDUDE_FLAGS - Flags to pass to avr-dude +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +AVRDUDE_PROGRAMMER ?= jtagicemkii +AVRDUDE_PORT ?= usb +AVRDUDE_FLAGS ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, AVRDUDE_PROGRAMMER) +$(call ERROR_IF_EMPTY, AVRDUDE_PORT) + +# Output Messages +MSG_AVRDUDE_CMD := ' [AVRDUDE] :' + +# Construct base avrdude command flags +BASE_AVRDUDE_FLAGS := -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# Programs in the target FLASH memory using AVRDUDE +avrdude: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_AVRDUDE_CMD) Programming device \"$(MCU)\" FLASH using \"$(AVRDUDE_PROGRAMMER)\" on port \"$(AVRDUDE_PORT)\" + avrdude $(BASE_AVRDUDE_FLAGS) -U flash:w:$< $(AVRDUDE_FLAGS) + +# Programs in the target EEPROM memory using AVRDUDE +avrdude-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_AVRDUDE_CMD) Programming device \"$(MCU)\" EEPROM using \"$(AVRDUDE_PROGRAMMER)\" on port \"$(AVRDUDE_PORT)\" + avrdude $(BASE_AVRDUDE_FLAGS) -U eeprom:w:$< $(AVRDUDE_FLAGS) + +# Phony build targets for this module +.PHONY: avrdude avrdude-ee diff --git a/Firmware/LUFA/Build/lufa_build.mk b/Firmware/LUFA/Build/lufa_build.mk new file mode 100644 index 00000000..c2f21070 --- /dev/null +++ b/Firmware/LUFA/Build/lufa_build.mk @@ -0,0 +1,343 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += BUILD +LUFA_BUILD_TARGETS += size symbol-sizes all lib elf bin hex lss clean mostlyclean +LUFA_BUILD_MANDATORY_VARS += TARGET ARCH MCU SRC F_USB LUFA_PATH +LUFA_BUILD_OPTIONAL_VARS += BOARD OPTIMIZATION C_STANDARD CPP_STANDARD F_CPU C_FLAGS CPP_FLAGS ASM_FLAGS CC_FLAGS LD_FLAGS OBJDIR OBJECT_FILES DEBUG_TYPE DEBUG_LEVEL LINKER_RELAXATIONS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA GCC Compiler Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to build a C, C++ and/or Assembly application +# via the AVR-GCC compiler. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# size - List built application size +# symbol-sizes - Print application symbols from the binary ELF +# file as a list sorted by size in bytes +# all - Build application and list size +# lib - Build and archive source files into a library +# elf - Build application ELF debug object file +# bin - Build application BIN binary object file +# hex - Build application HEX object file +# lss - Build application LSS assembly listing file +# clean - Remove all project intermediatary and binary +# output files +# mostlyclean - Remove intermediatary output files, but +# preserve binaries +# .s - Compile C/C++ source file into an assembly file +# for manual code inspection +# +# MANDATORY PARAMETERS: +# +# TARGET - Application name +# ARCH - Device architecture name +# MCU - Microcontroller device model name +# SRC - List of input source files (*.c, *.cpp, *.S) +# F_USB - Speed of the input clock of the USB controller +# in Hz +# LUFA_PATH - Path to the LUFA library core +# +# OPTIONAL PARAMETERS: +# +# BOARD - LUFA board hardware +# OPTIMIZATION - Optimization level +# C_STANDARD - C Language Standard to use +# CPP_STANDARD - C++ Language Standard to use +# F_CPU - Speed of the CPU, in Hz +# C_FLAGS - Flags to pass to the C compiler only +# CPP_FLAGS - Flags to pass to the C++ compiler only +# ASM_FLAGS - Flags to pass to the assembler only +# CC_FLAGS - Common flags to pass to the C/C++ compiler and +# assembler +# LD_FLAGS - Flags to pass to the linker +# LINKER_RELAXATIONS - Enable or disable linker relaxations to +# decrease binary size (note: can cause link +# failures on systems with an unpatched binutils) +# OBJDIR - Directory for the output object and dependency +# files; if equal to ".", the output files will +# be generated in the same folder as the sources +# OBJECT_FILES - Extra object files to link in to the binaries +# DEBUG_FORMAT - Format of the debugging information to +# generate in the compiled object files +# DEBUG_LEVEL - Level the debugging information to generate in +# the compiled object files +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +BOARD ?= NONE +OPTIMIZATION ?= s +F_CPU ?= +C_STANDARD ?= gnu99 +CPP_STANDARD ?= gnu++98 +C_FLAGS ?= +CPP_FLAGS ?= +ASM_FLAGS ?= +CC_FLAGS ?= +OBJDIR ?= . +OBJECT_FILES ?= +DEBUG_FORMAT ?= dwarf-2 +DEBUG_LEVEL ?= 2 +LINKER_RELAXATIONS ?= Y + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, ARCH) +$(call ERROR_IF_EMPTY, F_USB) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_EMPTY, BOARD) +$(call ERROR_IF_EMPTY, OPTIMIZATION) +$(call ERROR_IF_EMPTY, C_STANDARD) +$(call ERROR_IF_EMPTY, CPP_STANDARD) +$(call ERROR_IF_EMPTY, OBJDIR) +$(call ERROR_IF_EMPTY, DEBUG_FORMAT) +$(call ERROR_IF_EMPTY, DEBUG_LEVEL) +$(call ERROR_IF_NONBOOL, LINKER_RELAXATIONS) + +# Determine the utility prefix to use for the selected architecture +ifeq ($(ARCH), AVR8) + CROSS := avr +else ifeq ($(ARCH), XMEGA) + CROSS := avr + $(warning The XMEGA device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.) +else ifeq ($(ARCH), UC3) + CROSS := avr32 + $(warning The UC3 device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.) +else + $(error Unsupported architecture "$(ARCH)") +endif + +# Output Messages +MSG_INFO_MESSAGE := ' [INFO] :' +MSG_COMPILE_CMD := ' [GCC] :' +MSG_ASSEMBLE_CMD := ' [GAS] :' +MSG_NM_CMD := ' [NM] :' +MSG_REMOVE_CMD := ' [RM] :' +MSG_LINK_CMD := ' [LNK] :' +MSG_ARCHIVE_CMD := ' [AR] :' +MSG_SIZE_CMD := ' [SIZE] :' +MSG_OBJCPY_CMD := ' [OBJCPY] :' +MSG_OBJDMP_CMD := ' [OBJDMP] :' + +# Convert input source file list to differentiate them by type +C_SOURCE := $(filter %.c, $(SRC)) +CPP_SOURCE := $(filter %.cpp, $(SRC)) +ASM_SOURCE := $(filter %.S, $(SRC)) + +# Create a list of unknown source file types, if any are found throw an error +UNKNOWN_SOURCE := $(filter-out $(C_SOURCE) $(CPP_SOURCE) $(ASM_SOURCE), $(SRC)) +ifneq ($(UNKNOWN_SOURCE),) + $(error Unknown input source file formats: $(UNKNOWN_SOURCE)) +endif + +# Convert input source filenames into a list of required output object files +OBJECT_FILES += $(addsuffix .o, $(basename $(SRC))) + +# Check if an output object file directory was specified instead of the input file location +ifneq ($(OBJDIR),.) + # Prefix all the object filenames with the output object file directory path + OBJECT_FILES := $(addprefix $(patsubst %/,%,$(OBJDIR))/, $(notdir $(OBJECT_FILES))) + + # Check if any object file (without path) appears more than once in the object file list + ifneq ($(words $(sort $(OBJECT_FILES))), $(words $(OBJECT_FILES))) + $(error Cannot build with OBJDIR parameter set - one or more object file name is not unique) + endif + + # Create the output object file directory if it does not exist and add it to the virtual path list + $(shell mkdir $(OBJDIR) 2> /dev/null) + VPATH += $(dir $(SRC)) +endif + +# Create a list of dependency files from the list of object files +DEPENDENCY_FILES := $(OBJECT_FILES:%.o=%.d) + +# Create a list of common flags to pass to the compiler/linker/assembler +BASE_CC_FLAGS := -pipe -g$(DEBUG_FORMAT) -g$(DEBUG_LEVEL) +ifeq ($(ARCH), AVR8) + BASE_CC_FLAGS += -mmcu=$(MCU) -fshort-enums -fno-inline-small-functions -fpack-struct +else ifeq ($(ARCH), XMEGA) + BASE_CC_FLAGS += -mmcu=$(MCU) -fshort-enums -fno-inline-small-functions -fpack-struct +else ifeq ($(ARCH), UC3) + BASE_CC_FLAGS += -mpart=$(MCU:at32%=%) -masm-addr-pseudos +endif +BASE_CC_FLAGS += -Wall -fno-strict-aliasing -funsigned-char -funsigned-bitfields -ffunction-sections +BASE_CC_FLAGS += -I. -I$(patsubst %/,%,$(LUFA_PATH))/.. +BASE_CC_FLAGS += -DARCH=ARCH_$(ARCH) -DBOARD=BOARD_$(BOARD) -DF_USB=$(F_USB)UL +ifneq ($(F_CPU),) + BASE_CC_FLAGS += -DF_CPU=$(F_CPU)UL +endif +ifeq ($(LINKER_RELAXATIONS), Y) +BASE_CC_FLAGS += -mrelax +endif + +# Additional language specific compiler flags +BASE_C_FLAGS := -x c -O$(OPTIMIZATION) -std=$(C_STANDARD) -Wstrict-prototypes +BASE_CPP_FLAGS := -x c++ -O$(OPTIMIZATION) -std=$(CPP_STANDARD) +BASE_ASM_FLAGS := -x assembler-with-cpp + +# Create a list of flags to pass to the linker +BASE_LD_FLAGS := -lm -Wl,-Map=$(TARGET).map,--cref -Wl,--gc-sections +ifeq ($(LINKER_RELAXATIONS), Y) + BASE_LD_FLAGS += -Wl,--relax +endif +ifeq ($(ARCH), AVR8) + BASE_LD_FLAGS += -mmcu=$(MCU) +else ifeq ($(ARCH), XMEGA) + BASE_LD_FLAGS += -mmcu=$(MCU) +else ifeq ($(ARCH), UC3) + BASE_LD_FLAGS += -mpart=$(MCU:at32%=%) --rodata-writable --direct-data +endif + +# Determine flags to pass to the size utility based on its reported features (only invoke if size target required) +# and on an architecture where this non-standard patch is available +ifneq ($(ARCH), UC3) +size: SIZE_MCU_FLAG := $(shell $(CROSS)-size --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) ) +size: SIZE_FORMAT_FLAG := $(shell $(CROSS)-size --help | grep -- --format=.*avr > /dev/null && echo --format=avr ) +endif + +# Pre-build informational target, to give compiler and project name information when building +build_begin: + @echo $(MSG_INFO_MESSAGE) Begin compilation of project \"$(TARGET)\"... + @echo "" + @$(CROSS)-gcc --version + +# Post-build informational target, to project name information when building has completed +build_end: + @echo $(MSG_INFO_MESSAGE) Finished building project \"$(TARGET)\". + +# Prints size information of a compiled application (FLASH, RAM and EEPROM usages) +size: $(TARGET).elf + @echo $(MSG_SIZE_CMD) Determining size of \"$<\" + @echo "" + $(CROSS)-size $(SIZE_MCU_FLAG) $(SIZE_FORMAT_FLAG) $< + +# Prints size information on the symbols within a compiled application in decimal bytes +symbol-sizes: $(TARGET).elf + @echo $(MSG_NM_CMD) Extracting \"$<\" symbols with decimal byte sizes + $(CROSS)-nm --size-sort --demangle --radix=d $< + +# Cleans intermediary build files, leaving only the compiled application files +mostlyclean: + @echo $(MSG_REMOVE_CMD) Removing object files of \"$(TARGET)\" + rm -f $(OBJECT_FILES) + @echo $(MSG_REMOVE_CMD) Removing dependency files of \"$(TARGET)\" + rm -f $(DEPENDENCY_FILES) + +# Cleans all build files, leaving only the original source code +clean: mostlyclean + @echo $(MSG_REMOVE_CMD) Removing output files of \"$(TARGET)\" + rm -f $(TARGET).elf $(TARGET).hex $(TARGET).bin $(TARGET).eep $(TARGET).map $(TARGET).lss $(TARGET).sym $(TARGET).a + +# Performs a complete build of the user application and prints size information afterwards +all: build_begin elf hex bin lss sym size build_end + +# Helper targets, to build a specific type of output file without having to know the project target name +lib: lib$(TARGET).a +elf: $(TARGET).elf +hex: $(TARGET).hex $(TARGET).eep +bin: $(TARGET).bin +lss: $(TARGET).lss +sym: $(TARGET).sym + +# Default target to *create* the user application's specified source files; if this rule is executed by +# make, the input source file doesn't exist and an error needs to be presented to the user +$(SRC): + $(error Source file does not exist: $@) + +# Compiles an input C source file and generates an assembly listing for it +%.s: %.c $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Generating assembly from C file \"$(notdir $<)\" + $(CROSS)-gcc -S $(BASE_CC_FLAGS) $(BASE_C_FLAGS) $(CC_FLAGS) $(C_FLAGS) $< -o $@ + +# Compiles an input C++ source file and generates an assembly listing for it +%.s: %.cpp $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Generating assembly from C++ file \"$(notdir $<)\" + $(CROSS)-gcc -S $(BASE_CC_FLAGS) $(BASE_CPP_FLAGS) $(CC_FLAGS) $(CPP_FLAGS) $< -o $@ + +# Compiles an input C source file and generates a linkable object file for it +$(OBJDIR)/%.o: %.c $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Compiling C file \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_C_FLAGS) $(CC_FLAGS) $(C_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +# Compiles an input C++ source file and generates a linkable object file for it +$(OBJDIR)/%.o: %.cpp $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Compiling C++ file \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_CPP_FLAGS) $(CC_FLAGS) $(CPP_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +# Assembles an input ASM source file and generates a linkable object file for it +$(OBJDIR)/%.o: %.S $(MAKEFILE_LIST) + @echo $(MSG_ASSEMBLE_CMD) Assembling \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_ASM_FLAGS) $(CC_FLAGS) $(ASM_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +# Generates a library archive file from the user application, which can be linked into other applications +.PRECIOUS : $(OBJECT_FILES) +.SECONDARY : %.a +%.a: $(OBJECT_FILES) + @echo $(MSG_ARCHIVE_CMD) Archiving object files into \"$@\" + $(CROSS)-ar rcs $@ $(OBJECT_FILES) + +# Generates an ELF debug file from the user application, which can be further processed for FLASH and EEPROM data +# files, or used for programming and debugging directly +.PRECIOUS : $(OBJECT_FILES) +.SECONDARY : %.elf +%.elf: $(OBJECT_FILES) + @echo $(MSG_LINK_CMD) Linking object files into \"$@\" + $(CROSS)-gcc $^ -o $@ $(BASE_LD_FLAGS) $(LD_FLAGS) + +# Extracts out the loadable FLASH memory data from the project ELF file, and creates an Intel HEX format file of it +%.hex: %.elf + @echo $(MSG_OBJCPY_CMD) Extracting HEX file data from \"$<\" + $(CROSS)-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +# Extracts out the loadable FLASH memory data from the project ELF file, and creates an Binary format file of it +%.bin: %.elf + @echo $(MSG_OBJCPY_CMD) Extracting BIN file data from \"$<\" + $(CROSS)-objcopy -O binary -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +# Extracts out the loadable EEPROM memory data from the project ELF file, and creates an Intel HEX format file of it +%.eep: %.elf + @echo $(MSG_OBJCPY_CMD) Extracting EEP file data from \"$<\" + $(CROSS)-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings $< $@ || exit 0 + +# Creates an assembly listing file from an input project ELF file, containing interleaved assembly and source data +%.lss: %.elf + @echo $(MSG_OBJDMP_CMD) Extracting LSS file data from \"$<\" + $(CROSS)-objdump -h -d -S -z $< > $@ + +# Creates a symbol file listing the loadable and discarded symbols from an input project ELF file +%.sym: %.elf + @echo $(MSG_NM_CMD) Extracting SYM file data from \"$<\" + $(CROSS)-nm -n $< > $@ + +# Include build dependency files +-include $(DEPENDENCY_FILES) + +# Phony build targets for this module +.PHONY: build_begin build_end size symbol-sizes lib elf hex lss clean mostlyclean diff --git a/Firmware/LUFA/Build/lufa_core.mk b/Firmware/LUFA/Build/lufa_core.mk new file mode 100644 index 00000000..9a054931 --- /dev/null +++ b/Firmware/LUFA/Build/lufa_core.mk @@ -0,0 +1,175 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += CORE +LUFA_BUILD_TARGETS += help list_targets list_modules list_mandatory list_optional list_provided list_macros +LUFA_BUILD_MANDATORY_VARS += +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Core Build System Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of core build targets for the LUFA build system +# ----------------------------------------------------------------------------- +# TARGETS: +# +# help - Build system help +# list_targets - List all build targets +# list_modules - List all build modules +# list_mandatory - List all mandatory make variables required by +# the included build modules of the application +# list_optional - List all optional make variables required by +# the included build modules of the application +# list_provided - List all provided make variables from the +# included build modules of the application +# list_macros - List all provided make macros from the +# included build modules of the application +# +# MANDATORY PARAMETERS: +# +# (None) +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +# Converts a given input to a printable output using "(None)" if no items are in the list +CONVERT_TO_PRINTABLE = $(if $(strip $(1)), $(1), (None)) + + +# Build sorted and filtered lists of the included build module data +SORTED_LUFA_BUILD_MODULES = $(sort $(LUFA_BUILD_MODULES)) +SORTED_LUFA_BUILD_TARGETS = $(sort $(LUFA_BUILD_TARGETS)) +SORTED_LUFA_MANDATORY_VARS = $(sort $(LUFA_BUILD_MANDATORY_VARS)) +SORTED_LUFA_OPTIONAL_VARS = $(filter-out $(SORTED_LUFA_MANDATORY_VARS), $(sort $(LUFA_BUILD_OPTIONAL_VARS))) +SORTED_LUFA_PROVIDED_VARS = $(sort $(LUFA_BUILD_PROVIDED_VARS)) +SORTED_LUFA_PROVIDED_MACROS = $(sort $(LUFA_BUILD_PROVIDED_MACROS)) + +# Create printable versions of the sorted build module data (use "(None)" when no data is available) +PRINTABLE_LUFA_BUILD_MODULES = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_BUILD_MODULES)) +PRINTABLE_LUFA_BUILD_TARGETS = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_BUILD_TARGETS)) +PRINTABLE_LUFA_MANDATORY_VARS = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_MANDATORY_VARS)) +PRINTABLE_LUFA_OPTIONAL_VARS = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_OPTIONAL_VARS)) +PRINTABLE_LUFA_PROVIDED_VARS = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_PROVIDED_VARS)) +PRINTABLE_LUFA_PROVIDED_MACROS = $(call CONVERT_TO_PRINTABLE, $(SORTED_LUFA_PROVIDED_MACROS)) + +help: + @echo "===================================================================" + @echo " LUFA Build System 2.0 " + @echo " (C) Dean Camera, 2013 { dean @ fourwalledcubicle . com } " + @echo "===================================================================" + @echo "DESCRIPTION: " + @echo " This build system is a set of makefile modules for (GNU) Make, to " + @echo " provide a simple system for building LUFA powered applications. " + @echo " Each makefile module can be included from within a user makefile, " + @echo " to expose the build rules documented in the comments at the top of" + @echo " each build module. " + @echo " " + @echo "USAGE: " + @echo " To execute a rule, define all variables indicated in the desired " + @echo " module as a required parameter before including the build module " + @echo " in your project makefile. Parameters marked as optional will " + @echo " assume a default value in the modules if not user-assigned. " + @echo " " + @echo " By default the target output shows both a friendly summary, as " + @echo " well as the actual invoked command. To suppress the output of the " + @echo " invoked commands and show only the friendly command output, run " + @echo " make with the \"-s\" switch added before the target(s). " + @echo " " + @echo "SEE ALSO: " + @echo " For more information, see the 'Build System' chapter of the LUFA " + @echo " project documentation. " + @echo "===================================================================" + @echo " " + @echo " Currently used build system modules in this application: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_BUILD_MODULES:%= - %\n)" + @echo " " + @echo " " + @echo " Currently available build targets in this application: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_BUILD_TARGETS:%= - %\n)" + @echo " " + @echo " " + @echo " Mandatory variables required by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_MANDATORY_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Optional variables required by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_OPTIONAL_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Variables provided by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Macros provided by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_MACROS:%= - %\n)" + @echo " " + @echo "===================================================================" + @echo " The LUFA BuildSystem 2.0 - Powered By Positive Thinking (tm) " + @echo "===================================================================" + +# Lists build modules included by the project makefile, in alphabetical order +list_modules: + @echo Currently Used Build System Modules: + @printf " %b" "$(PRINTABLE_LUFA_BUILD_MODULES:%= - %\n)" + +# Lists build targets included by the project makefile, in alphabetical order +list_targets: + @echo Currently Available Build Targets: + @printf " %b" "$(PRINTABLE_LUFA_BUILD_TARGETS:%= - %\n)" + +# Lists mandatory variables that must be set by the project makefile, in alphabetical order +list_mandatory: + @echo Mandatory Variables for Included Modules: + @printf " %b" "$(PRINTABLE_LUFA_MANDATORY_VARS:%= - %\n)" + +# Lists optional variables that must be set by the project makefile, in alphabetical order +list_optional: + @echo Optional Variables for Included Modules: + @printf " %b" "$(PRINTABLE_LUFA_OPTIONAL_VARS:%= - %\n)" + +# Lists variables provided by the included build modules, in alphabetical order +list_provided: + @echo Variables Provided by the Included Modules: + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_VARS:%= - %\n)" + +# Lists macros provided by the included build modules, in alphabetical order +list_macros: + @echo Macros Provided by the Included Modules: + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_MACROS:%= - %\n)" + +# Disable default in-built make rules (those that are needed are explicitly +# defined, and doing so has performance benefits when recursively building) +ifeq ($(filter -r,$(MAKEFLAGS)),) + MAKEFLAGS += -r +endif +.SUFFIXES: + +# Phony build targets for this module +.PHONY: help list_modules list_targets list_mandatory list_optional list_provided list_macros diff --git a/Firmware/LUFA/Build/lufa_cppcheck.mk b/Firmware/LUFA/Build/lufa_cppcheck.mk new file mode 100644 index 00000000..5ffd89e5 --- /dev/null +++ b/Firmware/LUFA/Build/lufa_cppcheck.mk @@ -0,0 +1,106 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += CPPCHECK +LUFA_BUILD_TARGETS += cppcheck cppcheck-config +LUFA_BUILD_MANDATORY_VARS += SRC +LUFA_BUILD_OPTIONAL_VARS += CPPCHECK_INCLUDES CPPCHECK_EXCLUDES CPPCHECK_MSG_TEMPLATE CPPCHECK_ENABLE \ + CPPCHECK_SUPPRESS CPPCHECK_FAIL_ON_WARNING CPPCHECK_QUIET CPPCHECK_FLAGS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA CPPCheck Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to scan a project with the free "cppcheck" static +# analysis tool, to check for code errors at runtime (see http://cppcheck.sourceforge.net). +# ----------------------------------------------------------------------------- +# TARGETS: +# +# cppcheck - Scan the project with CPPCheck +# cppcheck-config - Use CPPCheck to look for missing include files +# +# MANDATORY PARAMETERS: +# +# SRC - List of source files to statically analyze +# +# OPTIONAL PARAMETERS: +# +# CPPCHECK_INCLUDES - Extra include paths to search for missing +# header files +# CPPCHECK_EXCLUDES - Source file paths to exclude checking (can be +# a path fragment if desired) +# CPPCHECK_MSG_TEMPLATE - Template for cppcheck error and warning output +# CPPCHECK_ENABLE - General cppcheck category checks to enable +# CPPCHECK_SUPPRESS - Specific cppcheck warnings to disable by ID +# CPPCHECK_FAIL_ON_WARNING - Set to Y to fail the build on cppcheck +# warnings, N to continue even if warnings occur +# CPPCHECK_QUIET - Enable cppcheck verbose or quiet output mode +# CPPCHECK_FLAGS - Additional flags to pass to cppcheck +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +CPPCHECK_INCLUDES ?= +CPPCHECK_EXCLUDES ?= +CPPCHECK_MSG_TEMPLATE ?= {file}:{line}: {severity} ({id}): {message} +CPPCHECK_ENABLE ?= all +CPPCHECK_SUPPRESS ?= variableScope missingInclude +CPPCHECK_FAIL_ON_WARNING ?= Y +CPPCHECK_QUIET ?= Y +CPPCHECK_FLAGS ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, SRC) +$(call ERROR_IF_EMPTY, CPPCHECK_MSG_TEMPLATE) +$(call ERROR_IF_EMPTY, CPPCHECK_ENABLE) +$(call ERROR_IF_NONBOOL, CPPCHECK_FAIL_ON_WARNING) +$(call ERROR_IF_NONBOOL, CPPCHECK_QUIET) + +# Build a default argument list for cppcheck +BASE_CPPCHECK_FLAGS := --template="$(CPPCHECK_MSG_TEMPLATE)" $(CPPCHECK_INCLUDES:%=-I%) $(CPPCHECK_EXCLUDES:%=-i%) --inline-suppr --force --std=c99 + +# Sanity check parameters and construct additional command line arguments to cppcheck +ifeq ($(CPPCHECK_FAIL_ON_WARNING), Y) + BASE_CPPCHECK_FLAGS += --error-exitcode=1 +endif +ifeq ($(CPPCHECK_QUIET), Y) + BASE_CPPCHECK_FLAGS += --quiet +endif + +# Output Messages +MSG_CPPCHECK_CMD := ' [CPPCHECK]:' + +# Checks the CPPCheck configuration as used in the user project, to determine if any paths are missing or invalid +cppcheck-config: $(MAKEFILE_LIST) + @echo $(MSG_CPPCHECK_CMD) Checking cppcheck configuration check on source files + cppcheck $(BASE_CPPCHECK_FLAGS) --check-config $(CPPCHECK_FLAGS) $(SRC) + +# Runs a static analysis using CPPCheck to determine if there are any issues +cppcheck: $(MAKEFILE_LIST) + @echo $(MSG_CPPCHECK_CMD) Performing static analysis on source files + cppcheck $(BASE_CPPCHECK_FLAGS) --enable=$(CPPCHECK_ENABLE) $(CPPCHECK_SUPPRESS:%=--suppress=%) $(CPPCHECK_FLAGS) $(SRC) + +# Phony build targets for this module +.PHONY: cppcheck-config cppcheck diff --git a/Firmware/LUFA/Build/lufa_dfu.mk b/Firmware/LUFA/Build/lufa_dfu.mk new file mode 100644 index 00000000..95da3462 --- /dev/null +++ b/Firmware/LUFA/Build/lufa_dfu.mk @@ -0,0 +1,95 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += DFU +LUFA_BUILD_TARGETS += flip flip-ee dfu dfu-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA DFU Bootloader Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device currently running a DFU +# class bootloader with a project's FLASH and EEPROM files. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# flip - Program FLASH into target via Atmel FLIP +# flip-ee - Program EEPROM into target via Atmel FLIP +# dfu - Program FLASH into target via dfu-programmer +# dfu-ee - Program EEPROM into target via dfu-programmer +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity-check values of mandatory user-supplied variables +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) + +# Output Messages +MSG_COPY_CMD := ' [CP] :' +MSG_REMOVE_CMD := ' [RM] :' +MSG_DFU_CMD := ' [DFU] :' + +# Programs in the target FLASH memory using BATCHISP, the command line tool used by FLIP +flip: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming FLASH with batchisp using \"$<\" + batchisp -hardware usb -device $(MCU) -operation erase f loadbuffer $< program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + +# Programs in the target EEPROM memory using BATCHISP, the command line tool used by FLIP +flip-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_COPY_CMD) Copying EEP file to temporary file \"$<.hex\" + cp $< $<.hex + @echo $(MSG_DFU_CMD) Programming EEPROM with batchisp using \"$<.hex\" + batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $<.hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + @echo $(MSG_REMOVE_CMD) Removing temporary file \"$<.hex\" + rm $<.hex + +# Programs in the target FLASH memory using DFU-PROGRAMMER +dfu: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming FLASH with dfu-programmer using \"$<\" + dfu-programmer $(MCU) erase + dfu-programmer $(MCU) flash $< + dfu-programmer $(MCU) reset + +# Programs in the target EEPROM memory using DFU-PROGRAMMER +dfu-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming EEPROM with dfu-programmer using \"$<\" + dfu-programmer $(MCU) eeprom-flash $< + dfu-programmer $(MCU) reset + +# Phony build targets for this module +.PHONY: flip flip-ee dfu dfu-ee diff --git a/Firmware/LUFA/Build/lufa_doxygen.mk b/Firmware/LUFA/Build/lufa_doxygen.mk new file mode 100644 index 00000000..82e65910 --- /dev/null +++ b/Firmware/LUFA/Build/lufa_doxygen.mk @@ -0,0 +1,100 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += DOXYGEN +LUFA_BUILD_TARGETS += doxygen doxygen_upgrade doxygen_create +LUFA_BUILD_MANDATORY_VARS += LUFA_PATH +LUFA_BUILD_OPTIONAL_VARS += DOXYGEN_CONF DOXYGEN_FAIL_ON_WARNING DOXYGEN_OVERRIDE_PARAMS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Doxygen Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to automatically build Doxygen documentation for +# a project (see www.doxygen.org). +# ----------------------------------------------------------------------------- +# TARGETS: +# +# doxygen - Build Doxygen Documentation +# doxygen_create - Create a new Doxygen configuration file using +# the latest template +# doxygen_upgrade - Upgrade an existing Doxygen configuration file +# to the latest template +# +# MANDATORY PARAMETERS: +# +# LUFA_PATH - Path to the LUFA library core +# +# OPTIONAL PARAMETERS: +# +# DOXYGEN_CONF - Doxygen configuration filename +# DOXYGEN_FAIL_ON_WARNING - Set to Y to fail the build on Doxygen warnings, +# N to continue even if warnings occur +# DOXYGEN_OVERRIDE_PARAMS - Parameters to override in the doxygen +# configuration file +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +DOXYGEN_CONF ?= Doxygen.conf +DOXYGEN_FAIL_ON_WARNING ?= Y +DOXYGEN_OVERRIDE_PARAMS ?= QUIET=YES HTML_EXTRA_STYLESHEET=$(patsubst %/,%,$(LUFA_PATH))/DoxygenPages/Style/Style.css + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, DOXYGEN_CONF) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_NONBOOL, DOXYGEN_FAIL_ON_WARNING) + +# Output Messages +MSG_DOXYGEN_CMD := ' [DOXYGEN] :' + +# Determine Doxygen invocation command +BASE_DOXYGEN_CMD := ( cat $(DOXYGEN_CONF) $(DOXYGEN_OVERRIDE_PARAMS:%=; echo "%") ) | doxygen - +ifeq ($(DOXYGEN_FAIL_ON_WARNING), Y) + DOXYGEN_CMD := if ( $(BASE_DOXYGEN_CMD) 2>&1 | grep -v "warning: ignoring unsupported tag" ;); then exit 1; fi; +else + DOXYGEN_CMD := $(BASE_DOXYGEN_CMD) +endif + +# Error if the specified Doxygen configuration file does not exist +$(DOXYGEN_CONF): + $(error Doxygen configuration file $@ does not exist) + +# Builds the project documentation using the specified configuration file and the DOXYGEN tool +doxygen: $(DOXYGEN_CONF) $(MAKEFILE_LIST) + @echo $(MSG_DOXYGEN_CMD) Configuration file \"$(DOXYGEN_CONF)\" with parameters \"$(DOXYGEN_OVERRIDE_PARAMS)\" + $(DOXYGEN_CMD) + +# Upgrades an existing Doxygen configuration file to the latest Doxygen template, preserving settings +doxygen_upgrade: $(DOXYGEN_CONF) $(MAKEFILE_LIST) + @echo $(MSG_DOXYGEN_CMD) Upgrading configuration file \"$(DOXYGEN_CONF)\" with latest template + doxygen -u $(DOXYGEN_CONF) > /dev/null + +# Creates a new Doxygen configuration file with the set file name +doxygen_create: $(MAKEFILE_LIST) + @echo $(MSG_DOXYGEN_CMD) Creating new configuration file \"$(DOXYGEN_CONF)\" with latest template + doxygen -g $(DOXYGEN_CONF) > /dev/null + +# Phony build targets for this module +.PHONY: doxygen doxygen_upgrade doxygen_create diff --git a/Firmware/LUFA/Build/lufa_hid.mk b/Firmware/LUFA/Build/lufa_hid.mk new file mode 100644 index 00000000..1b6f659c --- /dev/null +++ b/Firmware/LUFA/Build/lufa_hid.mk @@ -0,0 +1,94 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += HID +LUFA_BUILD_TARGETS += hid hid-ee teensy teensy-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA HID Bootloader Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device currently running a HID +# class bootloader with a project's FLASH files. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# hid - Program FLASH into target via +# hid_bootloader_cli +# hid-ee - Program EEPROM into target via a temporary +# AVR application and hid_bootloader_cli +# teensy - Program FLASH into target via +# teensy_loader_cli +# teensy-ee - Program EEPROM into target via a temporary +# AVR application and teensy_loader_cli +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity-check values of mandatory user-supplied variables +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) + +# Output Messages +MSG_HID_BOOTLOADER_CMD := ' [HID] :' +MSG_OBJCPY_CMD := ' [OBJCPY] :' +MSG_MAKE_CMD := ' [MAKE] :' + +# Programs in the target FLASH memory using the HID_BOOTLOADER_CLI tool +hid: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_HID_BOOTLOADER_CMD) Programming FLASH with hid_bootloader_cli using \"$<\" + hid_bootloader_cli -mmcu=$(MCU) -v $< + +# Programs in the target EEPROM memory using the HID_BOOTLOADER_CLI tool (note: clears target FLASH memory) +hid-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a binary file \"InputEEData.bin\" + avr-objcopy -I ihex -O binary $< $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/InputEEData.bin + @echo $(MSG_MAKE_CMD) Making EEPROM loader application for \"$<\" + make -C $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/ MCU=$(MCU) clean hid + +# Programs in the target FLASH memory using the TEENSY_BOOTLOADER_CLI tool +teensy: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_HID_BOOTLOADER_CMD) Programming FLASH with teensy_loader_cli using \"$<\" + teensy_loader_cli -mmcu=$(MCU) -v $< + +# Programs in the target EEPROM memory using the TEENSY_BOOTLOADER_CLI tool (note: clears target FLASH memory) +teensy-ee: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a binary file \"InputEEData.bin\" + avr-objcopy -I ihex -O binary $< $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/InputEEData.bin + @echo $(MSG_MAKE_CMD) Making EEPROM loader application for \"$<\" + make -s -C $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/ MCU=$(MCU) clean hid-teensy + +# Phony build targets for this module +.PHONY: hid hid-ee teensy teensy-ee diff --git a/Firmware/LUFA/Build/lufa_sources.mk b/Firmware/LUFA/Build/lufa_sources.mk new file mode 100644 index 00000000..21d8a9ef --- /dev/null +++ b/Firmware/LUFA/Build/lufa_sources.mk @@ -0,0 +1,144 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += SOURCES +LUFA_BUILD_TARGETS += +LUFA_BUILD_MANDATORY_VARS += LUFA_PATH ARCH +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += LUFA_SRC_USB_DEVICE LUFA_SRC_USB_HOST \ + LUFA_SRC_USB LUFA_SRC_USBCLASS_DEVICE \ + LUFA_SRC_USBCLASS_HOST LUFA_SRC_USBCLASS \ + LUFA_SRC_TEMPERATURE LUFA_SRC_SERIAL \ + LUFA_SRC_TWI LUFA_SRC_PLATFORM +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Sources Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of makefile variables for the various LUFA module sources. +# Once included, the sources required to use a given LUFA module will become +# available using the makefile variable names listed in the LUFA project +# documentation. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# (None) +# +# MANDATORY PARAMETERS: +# +# LUFA_PATH - Path to the LUFA library core +# ARCH - Device architecture name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# LUFA_SRC_USB_DEVICE - List of LUFA USB driver source files required +# for USB Device mode only +# LUFA_SRC_USB_HOST - List of LUFA USB driver source files required +# for USB Host mode only +# LUFA_SRC_USB - List of LUFA USB driver source files for all +# USB modes +# LUFA_SRC_USBCLASS_DEVICE - List of LUFA USB Class driver source files for +# USB Device mode only +# LUFA_SRC_USBCLASS_HOST - List of LUFA USB Class driver source files for +# USB Host mode only +# LUFA_SRC_USBCLASS - List of LUFA USB Class driver source files for +# all USB modes +# LUFA_SRC_TEMPERATURE - List of LUFA temperature sensor driver source +# files +# LUFA_SRC_SERIAL - List of LUFA Serial U(S)ART driver source files +# LUFA_SRC_TWI - List of LUFA TWI driver source files +# LUFA_SRC_PLATFORM - List of LUFA architecture specific platform +# management source files +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_EMPTY, ARCH) + +# Allow LUFA_ROOT_PATH to be overridden elsewhere to support legacy LUFA makefiles +LUFA_ROOT_PATH ?= $(patsubst %/,%,$(LUFA_PATH)) + +# Construct LUFA module source variables +LUFA_SRC_USB_COMMON := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBController_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBInterrupt_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/ConfigDescriptors.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/Events.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/USBTask.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Common/HIDParser.c \ + +LUFA_SRC_USB_HOST := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Host_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Pipe_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/PipeStream_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/HostStandardReq.c \ + $(LUFA_SRC_USB_COMMON) + +LUFA_SRC_USB_DEVICE := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Device_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Endpoint_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/EndpointStream_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/DeviceStandardReq.c \ + $(LUFA_SRC_USB_COMMON) + +LUFA_SRC_USBCLASS_DEVICE := $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/AudioClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/HIDClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MassStorageClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MIDIClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/PrinterClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/RNDISClassDevice.c \ + +LUFA_SRC_USBCLASS_HOST := $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AudioClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/CDCClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/HIDClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MassStorageClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MIDIClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/PrinterClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/RNDISClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/StillImageClassHost.c + +LUFA_SRC_USB := $(sort $(LUFA_SRC_USB_COMMON) $(LUFA_SRC_USB_HOST) $(LUFA_SRC_USB_DEVICE)) + +LUFA_SRC_USBCLASS := $(LUFA_SRC_USBCLASS_DEVICE) $(LUFA_SRC_USBCLASS_HOST) + +LUFA_SRC_TEMPERATURE := $(LUFA_ROOT_PATH)/Drivers/Board/Temperature.c + +LUFA_SRC_SERIAL := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/Serial_$(ARCH).c + +LUFA_SRC_TWI := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/TWI_$(ARCH).c + +ifeq ($(ARCH), UC3) + LUFA_SRC_PLATFORM := $(LUFA_ROOT_PATH)/Platform/UC3/Exception.S \ + $(LUFA_ROOT_PATH)/Platform/UC3/InterruptManagement.c +else + LUFA_SRC_PLATFORM := +endif + +# Build a list of all available module sources +LUFA_SRC_ALL_FILES := $(LUFA_SRC_USB) \ + $(LUFA_SRC_USBCLASS) \ + $(LUFA_SRC_TEMPERATURE) \ + $(LUFA_SRC_SERIAL) \ + $(LUFA_SRC_TWI) \ + $(LUFA_SRC_PLATFORM) diff --git a/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.c b/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.c new file mode 100644 index 00000000..52ea0d72 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.c @@ -0,0 +1,180 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * USB Device Descriptors, for library use when in USB device mode. Descriptors are special + * computer-readable structures which the host requests upon device enumeration, to determine + * the device's capabilities and functions. + */ + +#include "Descriptors.h" + +/** Device descriptor structure. This descriptor describes the overall device + * characteristics, including the supported USB version, control endpoint size + * and the number of device configurations. The descriptor is read out by the + * USB host when the enumeration process begins. + */ +const USB_Descriptor_Device_t DeviceDescriptor = +{ + .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, + + .USBSpecification = VERSION_BCD(02.00), + .Class = USB_CSCP_NoDeviceClass, + .SubClass = USB_CSCP_NoDeviceSubclass, + .Protocol = USB_CSCP_NoDeviceProtocol, + + .Endpoint0Size = 64, + + .VendorID = 0x0000, + .ProductID = 0x0000, + .ReleaseNumber = VERSION_BCD(00.02), + + .ManufacturerStrIndex = 0x01, + .ProductStrIndex = 0x02, + .SerialNumStrIndex = NO_DESCRIPTOR, + + .NumberOfConfigurations = 1 +}; + +/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage + * of the device in one of its supported configurations, including information about any device interfaces + * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting + * a configuration so that the host may correctly communicate with the USB device. + */ +const USB_Descriptor_Configuration_t ConfigurationDescriptor = +{ + .Config = + { + .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, + + .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), + .TotalInterfaces = 0, + + .ConfigurationNumber = 1, + .ConfigurationStrIndex = NO_DESCRIPTOR, + + .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, +}; + +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +const USB_Descriptor_String_t LanguageString = +{ + .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, + + .UnicodeString = {LANGUAGE_ID_ENG} +}; + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t ManufacturerString = +{ + .Header = {.Size = USB_STRING_LEN(14), .Type = DTYPE_String}, + + .UnicodeString = L"Your Name Here" +}; + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t ProductString = +{ + .Header = {.Size = USB_STRING_LEN(15), .Type = DTYPE_String}, + + .UnicodeString = L"LUFA USB Device" +}; + +/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" + * documentation) by the application code so that the address and size of a requested descriptor can be given + * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function + * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the + * USB host. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress + #if defined(HAS_MULTIPLE_DESCRIPTOR_ADDRESS_SPACES) + , uint8_t* const DescriptorMemorySpace + #endif + ) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorNumber = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorNumber) + { + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + + break; + } + + #if defined(HAS_MULTIPLE_DESCRIPTOR_ADDRESS_SPACES) + *DescriptorMemorySpace = MEMSPACE_RAM; + #endif + + *DescriptorAddress = Address; + return Size; +} + diff --git a/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.h b/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.h new file mode 100644 index 00000000..96ab07ed --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DeviceTemplate/Descriptors.h @@ -0,0 +1,59 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + + /* Includes: */ + #include + + /* Macros: */ + #if (defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))) + #define HAS_MULTIPLE_DESCRIPTOR_ADDRESS_SPACES + #endif + + /* Type Defines: */ + /** Type define for the device configuration descriptor structure. This must be defined in the + * application code, as the configuration descriptor contains several sub-descriptors which + * vary between devices, and which describe the device's usage to the host. + */ + typedef struct + { + USB_Descriptor_Configuration_Header_t Config; + } USB_Descriptor_Configuration_t; + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.c b/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.c new file mode 100644 index 00000000..2db4c30d --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.c @@ -0,0 +1,106 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Main source file for the USB device application. This file contains the + * main tasks of the application and is responsible for the initial + * application hardware configuration. + */ + +#include "DeviceApplication.h" + +/** Main program entry point. This routine contains the overall program flow, including initial + * setup of all components and the main program loop. + */ +int main(void) +{ + SetupHardware(); + + GlobalInterruptEnable(); + + for (;;) + { + USB_USBTask(); + } +} + +/** Configures the board hardware and chip peripherals for the demo's functionality. */ +void SetupHardware(void) +{ + #if (ARCH == ARCH_AVR8) + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + /* Hardware Initialization */ + USB_Init(USB_MODE_Device, USB_DEVICE_OPT_FULLSPEED | USB_OPT_AUTO_PLL); + #elif (ARCH == ARCH_XMEGA) + /* Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it */ + XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU); + XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL); + + /* Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference */ + XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ); + XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB); + + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + + /* Hardware Initialization */ + USB_Init(USB_OPT_RC32MCLKSRC | USB_OPT_BUSEVENT_PRIHIGH); + #endif +} + +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ + +} + +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ + +} + +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + +} + +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + +} diff --git a/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.h b/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.h new file mode 100644 index 00000000..c654c977 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DeviceTemplate/DeviceApplication.h @@ -0,0 +1,53 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for DeviceApplication.c. + */ + +#ifndef _USB_DEVICE_APPLICATION_H_ +#define _USB_DEVICE_APPLICATION_H_ + + /* Includes: */ + #include + #include + #include + + #include + #include + + #include "Descriptors.h" + + /* Function Prototypes: */ + void SetupHardware(void); + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/DeviceTemplate/asf.xml b/Firmware/LUFA/CodeTemplates/DeviceTemplate/asf.xml new file mode 100644 index 00000000..fd65db28 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DeviceTemplate/asf.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Template for a LUFA USB device mode application. + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/LUFA/CodeTemplates/DriverStubs/Board.h b/Firmware/LUFA/CodeTemplates/DriverStubs/Board.h new file mode 100644 index 00000000..7bbf1647 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DriverStubs/Board.h @@ -0,0 +1,82 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Hardware Information Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Board Hardware + * information driver. + */ + +#ifndef __BOARD_USER_H__ +#define __BOARD_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BOARD_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Board.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates the board has hardware Buttons mounted if defined. */ +// #define BOARD_HAS_BUTTONS + + /** Indicates the board has a hardware Dataflash mounted if defined. */ +// #define BOARD_HAS_DATAFLASH + + /** Indicates the board has a hardware Joystick mounted if defined. */ +// #define BOARD_HAS_JOYSTICK + + /** Indicates the board has hardware LEDs mounted if defined. */ +// #define BOARD_HAS_LEDS + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/CodeTemplates/DriverStubs/Buttons.h b/Firmware/LUFA/CodeTemplates/DriverStubs/Buttons.h new file mode 100644 index 00000000..84e21c6c --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DriverStubs/Buttons.h @@ -0,0 +1,90 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Button Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Buttons driver, + * for the control of physical board-mounted GPIO pushbuttons. + */ + +#ifndef __BUTTONS_USER_H__ +#define __BUTTONS_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 // TODO: Add mask for first board button here + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + // TODO: Initialize the appropriate port pins as an inputs here, with pull-ups + } + + static inline void Buttons_Disable(void) + { + // TODO: Clear the appropriate port pins as high impedance inputs here + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + // TODO: Return current button status here, debounced if required + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/DriverStubs/Dataflash.h b/Firmware/LUFA/CodeTemplates/DriverStubs/Dataflash.h new file mode 100644 index 00000000..61b1ddeb --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DriverStubs/Dataflash.h @@ -0,0 +1,223 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Dataflash Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Dataflash + * driver. +*/ + +#ifndef __DATAFLASH_USER_H__ +#define __DATAFLASH_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK // TODO: Replace this with a mask of all the /CS pins of all Dataflashes + #define DATAFLASH_CHIPCS_DDR // TODO: Replace with the DDR register name for the board's Dataflash ICs + #define DATAFLASH_CHIPCS_PORT // TODO: Replace with the PORT register name for the board's Dataflash ICs + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 // TODO: Replace with the number of Dataflashes on the board, max 2 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP 0 + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 // TODO: Replace with mask with the pin attached to the first Dataflash /CS set + + /** Mask for the second dataflash chip selected. */ + #define DATAFLASH_CHIP2 // TODO: Replace with mask with the pin attached to the second Dataflash /CS set + + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE // TODO: Replace with the page size for the Dataflash ICs + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + // TODO + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + // TODO + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + // TODO + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (~DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of a \c DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT | DATAFLASH_CHIPCS_MASK) & ~ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS)) + return; + + #if (DATAFLASH_TOTALCHIPS == 2) + if (PageAddress & 0x01) + Dataflash_SelectChip(DATAFLASH_CHIP2); + else + Dataflash_SelectChip(DATAFLASH_CHIP1); + #else + Dataflash_SelectChip(DATAFLASH_CHIP1); + #endif + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + #if (DATAFLASH_TOTALCHIPS == 2) + PageAddress >>= 1; + #endif + + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + #endif + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/DriverStubs/Joystick.h b/Firmware/LUFA/CodeTemplates/DriverStubs/Joystick.h new file mode 100644 index 00000000..743d3d4c --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DriverStubs/Joystick.h @@ -0,0 +1,102 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Joystick Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Joystick + * driver, for a digital four-way (plus button) joystick. +*/ + +#ifndef __JOYSTICK_USER_H__ +#define __JOYSTICK_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT // TODO: Add mask to indicate joystick left position here + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT // TODO: Add mask to indicate joystick right position here + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP // TODO: Add mask to indicate joystick up position here + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN // TODO: Add mask to indicate joystick down position here + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS // TODO: Add mask to indicate joystick pressed position here + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + // TODO: Initialize joystick port pins as inputs with pull-ups + } + + static inline void Joystick_Disable(void) + { + // TODO: Clear the joystick pins as high impedance inputs here + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + // TODO: Return current joystick position data which can be obtained by masking against the JOY_* macros + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/DriverStubs/LEDs.h b/Firmware/LUFA/CodeTemplates/DriverStubs/LEDs.h new file mode 100644 index 00000000..dc975373 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/DriverStubs/LEDs.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board LED Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA LEDs driver, + * for the LEDs (up to four) mounted on most development boards. +*/ + +#ifndef __LEDS_USER_H__ +#define __LEDS_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 // TODO: Add mask for first board LED here + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 // TODO: Add mask for second board LED here + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 // TODO: Add mask for third board LED here + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 // TODO: Add mask for fourth board LED here + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + // TODO: Add code to initialize LED port pins as outputs here + } + + static inline void LEDs_Disable(void) + { + // TODO: Clear the LED port pins as high impedance inputs here + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn on LEDs given in the LEDMask mask here, leave others as-is + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn off LEDs given in the LEDMask mask here, leave others as-is + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn on only LEDs given in the LEDMask mask here, all others off + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) + { + // TODO: Add code to set the Leds in the given LEDMask to the status given in ActiveMask here + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + // TODO: Add code to toggle the Leds in the given LEDMask, ignoring all others + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + // TODO: Add code to return the current LEDs status' here which can be masked against LED_LED* macros + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.c b/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.c new file mode 100644 index 00000000..8de143c3 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.c @@ -0,0 +1,133 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Main source file for the USB host application. This file contains the + * main tasks of the application and is responsible for the initial + * application hardware configuration. + */ + +#include "HostApplication.h" + +/** Main program entry point. This routine configures the hardware required by the application, then + * enters a loop to run the application tasks in sequence. + */ +int main(void) +{ + SetupHardware(); + + GlobalInterruptEnable(); + + for (;;) + { + USB_USBTask(); + } +} + +/** Configures the board hardware and chip peripherals for the demo's functionality. */ +void SetupHardware(void) +{ + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + /* Hardware Initialization */ + USB_Init(USB_MODE_Host, USB_DEVICE_OPT_FULLSPEED | USB_OPT_AUTO_PLL); +} + +/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and + * starts the library USB task to begin the enumeration and USB management process. + */ +void EVENT_USB_Host_DeviceAttached(void) +{ + +} + +/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and + * stops the library USB task management process. + */ +void EVENT_USB_Host_DeviceUnattached(void) +{ + +} + +/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully + * enumerated by the host and is now ready to be used by the application. + */ +void EVENT_USB_Host_DeviceEnumerationComplete(void) +{ + uint16_t ConfigDescriptorSize; + uint8_t ConfigDescriptorData[512]; + + if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) + { + return; + } + + if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) + { + return; + } +} + +/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ +void EVENT_USB_Host_HostError(const uint8_t ErrorCode) +{ + USB_Disable(); + for(;;); +} + +/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while + * enumerating an attached USB device. + */ +void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, + const uint8_t SubErrorCode) +{ + +} + +/* Required callback for retrieving descriptors from a LUFA device - unless the USB_HOST_ONLY configuration + * option is set, this is still required even in an application that uses host mode only. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress +#if defined(HAS_MULTIPLE_DESCRIPTOR_ADDRESS_SPACES) + , uint8_t* const DescriptorMemorySpace +#endif +) +{ + return 0; +} diff --git a/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.h b/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.h new file mode 100644 index 00000000..9aa8578b --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/HostTemplate/HostApplication.h @@ -0,0 +1,56 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for HostApplication.c. + */ + +#ifndef _USB_HOST_APPLICATION_H_ +#define _USB_HOST_APPLICATION_H_ + + /* Includes: */ + #include + #include + #include + + #include + + /* Macros: */ + #if (defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))) + #define HAS_MULTIPLE_DESCRIPTOR_ADDRESS_SPACES + #endif + + /* Function Prototypes: */ + void SetupHardware(void); + +#endif + diff --git a/Firmware/LUFA/CodeTemplates/HostTemplate/asf.xml b/Firmware/LUFA/CodeTemplates/HostTemplate/asf.xml new file mode 100644 index 00000000..c1996ec7 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/HostTemplate/asf.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + Template for a LUFA USB host mode application. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/LUFA/CodeTemplates/LUFAConfig.h b/Firmware/LUFA/CodeTemplates/LUFAConfig.h new file mode 100644 index 00000000..70d536b7 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/LUFAConfig.h @@ -0,0 +1,167 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Library Configuration Header File (Template) + * + * This is a header file which can be used to configure LUFA's + * compile time options, as an alternative to the compile time + * constants supplied through a makefile. To use this configuration + * header, copy this into your project's root directory and supply + * the \c USE_LUFA_CONFIG_HEADER token to the compiler so that it is + * defined in all compiled source files. + * + * For information on what each token does, refer to the LUFA + * manual section "Summary of Compile Tokens". + */ + +#ifndef __LUFA_CONFIG_H__ +#define __LUFA_CONFIG_H__ + + #if (ARCH == ARCH_AVR8) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define ORDERED_EP_CONFIG +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_DEVICE_ONLY +// #define USB_HOST_ONLY +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS +// #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define INTERRUPT_CONTROL_ENDPOINT +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + /* USB Host Mode Driver Related Tokens: */ +// #define HOST_STATE_AS_GPIOR {Insert Value Here} +// #define USB_HOST_TIMEOUT_MS {Insert Value Here} +// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} +// #define NO_AUTO_VBUS_MANAGEMENT +// #define INVERTED_VBUS_ENABLE_LINE + + #elif (ARCH == ARCH_XMEGA) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS +// #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define MAX_ENDPOINT_INDEX {Insert Value Here} +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + #elif (ARCH == ARCH_UC3) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define ORDERED_EP_CONFIG +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_DEVICE_ONLY +// #define USB_HOST_ONLY +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define INTERRUPT_CONTROL_ENDPOINT +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + /* USB Host Mode Driver Related Tokens: */ +// #define USB_HOST_TIMEOUT_MS {Insert Value Here} +// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} +// #define NO_AUTO_VBUS_MANAGEMENT +// #define INVERTED_VBUS_ENABLE_LINE + + #else + + #error Unsupported architecture for this LUFA configuration file. + + #endif +#endif + diff --git a/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA CDC-ACM.inf b/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA CDC-ACM.inf new file mode 100644 index 00000000..f9e2c6f0 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA CDC-ACM.inf @@ -0,0 +1,64 @@ +; Windows LUFA CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation + +[DefaultInstall] +CopyINF="LUFA CDC-ACM.inf" + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +DriverVer=7/1/2012,10.0.0.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 + +[SourceDisksNames] + +[SourceDisksFiles] + +[DestinationDirs] +DefaultDestDir=12 + +[DriverInstall] +Include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=DriverInstall.AddReg + +[DriverInstall.Services] +Include=mdmcpq.inf +AddService=usbser, 0x00000002, LowerFilter_Service_Inst + +[DriverInstall.AddReg] +HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider" + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTx86] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +[DeviceList.NTia64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044 + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGNAME="http://www.lufa-lib.org" +DESCRIPTION="LUFA CDC-ACM Virtual Serial Port" diff --git a/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA RNDIS.inf b/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA RNDIS.inf new file mode 100644 index 00000000..4ad76ace --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/WindowsINF/LUFA RNDIS.inf @@ -0,0 +1,59 @@ +; Windows LUFA RNDIS Setup File +; Copyright (c) 2000 Microsoft Corporation + +[DefaultInstall] +CopyINF="LUFA RNDIS.inf" + +[Version] +Signature="$Windows NT$" +Class=Net +ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318} +Provider=%MFGNAME% +DriverVer=7/1/2012,10.0.0.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 + +[ControlFlags] +ExcludeFromSelect=* + +[DriverInstall] +Characteristics=0x84 ; NCF_PHYSICAL + NCF_HAS_UI +BusType=15 +include=netrndis.inf +needs=Usb_Rndis.ndi +AddReg=Rndis_AddReg_Vista + +[DriverInstall.Services] +include=netrndis.inf +needs=Usb_Rndis.ndi.Services + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204C + +[DeviceList.NTx86] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204C + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204C + +[DeviceList.NTia64] +%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204C + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGNAME="http://www.lufa-lib.org" +DESCRIPTION="LUFA RNDIS USB Ethernet Adapter" diff --git a/Firmware/LUFA/CodeTemplates/makefile_template b/Firmware/LUFA/CodeTemplates/makefile_template new file mode 100644 index 00000000..d2c45118 --- /dev/null +++ b/Firmware/LUFA/CodeTemplates/makefile_template @@ -0,0 +1,38 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2013. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# -------------------------------------- +# LUFA Project Makefile. +# -------------------------------------- + +# Run "make help" for target help. + +MCU = at90usb1287 +ARCH = AVR8 +BOARD = USBKEY +F_CPU = 8000000 +F_USB = $(F_CPU) +OPTIMIZATION = s +TARGET = Target +SRC = $(TARGET).c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) $(LUFA_SRC_PLATFORM) +LUFA_PATH = ../../LUFA +CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig +LD_FLAGS = + +# Default target +all: + +# Include LUFA build script makefiles +include $(LUFA_PATH)/Build/lufa_core.mk +include $(LUFA_PATH)/Build/lufa_sources.mk +include $(LUFA_PATH)/Build/lufa_build.mk +include $(LUFA_PATH)/Build/lufa_cppcheck.mk +include $(LUFA_PATH)/Build/lufa_doxygen.mk +include $(LUFA_PATH)/Build/lufa_dfu.mk +include $(LUFA_PATH)/Build/lufa_hid.mk +include $(LUFA_PATH)/Build/lufa_avrdude.mk +include $(LUFA_PATH)/Build/lufa_atprogram.mk diff --git a/Firmware/LUFA/Common/ArchitectureSpecific.h b/Firmware/LUFA/Common/ArchitectureSpecific.h new file mode 100644 index 00000000..2dd0f6ff --- /dev/null +++ b/Firmware/LUFA/Common/ArchitectureSpecific.h @@ -0,0 +1,177 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Architecture specific definitions relating to specific processor architectures. + * + * \copydetails Group_ArchitectureSpecific + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_ArchitectureSpecific Architecture Specific Definitions + * \brief Architecture specific definitions relating to specific processor architectures. + * + * Architecture specific macros, functions and other definitions, which relate to specific architectures. This + * definitions may or may not be available in some form on other architectures, and thus should be protected by + * preprocessor checks in portable code to prevent compile errors. + * + * @{ + */ + +#ifndef __LUFA_ARCHSPEC_H__ +#define __LUFA_ARCHSPEC_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (ARCH == ARCH_AVR8) || (ARCH == ARCH_XMEGA) || defined(__DOXYGEN__) + #if (ARCH == ARCH_AVR8) || defined(__DOXYGEN__) + /** Re-enables the AVR's JTAG bus in software, until a system reset. This will re-enable JTAG debugging + * interface after is has been disabled in software via \ref JTAG_DISABLE(). + * + * \note This macro is not available for all architectures. + */ + #define JTAG_ENABLE() MACROS{ \ + __asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "out %1, %0" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + "out %1, %0" "\n\t" \ + : \ + : "r" (MCUCR & ~(1 << JTD)), \ + "M" (_SFR_IO_ADDR(MCUCR)) \ + : "r0"); \ + }MACROE + + /** Disables the AVR's JTAG bus in software, until a system reset. This will override the current JTAG + * status as set by the JTAGEN fuse, disabling JTAG debugging and reverting the JTAG pins back to GPIO + * mode. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DISABLE() MACROS{ \ + __asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "out %1, %0" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + "out %1, %0" "\n\t" \ + : \ + : "r" (MCUCR | (1 << JTD)), \ + "M" (_SFR_IO_ADDR(MCUCR)) \ + : "r0"); \ + }MACROE + #endif + + /** Defines a volatile \c NOP statement which cannot be optimized out by the compiler, and thus can always + * be set as a breakpoint in the resulting code. Useful for debugging purposes, where the optimizer + * removes/reorders code to the point where break points cannot reliably be set. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::) + + /** Defines an explicit JTAG break point in the resulting binary via the assembly \c BREAK statement. When + * a JTAG is used, this causes the program execution to halt when reached until manually resumed. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("break" ::) + + /** Macro for testing condition "x" and breaking via \ref JTAG_DEBUG_BREAK() if the condition is false. + * + * \note This macro is not available for all architectures. + * + * \param[in] Condition Condition that will be evaluated. + */ + #define JTAG_ASSERT(Condition) MACROS{ if (!(Condition)) { JTAG_DEBUG_BREAK(); } }MACROE + + /** Macro for testing condition \c "x" and writing debug data to the stdout stream if \c false. The stdout stream + * must be pre-initialized before this macro is run and linked to an output device, such as the microcontroller's + * USART peripheral. + * + * The output takes the form "{FILENAME}: Function {FUNCTION NAME}, Line {LINE NUMBER}: Assertion {Condition} failed." + * + * \note This macro is not available for all architectures. + * + * \param[in] Condition Condition that will be evaluated, + */ + #define STDOUT_ASSERT(Condition) MACROS{ if (!(Condition)) { \ + printf_P(PSTR("%s: Function \"%s\", Line %d: " \ + "Assertion \"%s\" failed.\r\n"), \ + __FILE__, __func__, __LINE__, #Condition); } }MACROE + + #if !defined(pgm_read_ptr) || defined(__DOXYGEN__) + /** Reads a pointer out of PROGMEM space on the AVR8 architecture. This is currently a wrapper for the + * avr-libc \c pgm_read_word() macro with a \c void* cast, so that its value can be assigned directly + * to a pointer variable or used in pointer arithmetic without further casting in C. In a future + * avr-libc distribution this will be part of the standard API and will be implemented in a more formal + * manner. + * + * \note This macro is not available for all architectures. + * + * \param[in] Address Address of the pointer to read. + * + * \return Pointer retrieved from PROGMEM space. + */ + #define pgm_read_ptr(Address) (void*)pgm_read_word(Address) + #endif + #elif (ARCH == ARCH_UC3) + #define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::) + #define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("breakpoint" ::) + #define JTAG_ASSERT(Condition) MACROS{ if (!(Condition)) { JTAG_DEBUG_BREAK(); } }MACROE + #define STDOUT_ASSERT(Condition) MACROS{ if (!(Condition)) { \ + printf("%s: Function \"%s\", Line %d: " \ + "Assertion \"%s\" failed.\r\n"), \ + __FILE__, __func__, __LINE__, #Condition); } }MACROE + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/Architectures.h b/Firmware/LUFA/Common/Architectures.h new file mode 100644 index 00000000..b151e2bd --- /dev/null +++ b/Firmware/LUFA/Common/Architectures.h @@ -0,0 +1,84 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Supported library architecture defines. + * + * \copydetails Group_Architectures + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_Architectures Hardware Architectures + * \brief Supported library architecture defines. + * + * Architecture macros for selecting the desired target microcontroller architecture. One of these values should be + * defined as the value of \c ARCH in the user project makefile via the \c -D compiler switch to GCC, to select the + * target architecture. + * + * The selected architecture should remain consistent with the makefile \c ARCH value, which is used to select the + * underlying driver source files for each architecture. + * + * @{ + */ + +#ifndef __LUFA_ARCHITECTURES_H__ +#define __LUFA_ARCHITECTURES_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Selects the Atmel 8-bit AVR (AT90USB* and ATMEGA*U* chips) architecture. */ + #define ARCH_AVR8 0 + + /** Selects the Atmel 32-bit UC3 AVR (AT32UC3* chips) architecture. */ + #define ARCH_UC3 1 + + /** Selects the Atmel XMEGA AVR (ATXMEGA* chips) architecture. */ + #define ARCH_XMEGA 2 + + #if !defined(__DOXYGEN__) + #define ARCH_ ARCH_AVR8 + + #if !defined(ARCH) + #define ARCH ARCH_AVR8 + #endif + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/Attributes.h b/Firmware/LUFA/Common/Attributes.h new file mode 100644 index 00000000..cecbb5e9 --- /dev/null +++ b/Firmware/LUFA/Common/Attributes.h @@ -0,0 +1,155 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Special function/variable attribute macros. + * + * \copydetails Group_FuncVarAttributes + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_FuncVarAttributes Function/Variable Attributes + * \brief Special function/variable attribute macros. + * + * This module contains macros for applying specific attributes to functions and variables to control various + * optimizer and code generation features of the compiler. Attributes may be placed in the function prototype + * or variable declaration in any order, and multiple attributes can be specified for a single item via a space + * separated list. + * + * On incompatible versions of GCC or on other compilers, these macros evaluate to nothing unless they are + * critical to the code's function and thus must throw a compile error when used. + * + * @{ + */ + +#ifndef __LUFA_ATTR_H__ +#define __LUFA_ATTR_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (__GNUC__ >= 3) || defined(__DOXYGEN__) + /** Indicates to the compiler that the function can not ever return, so that any stack restoring or + * return code may be omitted by the compiler in the resulting binary. + */ + #define ATTR_NO_RETURN __attribute__ ((noreturn)) + + /** Indicates that the function returns a value which should not be ignored by the user code. When + * applied, any ignored return value from calling the function will produce a compiler warning. + */ + #define ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) + + /** Indicates that the specified parameters of the function are pointers which should never be \c NULL. + * When applied as a 1-based comma separated list the compiler will emit a warning if the specified + * parameters are known at compiler time to be \c NULL at the point of calling the function. + */ + #define ATTR_NON_NULL_PTR_ARG(...) __attribute__ ((nonnull (__VA_ARGS__))) + + /** Removes any preamble or postamble from the function. When used, the function will not have any + * register or stack saving code. This should be used with caution, and when used the programmer + * is responsible for maintaining stack and register integrity. + */ + #define ATTR_NAKED __attribute__ ((naked)) + + /** Prevents the compiler from considering a specified function for in-lining. When applied, the given + * function will not be in-lined under any circumstances. + */ + #define ATTR_NO_INLINE __attribute__ ((noinline)) + + /** Forces the compiler to never inline the specified function. When applied, the given function will be + * always be called explicitly under all circumstances. + */ + #define ATTR_NEVER_INLINE __attribute__ ((noinline)) + + /** Forces the compiler to inline the specified function. When applied, the given function will be + * in-lined under all circumstances. + */ + #define ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) + + /** Indicates that the specified function is pure, in that it has no side-effects other than global + * or parameter variable access. + */ + #define ATTR_PURE __attribute__ ((pure)) + + /** Indicates that the specified function is constant, in that it has no side effects other than + * parameter access. + */ + #define ATTR_CONST __attribute__ ((const)) + + /** Marks a given function as deprecated, which produces a warning if the function is called. */ + #define ATTR_DEPRECATED __attribute__ ((deprecated)) + + /** Marks a function as a weak reference, which can be overridden by other functions with an + * identical name (in which case the weak reference is discarded at link time). + */ + #define ATTR_WEAK __attribute__ ((weak)) + #endif + + /** Forces the compiler to not automatically zero the given global variable on startup, so that the + * current RAM contents is retained. Under most conditions this value will be random due to the + * behavior of volatile memory once power is removed, but may be used in some specific circumstances, + * like the passing of values back after a system watchdog reset. + */ + #define ATTR_NO_INIT __attribute__ ((section (".noinit"))) + + /** Places the function in one of the initialization sections, which execute before the main function + * of the application. Refer to the avr-libc manual for more information on the initialization sections. + * + * \param[in] SectionIndex Initialization section number where the function should be placed. + */ + #define ATTR_INIT_SECTION(SectionIndex) __attribute__ ((used, naked, section (".init" #SectionIndex ))) + + /** Marks a function as an alias for another function. + * + * \param[in] Func Name of the function which the given function name should alias. + */ + #define ATTR_ALIAS(Func) __attribute__ ((alias( #Func ))) + + /** Marks a variable or struct element for packing into the smallest space available, omitting any + * alignment bytes usually added between fields to optimize field accesses. + */ + #define ATTR_PACKED __attribute__ ((packed)) + + /** Indicates the minimum alignment in bytes for a variable or struct element. + * + * \param[in] Bytes Minimum number of bytes the item should be aligned to. + */ + #define ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/BoardTypes.h b/Firmware/LUFA/Common/BoardTypes.h new file mode 100644 index 00000000..98241e5a --- /dev/null +++ b/Firmware/LUFA/Common/BoardTypes.h @@ -0,0 +1,248 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Supported pre-made board hardware defines. + * + * \copydetails Group_BoardTypes + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_BoardTypes Board Types + * \brief Supported pre-made board hardware defines. + * + * Board macros for indicating the chosen physical board hardware to the library. These macros should be used when + * defining the \c BOARD token to the chosen hardware via the \c -D switch in the project makefile. If a custom + * board is used, the \ref BOARD_NONE or \ref BOARD_USER values should be selected. + * + * @{ + */ + +#ifndef __LUFA_BOARDTYPES_H__ +#define __LUFA_BOARDTYPES_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Selects the user-defined board drivers, which should be placed in the user project's folder + * under a directory named \c /Board/. Each board driver should be named identically to the LUFA + * master board driver (i.e., driver in the \c LUFA/Drivers/Board directory) so that the library + * can correctly identify it. + */ + #define BOARD_USER 0 + + /** Disables board drivers when operation will not be adversely affected (e.g. LEDs) - use of board drivers + * such as the Joystick driver, where the removal would adversely affect the code's operation is still disallowed. */ + #define BOARD_NONE 1 + + /** Selects the USBKEY specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_USBKEY 2 + + /** Selects the STK525 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_STK525 3 + + /** Selects the STK526 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_STK526 4 + + /** Selects the RZUSBSTICK specific board drivers, including the driver for the boards LEDs. */ + #define BOARD_RZUSBSTICK 5 + + /** Selects the ATAVRUSBRF01 specific board drivers, including the driver for the board LEDs. */ + #define BOARD_ATAVRUSBRF01 6 + + /** Selects the BUMBLEB specific board drivers, using the officially recommended peripheral layout. */ + #define BOARD_BUMBLEB 7 + + /** Selects the XPLAIN (Revision 2 or newer) specific board drivers, including LED and Dataflash drivers. */ + #define BOARD_XPLAIN 8 + + /** Selects the XPLAIN (Revision 1) specific board drivers, including LED and Dataflash drivers. */ + #define BOARD_XPLAIN_REV1 9 + + /** Selects the EVK527 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_EVK527 10 + + /** Selects the Teensy version 1.x specific board drivers, including the driver for the board LEDs. */ + #define BOARD_TEENSY 11 + + /** Selects the USBTINY MKII specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USBTINYMKII 12 + + /** Selects the Benito specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_BENITO 13 + + /** Selects the JM-DB-U2 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_JMDBU2 14 + + /** Selects the Olimex AVR-USB-162 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_OLIMEX162 15 + + /** Selects the UDIP specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_UDIP 16 + + /** Selects the BUI specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BUI 17 + + /** Selects the Arduino Uno specific board drivers, including the driver for the board LEDs. */ + #define BOARD_UNO 18 + + /** Selects the Busware CUL V3 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_CULV3 19 + + /** Selects the Blackcat USB JTAG specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BLACKCAT 20 + + /** Selects the Maximus specific board drivers, including the driver for the board LEDs. */ + #define BOARD_MAXIMUS 21 + + /** Selects the Minimus specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_MINIMUS 22 + + /** Selects the Adafruit U4 specific board drivers, including the Button driver. */ + #define BOARD_ADAFRUITU4 23 + + /** Selects the Microsin AVR-USB162 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_MICROSIN162 24 + + /** Selects the Kernel Concepts USBFOO specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USBFOO 25 + + /** Selects the Sparkfun ATMEGA8U2 specific board drivers, including the driver for the board LEDs. */ + #define BOARD_SPARKFUN8U2 26 + + /** Selects the Atmel EVK1101 specific board drivers, including the Button, Joystick and LED drivers. */ + #define BOARD_EVK1101 27 + + /** Selects the Busware TUL specific board drivers, including the Button and LED drivers. */ + #define BOARD_TUL 28 + + /** Selects the Atmel EVK1100 specific board drivers, including the Button, Joystick and LED drivers. */ + #define BOARD_EVK1100 29 + + /** Selects the Atmel EVK1104 specific board drivers, including the Button and LED drivers. */ + #define BOARD_EVK1104 30 + + /** Selects the Atmel XMEGA A3BU Xplained specific board drivers, including Dataflash, Button and LED drivers. */ + #define BOARD_A3BU_XPLAINED 31 + + /** Selects the Teensy version 2.x specific board drivers, including the driver for the board LEDs. */ + #define BOARD_TEENSY2 32 + + /** Selects the USB2AX version 1 and 2 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USB2AX 33 + + /** Selects the USB2AX version 3 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USB2AX_V3 34 + + /** Selects the Micropendous 32U2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_32U2 35 + + /** Selects the Micropendous A specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_A 36 + + /** Selects the Micropendous 1 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_1 37 + + /** Selects the Micropendous 2 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_2 38 + + /** Selects the Micropendous 3 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_3 39 + + /** Selects the Micropendous 4 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_4 40 + + /** Selects the Micropendous DIP specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_DIP 41 + + /** Selects the Micropendous (Arduino-like) revision 1 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_REV1 42 + + /** Selects the Micropendous (Arduino-like) revision 2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_REV2 43 + + /** Selects the XMEGA B1 Xplained specific board drivers, including the Button and LED drivers. */ + #define BOARD_B1_XPLAINED 44 + + /** Selects the Bitwizard Multio specific board drivers, including the driver for the board LEDs. */ + #define BOARD_MULTIO 45 + + /** Selects the Bitwizard Big-Multio specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BIGMULTIO 46 + + /** Selects the DorkbotPDX Duce specific board drivers, including the driver for the board LEDs. */ + #define BOARD_DUCE 47 + + /** Selects the Olimex AVR-USB-32U4 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEX32U4 48 + + /** Selects the Olimex AVR-USB-T32U4 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEXT32U4 49 + + /** Selects the Olimex AVR-ISP-MK2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEXISPMK2 50 + + /** Selects the Arduino Leonardo specific board drivers, including the driver for the board LEDs. */ + #define BOARD_LEONARDO 51 + + /** Selects the UC3-A3 Xplained specific board drivers, including the Button and LED drivers. */ + #define BOARD_UC3A3_XPLAINED 52 + + /** Selects the USB2AX version 3.1 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USB2AX_V31 53 + + /** Selects the Stange-ISP specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_STANGE_ISP 54 + + /** Selects the XMEGA C3 XPLAINED specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_C3_XPLAINED 55 + + /** Selects the U2S specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_U2S 56 + + #if !defined(__DOXYGEN__) + #define BOARD_ BOARD_NONE + + #if !defined(BOARD) + #define BOARD BOARD_NONE + #endif + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/Common.h b/Firmware/LUFA/Common/Common.h new file mode 100644 index 00000000..2b6b1257 --- /dev/null +++ b/Firmware/LUFA/Common/Common.h @@ -0,0 +1,401 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \dir + * \brief Common library header files. + * + * This folder contains header files which are common to all parts of the LUFA library. They may be used freely in + * user applications. + */ + +/** \file + * \brief Common library convenience headers, macros and functions. + * + * \copydetails Group_Common + */ + +/** \defgroup Group_Common Common Utility Headers - LUFA/Drivers/Common/Common.h + * \brief Common library convenience headers, macros and functions. + * + * Common utility headers containing macros, functions, enums and types which are common to all + * aspects of the library. + * + * @{ + */ + +/** \defgroup Group_GlobalInt Global Interrupt Macros + * \brief Convenience macros for the management of interrupts globally within the device. + * + * Macros and functions to create and control global interrupts within the device. + */ + +#ifndef __LUFA_COMMON_H__ +#define __LUFA_COMMON_H__ + + /* Macros: */ + #define __INCLUDE_FROM_COMMON_H + + /* Includes: */ + #include + #include + #include + #include + + #include "Architectures.h" + #include "BoardTypes.h" + #include "ArchitectureSpecific.h" + #include "CompilerSpecific.h" + #include "Attributes.h" + + #if defined(USE_LUFA_CONFIG_HEADER) + #include "LUFAConfig.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Architecture specific utility includes: */ + #if defined(__DOXYGEN__) + /** Type define for an unsigned integer the same width as the selected architecture's machine register. + * This is distinct from the non-specific standard int data type, whose width is machine dependant but + * which may not reflect the actual machine register width on some targets (e.g. AVR8). + */ + typedef MACHINE_REG_t uint_reg_t; + #elif (ARCH == ARCH_AVR8) + #include + #include + #include + #include + #include + #include + #include + + typedef uint8_t uint_reg_t; + + #define ARCH_HAS_EEPROM_ADDRESS_SPACE + #define ARCH_HAS_FLASH_ADDRESS_SPACE + #define ARCH_HAS_MULTI_ADDRESS_SPACE + #define ARCH_LITTLE_ENDIAN + + #include "Endianness.h" + #elif (ARCH == ARCH_UC3) + #include + #include + + // === TODO: Find abstracted way to handle these === + #define PROGMEM + #define pgm_read_byte(x) *x + #define memcmp_P(...) memcmp(__VA_ARGS__) + #define memcpy_P(...) memcpy(__VA_ARGS__) + // ================================================= + + typedef uint32_t uint_reg_t; + + #define ARCH_BIG_ENDIAN + + #include "Endianness.h" + #elif (ARCH == ARCH_XMEGA) + #include + #include + #include + #include + #include + #include + + typedef uint8_t uint_reg_t; + + #define ARCH_HAS_EEPROM_ADDRESS_SPACE + #define ARCH_HAS_FLASH_ADDRESS_SPACE + #define ARCH_HAS_MULTI_ADDRESS_SPACE + #define ARCH_LITTLE_ENDIAN + + #include "Endianness.h" + #else + #error Unknown device architecture specified. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Macro for encasing other multi-statement macros. This should be used along with an opening brace + * before the start of any multi-statement macro, so that the macros contents as a whole are treated + * as a discrete block and not as a list of separate statements which may cause problems when used as + * a block (such as inline \c if statements). + */ + #define MACROS do + + /** Macro for encasing other multi-statement macros. This should be used along with a preceding closing + * brace at the end of any multi-statement macro, so that the macros contents as a whole are treated + * as a discrete block and not as a list of separate statements which may cause problems when used as + * a block (such as inline \c if statements). + */ + #define MACROE while (0) + + /** Convenience macro to determine the larger of two values. + * + * \attention This macro should only be used with operands that do not have side effects from being evaluated + * multiple times. + * + * \param[in] x First value to compare + * \param[in] y First value to compare + * + * \return The larger of the two input parameters + */ + #if !defined(MAX) || defined(__DOXYGEN__) + #define MAX(x, y) (((x) > (y)) ? (x) : (y)) + #endif + + /** Convenience macro to determine the smaller of two values. + * + * \attention This macro should only be used with operands that do not have side effects from being evaluated + * multiple times. + * + * \param[in] x First value to compare. + * \param[in] y First value to compare. + * + * \return The smaller of the two input parameters + */ + #if !defined(MIN) || defined(__DOXYGEN__) + #define MIN(x, y) (((x) < (y)) ? (x) : (y)) + #endif + + #if !defined(STRINGIFY) || defined(__DOXYGEN__) + /** Converts the given input into a string, via the C Preprocessor. This macro puts literal quotation + * marks around the input, converting the source into a string literal. + * + * \param[in] x Input to convert into a string literal. + * + * \return String version of the input. + */ + #define STRINGIFY(x) #x + + /** Converts the given input into a string after macro expansion, via the C Preprocessor. This macro puts + * literal quotation marks around the expanded input, converting the source into a string literal. + * + * \param[in] x Input to expand and convert into a string literal. + * + * \return String version of the expanded input. + */ + #define STRINGIFY_EXPANDED(x) STRINGIFY(x) + #endif + + #if !defined(CONCAT) || defined(__DOXYGEN__) + /** Concatenates the given input into a single token, via the C Preprocessor. + * + * \param[in] x First item to concatenate. + * \param[in] y Second item to concatenate. + * + * \return Concatenated version of the input. + */ + #define CONCAT(x, y) x ## y + + /** CConcatenates the given input into a single token after macro expansion, via the C Preprocessor. + * + * \param[in] x First item to concatenate. + * \param[in] y Second item to concatenate. + * + * \return Concatenated version of the expanded input. + */ + #define CONCAT_EXPANDED(x, y) CONCAT(x, y) + #endif + + #if !defined(ISR) || defined(__DOXYGEN__) + /** Macro for the definition of interrupt service routines, so that the compiler can insert the required + * prologue and epilogue code to properly manage the interrupt routine without affecting the main thread's + * state with unintentional side-effects. + * + * Interrupt handlers written using this macro may still need to be registered with the microcontroller's + * Interrupt Controller (if present) before they will properly handle incoming interrupt events. + * + * \note This macro is only supplied on some architectures, where the standard library does not include a valid + * definition. If an existing definition exists, the alternative definition here will be ignored. + * + * \ingroup Group_GlobalInt + * + * \param[in] Name Unique name of the interrupt service routine. + */ + #define ISR(Name, ...) void Name (void) __attribute__((__interrupt__)) __VA_ARGS__; void Name (void) + #endif + + /* Inline Functions: */ + /** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1, + * etc. + * + * \param[in] Byte Byte of data whose bits are to be reversed. + * + * \return Input data with the individual bits reversed (mirrored). + */ + static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint8_t BitReverse(uint8_t Byte) + { + Byte = (((Byte & 0xF0) >> 4) | ((Byte & 0x0F) << 4)); + Byte = (((Byte & 0xCC) >> 2) | ((Byte & 0x33) << 2)); + Byte = (((Byte & 0xAA) >> 1) | ((Byte & 0x55) << 1)); + + return Byte; + } + + /** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be + * at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations + * may be slightly higher. + * + * \param[in] Milliseconds Number of milliseconds to delay + */ + static inline void Delay_MS(uint16_t Milliseconds) ATTR_ALWAYS_INLINE; + static inline void Delay_MS(uint16_t Milliseconds) + { + #if (ARCH == ARCH_AVR8) + if (GCC_IS_COMPILE_CONST(Milliseconds)) + { + _delay_ms(Milliseconds); + } + else + { + while (Milliseconds--) + _delay_ms(1); + } + #elif (ARCH == ARCH_UC3) + while (Milliseconds--) + { + __builtin_mtsr(AVR32_COUNT, 0); + while ((uint32_t)__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000)); + } + #elif (ARCH == ARCH_XMEGA) + if (GCC_IS_COMPILE_CONST(Milliseconds)) + { + _delay_ms(Milliseconds); + } + else + { + while (Milliseconds--) + _delay_ms(1); + } + #endif + } + + /** Retrieves a mask which contains the current state of the global interrupts for the device. This + * value can be stored before altering the global interrupt enable state, before restoring the + * flag(s) back to their previous values after a critical section using \ref SetGlobalInterruptMask(). + * + * \ingroup Group_GlobalInt + * + * \return Mask containing the current Global Interrupt Enable Mask bit(s). + */ + static inline uint_reg_t GetGlobalInterruptMask(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint_reg_t GetGlobalInterruptMask(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + return SREG; + #elif (ARCH == ARCH_UC3) + return __builtin_mfsr(AVR32_SR); + #elif (ARCH == ARCH_XMEGA) + return SREG; + #endif + } + + /** Sets the global interrupt enable state of the microcontroller to the mask passed into the function. + * This can be combined with \ref GetGlobalInterruptMask() to save and restore the Global Interrupt Enable + * Mask bit(s) of the device after a critical section has completed. + * + * \ingroup Group_GlobalInt + * + * \param[in] GlobalIntState Global Interrupt Enable Mask value to use + */ + static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE; + static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + SREG = GlobalIntState; + #elif (ARCH == ARCH_UC3) + if (GlobalIntState & AVR32_SR_GM) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + else + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + SREG = GlobalIntState; + #endif + + GCC_MEMORY_BARRIER(); + } + + /** Enables global interrupt handling for the device, allowing interrupts to be handled. + * + * \ingroup Group_GlobalInt + */ + static inline void GlobalInterruptEnable(void) ATTR_ALWAYS_INLINE; + static inline void GlobalInterruptEnable(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + sei(); + #elif (ARCH == ARCH_UC3) + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + sei(); + #endif + + GCC_MEMORY_BARRIER(); + } + + /** Disabled global interrupt handling for the device, preventing interrupts from being handled. + * + * \ingroup Group_GlobalInt + */ + static inline void GlobalInterruptDisable(void) ATTR_ALWAYS_INLINE; + static inline void GlobalInterruptDisable(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + cli(); + #elif (ARCH == ARCH_UC3) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + cli(); + #endif + + GCC_MEMORY_BARRIER(); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/CompilerSpecific.h b/Firmware/LUFA/Common/CompilerSpecific.h new file mode 100644 index 00000000..b20f4a9d --- /dev/null +++ b/Firmware/LUFA/Common/CompilerSpecific.h @@ -0,0 +1,97 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Compiler specific definitions for code optimization and correctness. + * + * \copydetails Group_CompilerSpecific + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_CompilerSpecific Compiler Specific Definitions + * \brief Compiler specific definitions for code optimization and correctness. + * + * Compiler specific definitions to expose certain compiler features which may increase the level of code optimization + * for a specific compiler, or correct certain issues that may be present such as memory barriers for use in conjunction + * with atomic variable access. + * + * Where possible, on alternative compilers, these macros will either have no effect, or default to returning a sane value + * so that they can be used in existing code without the need for extra compiler checks in the user application code. + * + * @{ + */ + +#ifndef __LUFA_COMPILERSPEC_H__ +#define __LUFA_COMPILERSPEC_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if defined(__GNUC__) || defined(__DOXYGEN__) + /** Forces GCC to use pointer indirection (via the device's pointer register pairs) when accessing the given + * struct pointer. In some cases GCC will emit non-optimal assembly code when accessing a structure through + * a pointer, resulting in a larger binary. When this macro is used on a (non \c const) structure pointer before + * use, it will force GCC to use pointer indirection on the elements rather than direct store and load + * instructions. + * + * \param[in, out] StructPtr Pointer to a structure which is to be forced into indirect access mode. + */ + #define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr)) + + /** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point. + * This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting + * assembly output in an unexpected manner on sections of code that are ordering-specific. + */ + #define GCC_MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory"); + + /** Determines if the specified value can be determined at compile-time to be a constant value when compiling under GCC. + * + * \param[in] x Value to check compile-time constantness of. + * + * \return Boolean \c true if the given value is known to be a compile time constant, \c false otherwise. + */ + #define GCC_IS_COMPILE_CONST(x) __builtin_constant_p(x) + #else + #define GCC_FORCE_POINTER_ACCESS(StructPtr) + #define GCC_MEMORY_BARRIER() + #define GCC_IS_COMPILE_CONST(x) 0 + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Common/Endianness.h b/Firmware/LUFA/Common/Endianness.h new file mode 100644 index 00000000..9b807d99 --- /dev/null +++ b/Firmware/LUFA/Common/Endianness.h @@ -0,0 +1,493 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2013. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endianness and Byte Ordering macros and functions. + * + * \copydetails Group_Endianness + */ + +/** \ingroup Group_Endianness + * \defgroup Group_ByteSwapping Byte Reordering + * \brief Macros and functions for forced byte reordering. + */ + +/** \ingroup Group_Endianness + * \defgroup Group_EndianConversion Endianness Conversion + * \brief Macros and functions for automatic endianness conversion. + */ + +/** \ingroup Group_Common + * \defgroup Group_Endianness Endianness and Byte Ordering + * \brief Convenience macros and functions relating to byte (re-)ordering + * + * Common library convenience macros and functions relating to byte (re-)ordering. + * + * @{ + */ + +#ifndef __LUFA_ENDIANNESS_H__ +#define __LUFA_ENDIANNESS_H__ + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + #if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN)) + #error ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set for the specified architecture. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Swaps the byte ordering of a 16-bit value at compile-time. Do not use this macro for swapping byte orderings + * of dynamic values computed at runtime, use \ref SwapEndian_16() instead. The result of this macro can be used + * inside struct or other variable initializers outside of a function, something that is not possible with the + * inline function variant. + * + * \hideinitializer + * + * \ingroup Group_ByteSwapping + * + * \param[in] x 16-bit value whose byte ordering is to be swapped. + * + * \return Input value with the byte ordering reversed. + */ + #define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) + + /** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings + * of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used + * inside struct or other variable initializers outside of a function, something that is not possible with the + * inline function variant. + * + * \hideinitializer + * + * \ingroup Group_ByteSwapping + * + * \param[in] x 32-bit value whose byte ordering is to be swapped. + * + * \return Input value with the byte ordering reversed. + */ + #define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \ + (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL)) + + #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu) + #define le16_to_cpu(x) SwapEndian_16(x) + #define le32_to_cpu(x) SwapEndian_32(x) + #define be16_to_cpu(x) (x) + #define be32_to_cpu(x) (x) + #define cpu_to_le16(x) SwapEndian_16(x) + #define cpu_to_le32(x) SwapEndian_32(x) + #define cpu_to_be16(x) (x) + #define cpu_to_be32(x) (x) + #define LE16_TO_CPU(x) SWAPENDIAN_16(x) + #define LE32_TO_CPU(x) SWAPENDIAN_32(x) + #define BE16_TO_CPU(x) (x) + #define BE32_TO_CPU(x) (x) + #define CPU_TO_LE16(x) SWAPENDIAN_16(x) + #define CPU_TO_LE32(x) SWAPENDIAN_32(x) + #define CPU_TO_BE16(x) (x) + #define CPU_TO_BE32(x) (x) + #elif !defined(le16_to_cpu) + /** \name Run-time endianness conversion */ + //@{ + + /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref LE16_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define le16_to_cpu(x) (x) + + /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref LE32_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define le32_to_cpu(x) (x) + + /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref BE16_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define be16_to_cpu(x) SwapEndian_16(x) + + /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref BE32_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define be32_to_cpu(x) SwapEndian_32(x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_LE16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_le16(x) (x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_LE32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_le32(x) (x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_BE16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_be16(x) SwapEndian_16(x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_BE32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_be32(x) SwapEndian_32(x) + + //@} + + /** \name Compile-time endianness conversion */ + //@{ + + /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run time endianness + * conversion, use \ref le16_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define LE16_TO_CPU(x) (x) + + /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run time endianness + * conversion, use \ref le32_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define LE32_TO_CPU(x) (x) + + /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref be16_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define BE16_TO_CPU(x) SWAPENDIAN_16(x) + + /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref be32_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define BE32_TO_CPU(x) SWAPENDIAN_32(x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_le16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_LE16(x) (x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_le32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_LE32(x) (x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_be16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_BE16(x) SWAPENDIAN_16(x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_be32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_BE32(x) SWAPENDIAN_32(x) + + //! @} + #endif + + /* Inline Functions: */ + /** Function to reverse the byte ordering of the individual bytes in a 16 bit value. + * + * \ingroup Group_ByteSwapping + * + * \param[in] Word Word of data whose bytes are to be swapped. + * + * \return Input data with the individual bytes reversed. + */ + static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint16_t SwapEndian_16(const uint16_t Word) + { + if (GCC_IS_COMPILE_CONST(Word)) + return SWAPENDIAN_16(Word); + + uint8_t Temp; + + union + { + uint16_t Word; + uint8_t Bytes[2]; + } Data; + + Data.Word = Word; + + Temp = Data.Bytes[0]; + Data.Bytes[0] = Data.Bytes[1]; + Data.Bytes[1] = Temp; + + return Data.Word; + } + + /** Function to reverse the byte ordering of the individual bytes in a 32 bit value. + * + * \ingroup Group_ByteSwapping + * + * \param[in] DWord Double word of data whose bytes are to be swapped. + * + * \return Input data with the individual bytes reversed. + */ + static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint32_t SwapEndian_32(const uint32_t DWord) + { + if (GCC_IS_COMPILE_CONST(DWord)) + return SWAPENDIAN_32(DWord); + + uint8_t Temp; + + union + { + uint32_t DWord; + uint8_t Bytes[4]; + } Data; + + Data.DWord = DWord; + + Temp = Data.Bytes[0]; + Data.Bytes[0] = Data.Bytes[3]; + Data.Bytes[3] = Temp; + + Temp = Data.Bytes[1]; + Data.Bytes[1] = Data.Bytes[2]; + Data.Bytes[2] = Temp; + + return Data.DWord; + } + + /** Function to reverse the byte ordering of the individual bytes in a n byte value. + * + * \ingroup Group_ByteSwapping + * + * \param[in,out] Data Pointer to a number containing an even number of bytes to be reversed. + * \param[in] Length Length of the data in bytes. + * + * \return Input data with the individual bytes reversed. + */ + static inline void SwapEndian_n(void* const Data, + uint8_t Length) ATTR_NON_NULL_PTR_ARG(1); + static inline void SwapEndian_n(void* const Data, + uint8_t Length) + { + uint8_t* CurrDataPos = (uint8_t*)Data; + + while (Length > 1) + { + uint8_t Temp = *CurrDataPos; + *CurrDataPos = *(CurrDataPos + Length - 1); + *(CurrDataPos + Length - 1) = Temp; + + CurrDataPos++; + Length -= 2; + } + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/Firmware/LUFA/Doxygen.conf b/Firmware/LUFA/Doxygen.conf new file mode 100644 index 00000000..1d578806 --- /dev/null +++ b/Firmware/LUFA/Doxygen.conf @@ -0,0 +1,2317 @@ +# Doxyfile 1.8.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "LUFA Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 000000 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = ./DoxygenPages/Images/LUFA_thumb.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./Documentation/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- +# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, +# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = NO + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = YES + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: NO. + +SORT_BRIEF_DOCS = YES + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = YES + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 1 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = ./ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.h \ + *.txt + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = Documentation/ \ + StudioIntegration/ \ + License.txt + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = _* \ + __* + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ./ \ + CodeTemplates/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = ./ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = NO + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +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 a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = ./DoxygenPages/Style/Footer.htm + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = ./DoxygenPages/Style/Style.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_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. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 120 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_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. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = com.lufa-lib.library.documentation + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = DeanCamera + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = ../LUFA.chm + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 1 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 300 + +# 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. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# 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 directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +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 MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /