I'm trying to port GRBL 1.1 to the STM32F746 chip. Tell me the solution, thanks.

Files at this revision

API Documentation at this revision

Comitter:
Sergunb
Date:
Mon Sep 04 12:05:05 2017 +0000
Commit message:
Initial commit

Changed in this revision

COPYING Show annotated file Show diff for this revision Revisions of this file
Makefile Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
build/.gitignore Show annotated file Show diff for this revision Revisions of this file
cmsis/core_cm3.h Show annotated file Show diff for this revision Revisions of this file
cmsis/core_cmFunc.h Show annotated file Show diff for this revision Revisions of this file
cmsis/core_cmInstr.h Show annotated file Show diff for this revision Revisions of this file
cmsis_boot/startup/startup_stm32f10x_md.c Show annotated file Show diff for this revision Revisions of this file
cmsis_boot/stm32f10x.h Show annotated file Show diff for this revision Revisions of this file
cmsis_boot/stm32f10x_conf.h Show annotated file Show diff for this revision Revisions of this file
cmsis_boot/system_stm32f10x.c Show annotated file Show diff for this revision Revisions of this file
cmsis_boot/system_stm32f10x.h Show annotated file Show diff for this revision Revisions of this file
doc/csv/alarm_codes_en_US.csv Show annotated file Show diff for this revision Revisions of this file
doc/csv/build_option_codes_en_US.csv Show annotated file Show diff for this revision Revisions of this file
doc/csv/error_codes_en_US.csv Show annotated file Show diff for this revision Revisions of this file
doc/csv/setting_codes_en_US.csv Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v0.7.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v0.8c.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v0.9g.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v0.9i.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v0.9j.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v1.0b.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v1.0c.txt Show annotated file Show diff for this revision Revisions of this file
doc/log/commit_log_v1.1.txt Show annotated file Show diff for this revision Revisions of this file
doc/markdown/change_summary.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/commands.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/interface.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/jogging.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/laser_mode.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/old_wiki_pages/interface_notes.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/realtime_cmds.md Show annotated file Show diff for this revision Revisions of this file
doc/markdown/settings.md Show annotated file Show diff for this revision Revisions of this file
doc/media/COPYING Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo 150px.png Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo 250px.png Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo 320px.png Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo 640px.png Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo.pdf Show annotated file Show diff for this revision Revisions of this file
doc/media/Grbl Logo.svg Show annotated file Show diff for this revision Revisions of this file
doc/script/simple_stream.py Show annotated file Show diff for this revision Revisions of this file
doc/script/stream.py Show annotated file Show diff for this revision Revisions of this file
grbl/config.h Show annotated file Show diff for this revision Revisions of this file
grbl/coolant_control.c Show annotated file Show diff for this revision Revisions of this file
grbl/coolant_control.h Show annotated file Show diff for this revision Revisions of this file
grbl/cpu_map.h Show annotated file Show diff for this revision Revisions of this file
grbl/cpu_map.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/defaults.h Show annotated file Show diff for this revision Revisions of this file
grbl/defaults.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/eeprom.c Show annotated file Show diff for this revision Revisions of this file
grbl/eeprom.h Show annotated file Show diff for this revision Revisions of this file
grbl/examples/grblUpload/grblUpload.ino Show annotated file Show diff for this revision Revisions of this file
grbl/examples/grblUpload/license.txt Show annotated file Show diff for this revision Revisions of this file
grbl/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino Show annotated file Show diff for this revision Revisions of this file
grbl/examples/grblWrite_BuildInfo/license.txt Show annotated file Show diff for this revision Revisions of this file
grbl/gcode.c Show annotated file Show diff for this revision Revisions of this file
grbl/gcode.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/gcode.h Show annotated file Show diff for this revision Revisions of this file
grbl/grbl.h Show annotated file Show diff for this revision Revisions of this file
grbl/grbl.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/jog.c Show annotated file Show diff for this revision Revisions of this file
grbl/jog.h Show annotated file Show diff for this revision Revisions of this file
grbl/limits.c Show annotated file Show diff for this revision Revisions of this file
grbl/limits.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/limits.h Show annotated file Show diff for this revision Revisions of this file
grbl/main.c Show annotated file Show diff for this revision Revisions of this file
grbl/main.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/motion_control.c Show annotated file Show diff for this revision Revisions of this file
grbl/motion_control.h Show annotated file Show diff for this revision Revisions of this file
grbl/nuts_bolts.c Show annotated file Show diff for this revision Revisions of this file
grbl/nuts_bolts.h Show annotated file Show diff for this revision Revisions of this file
grbl/nuts_bolts.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/planner.c Show annotated file Show diff for this revision Revisions of this file
grbl/planner.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/planner.h Show annotated file Show diff for this revision Revisions of this file
grbl/planner.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/print.c Show annotated file Show diff for this revision Revisions of this file
grbl/print.h Show annotated file Show diff for this revision Revisions of this file
grbl/probe.c Show annotated file Show diff for this revision Revisions of this file
grbl/probe.h Show annotated file Show diff for this revision Revisions of this file
grbl/protocol.c Show annotated file Show diff for this revision Revisions of this file
grbl/protocol.h Show annotated file Show diff for this revision Revisions of this file
grbl/report.c Show annotated file Show diff for this revision Revisions of this file
grbl/report.h Show annotated file Show diff for this revision Revisions of this file
grbl/serial.c Show annotated file Show diff for this revision Revisions of this file
grbl/serial.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/serial.h Show annotated file Show diff for this revision Revisions of this file
grbl/serial.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/settings.c Show annotated file Show diff for this revision Revisions of this file
grbl/settings.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/settings.h Show annotated file Show diff for this revision Revisions of this file
grbl/spindle_control.c Show annotated file Show diff for this revision Revisions of this file
grbl/spindle_control.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/spindle_control.h Show annotated file Show diff for this revision Revisions of this file
grbl/stepper.c Show annotated file Show diff for this revision Revisions of this file
grbl/stepper.h Show annotated file Show diff for this revision Revisions of this file
grbl/stepper.h.bak Show annotated file Show diff for this revision Revisions of this file
grbl/system.c Show annotated file Show diff for this revision Revisions of this file
grbl/system.c.bak Show annotated file Show diff for this revision Revisions of this file
grbl/system.h Show annotated file Show diff for this revision Revisions of this file
grbl/system.h.bak Show annotated file Show diff for this revision Revisions of this file
grblwin/.vs/grblwin/v14/.suo Show annotated file Show diff for this revision Revisions of this file
grblwin/ReadMe.txt Show annotated file Show diff for this revision Revisions of this file
grblwin/eeprom.bin Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.VC.db Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.sdf Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.sln Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.suo Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.v12.suo Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.vcxproj Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.vcxproj.filters Show annotated file Show diff for this revision Revisions of this file
grblwin/grblwin.vcxproj.user Show annotated file Show diff for this revision Revisions of this file
grblwin/ipch/grblwin-905085aa/grblwin-3bc7f0ad.ipch Show annotated file Show diff for this revision Revisions of this file
stm32grbl.cogui Show annotated file Show diff for this revision Revisions of this file
stm32grbl.comarker Show annotated file Show diff for this revision Revisions of this file
stm32grbl11.coproj Show annotated file Show diff for this revision Revisions of this file
stm32grbl11d.coproj Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/misc.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_exti.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_flash.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_gpio.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_rcc.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_tim.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/inc/stm32f10x_usart.h Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/misc.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_exti.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_flash.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_gpio.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_rcc.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_tim.c Show annotated file Show diff for this revision Revisions of this file
stm_lib/src/stm32f10x_usart.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_conf.hh Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_core.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_def.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_init.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_int.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_lib.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_mem.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_regs.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_sil.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/inc/usb_type.h Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_core.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_init.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_int.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_mem.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_regs.c Show annotated file Show diff for this revision Revisions of this file
stm_usb_fs_lib/src/usb_sil.c Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Entries Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Entries.Extra Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Entries.Extra.Old Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Entries.Old Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Repository Show annotated file Show diff for this revision Revisions of this file
usb/CVS/Root Show annotated file Show diff for this revision Revisions of this file
usb/hw_config.c Show annotated file Show diff for this revision Revisions of this file
usb/hw_config.h Show annotated file Show diff for this revision Revisions of this file
usb/platform_config.h Show annotated file Show diff for this revision Revisions of this file
usb/stm32f10x_it.h Show annotated file Show diff for this revision Revisions of this file
usb/usb_conf.h Show annotated file Show diff for this revision Revisions of this file
usb/usb_desc.c Show annotated file Show diff for this revision Revisions of this file
usb/usb_desc.c.bak Show annotated file Show diff for this revision Revisions of this file
usb/usb_desc.h Show annotated file Show diff for this revision Revisions of this file
usb/usb_endp.c Show annotated file Show diff for this revision Revisions of this file
usb/usb_endp.c.bak Show annotated file Show diff for this revision Revisions of this file
usb/usb_istr.c Show annotated file Show diff for this revision Revisions of this file
usb/usb_istr.h Show annotated file Show diff for this revision Revisions of this file
usb/usb_prop.c Show annotated file Show diff for this revision Revisions of this file
usb/usb_prop.h Show annotated file Show diff for this revision Revisions of this file
usb/usb_pwr.c Show annotated file Show diff for this revision Revisions of this file
usb/usb_pwr.h Show annotated file Show diff for this revision Revisions of this file
util/CVS/Entries Show annotated file Show diff for this revision Revisions of this file
util/CVS/Entries.Extra Show annotated file Show diff for this revision Revisions of this file
util/CVS/Entries.Extra.Old Show annotated file Show diff for this revision Revisions of this file
util/CVS/Entries.Old Show annotated file Show diff for this revision Revisions of this file
util/CVS/Repository Show annotated file Show diff for this revision Revisions of this file
util/CVS/Root Show annotated file Show diff for this revision Revisions of this file
util/stm32eeprom.h Show annotated file Show diff for this revision Revisions of this file
util/stm32f10x_it.c Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/COPYING	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,681 @@
+------------------------------------------------------------------------------
+COPYRIGHT NOTICE FOR GRBL:
+------------------------------------------------------------------------------
+
+Grbl - Embedded CNC g-code interpreter and motion-controller
+
+Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+Copyright (c) 2009-2011 Simen Svale Skogsrud
+Copyright (c) 2011 Jens Geisler
+
+Grbl is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Grbl is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+
+
+------------------------------------------------------------------------------
+COPYRIGHT NOTICE(S) FOR WORK CONTAINED IN THIS SOFTWARE:
+------------------------------------------------------------------------------
+
+Copyright (c) 2008, Atmel Corporation All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. 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.
+
+THIS SOFTWARE IS PROVIDED BY ATMEL "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 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.
+
+
+
+------------------------------------------------------------------------------
+GNU GPLv3 TERMS AND CONDITIONS REPRODUCED HERE FOR CLARITY:
+------------------------------------------------------------------------------
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,127 @@
+# detect what shell is used
+ifeq ($(findstring cmd.exe,$(SHELL)),cmd.exe)
+$(info "Info : Running on Windows shell cmd.exe")
+DEVNUL := NUL
+WHICH := where
+else
+$(info "Info : Running on Unix shell")
+DEVNUL := /dev/null
+WHICH := which
+endif
+
+
+# Find first cross compilation tools
+XTOOLS_DIR = $(abspath $(shell dirname `${WHICH} arm-none-eabi-gcc`)/..)
+
+# Set tool & Lib paths
+X_LIBC_DIR = $(XTOOLS_DIR)/arm-none-eabi/lib/armv7e-m/fpu
+X_CC = $(XTOOLS_DIR)/bin/arm-none-eabi-gcc
+X_OBJCOPY = $(XTOOLS_DIR)/bin/arm-none-eabi-objcopy
+X_AR = $(XTOOLS_DIR)/bin/arm-none-eabi-ar
+X_LD = $(XTOOLS_DIR)/bin/arm-none-eabi-ld
+X_GDB = $(XTOOLS_DIR)/bin/arm-none-eabi-gdb
+
+OUT_DIR = debug
+
+OUTPUT = grbl-stm32
+
+SRC= ./cmsis_boot/startup/startup_stm32f10x_md.c \
+     ./cmsis_boot/system_stm32f10x.c \
+     ./grbl/coolant_control.c \
+     ./grbl/eeprom.c \
+     ./grbl/gcode.c \
+     ./grbl/jog.c \
+     ./grbl/limits.c \
+     ./grbl/main.c \
+     ./grbl/motion_control.c \
+     ./grbl/nuts_bolts.c \
+     ./grbl/planner.c \
+     ./grbl/print.c \
+     ./grbl/probe.c \
+     ./grbl/protocol.c \
+     ./grbl/report.c \
+     ./grbl/serial.c \
+     ./grbl/settings.c \
+     ./grbl/spindle_control.c \
+     ./grbl/stepper.c \
+     ./grbl/system.c \
+     ./stm_lib/src/misc.c \
+     ./stm_lib/src/stm32f10x_exti.c \
+     ./stm_lib/src/stm32f10x_flash.c \
+     ./stm_lib/src/stm32f10x_gpio.c \
+     ./stm_lib/src/stm32f10x_rcc.c \
+     ./stm_lib/src/stm32f10x_tim.c \
+     ./stm_lib/src/stm32f10x_usart.c \
+     ./stm_usb_fs_lib/src/usb_core.c \
+     ./stm_usb_fs_lib/src/usb_init.c \
+     ./stm_usb_fs_lib/src/usb_int.c \
+     ./stm_usb_fs_lib/src/usb_mem.c \
+     ./stm_usb_fs_lib/src/usb_regs.c \
+     ./stm_usb_fs_lib/src/usb_sil.c \
+     ./usb/hw_config.c \
+     ./usb/usb_desc.c \
+     ./usb/usb_endp.c \
+     ./usb/usb_istr.c \
+     ./usb/usb_prop.c \
+     ./usb/usb_pwr.c \
+     ./util/stm32f10x_it.c
+
+OBJ = $(patsubst %.c, %.o, $(SRC))
+#OBJ += $(BOARD_DIR)/start.o
+
+# include files
+INC = .
+INC += cmsis
+INC += cmsis_boot
+INC += cmsis_boot/startup
+INC += grbl
+INC += stm_lib/inc
+INC += stm_lib/src
+INC += stm_usb_fs_lib/inc
+INC += stm_usb_fs_lib/src
+INC += usb
+INC += util
+
+INCLUDE = $(addprefix -I,$(INC))
+
+# compiler flags
+# as in coocox
+# -mcpu=cortex-m3 ; -mthumb ; -g2 ; -Wall ; -Os ; -DUSE_STDPERIPH_DRIVER ; -D__ASSEMBLY__ ; -D_GRBL_ ; -DSTM32F103C8 ; -DSTM32F10X_MD ; -DLEDBLINK ; -DUSEUSB ; -I. ; -Iusb ; -Iutil ; -Iuseusb ; -Igrbl ;
+
+CFLAGS = -Wall
+CFLAGS += -Os
+CFLAGS += -g2
+CFLAGS += -mthumb 
+CFLAGS += -mcpu=cortex-m3
+
+# linker flags
+LDSCRIPT = STM32F103C8T6.ld
+LDFLAGS = -T$(LDSCRIPT) -Wl,-Map,$(OUT_DIR)/$(OUTPUT).map -Wl,--gc-sections
+
+# defines
+DEFINES = -DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ -D_GRBL_ -DSTM32F103C8 -DSTM32F10X_MD -DLEDBLINK -DUSEUSB
+
+.S.o:
+	$(X_CC) $(INCLUDE) $(DEFINES) $(CFLAGS) -c $< -o $@
+.c.o:
+	$(X_CC) $(INCLUDE) $(DEFINES) $(CFLAGS) -c $< -o $@
+
+.PHONY: all flash grbl_src clean
+
+all:  $(OBJ)
+	$(X_CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -lm -o $(OUT_DIR)/$(OUTPUT)
+	mv $(OUT_DIR)/$(OUTPUT) $(OUT_DIR)/$(OUTPUT).elf
+	$(X_OBJCOPY) -O binary $(OUT_DIR)/$(OUTPUT).elf $(OUT_DIR)/$(OUTPUT).bin
+
+flash:
+	make all
+	st-flash write $(OUT_DIR)/$(OUTPUT).bin 0x08000000
+
+grbl_src:
+	make  all
+
+clean:
+	-rm $(OBJ)
+	-rm $(OUT_DIR)/$(OUTPUT).map
+	-rm $(OUT_DIR)/$(OUTPUT).bin
+	-rm $(OUT_DIR)/$(OUTPUT).elf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,85 @@
+![GitHub Logo](https://github.com/gnea/gnea-Media/blob/master/Grbl%20Logo/Grbl%20Logo%20250px.png?raw=true)
+
+***
+_Click the `Release` tab to download pre-compiled `.hex` files or just [click here](https://github.com/gnea/grbl/releases)_
+***
+Grbl is a no-compromise, high performance, low cost alternative to parallel-port-based motion control for CNC milling. This version of Grbl runs on an Arduino with a 328p processor (Uno, Duemilanove, Nano, Micro, etc).
+
+The controller is written in highly optimized C utilizing every clever feature of the AVR-chips to achieve precise timing and asynchronous operation. It is able to maintain up to 30kHz of stable, jitter free control pulses.
+
+It accepts standards-compliant g-code and has been tested with the output of several CAM tools with no problems. Arcs, circles and helical motion are fully supported, as well as, all other primary g-code commands. Macro functions, variables, and most canned cycles are not supported, but we think GUIs can do a much better job at translating them into straight g-code anyhow.
+
+Grbl includes full acceleration management with look ahead. That means the controller will look up to 16 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering.
+
+* [Licensing](https://github.com/gnea/grbl/wiki/Licensing): Grbl is free software, released under the GPLv3 license.
+
+* For more information and help, check out our **[Wiki pages!](https://github.com/gnea/grbl/wiki)** If you find that the information is out-dated, please to help us keep it updated by editing it or notifying our community! Thanks!
+
+* Lead Developer: Sungeun "Sonny" Jeon, Ph.D. (USA) aka @chamnit
+
+* Built on the wonderful Grbl v0.6 (2011) firmware written by Simen Svale Skogsrud (Norway).
+
+***
+
+### Official Supporters of the Grbl CNC Project
+![Official Supporters](https://github.com/gnea/gnea-Media/blob/master/Contributors.png?raw=true)
+
+
+***
+
+## Update Summary for v1.1
+- **IMPORTANT:** Your EEPROM will be wiped and restored with new settings. This is due to the addition of two new spindle speed '$' settings.
+
+- **Real-time Overrides** : Alters the machine running state immediately with feed, rapid, spindle speed, spindle stop, and coolant toggle controls. This awesome new feature is common only on industrial machines, often used to optimize speeds and feeds while a job is running. Most hobby CNC's try to mimic this behavior, but usually have large amounts of lag. Grbl executes overrides in realtime and within tens of milliseconds.
+
+- **Jogging Mode** : The new jogging commands are independent of the g-code parser, so that the parser state doesn't get altered and cause a potential crash if not restored properly. Documentation is included on how this works and how it can be used to control your machine via a joystick or rotary dial with a low-latency, satisfying response.
+
+- **Laser Mode** : The new "laser" mode will cause Grbl to move continuously through consecutive G1, G2, and G3 commands with spindle speed changes. When "laser" mode is disabled, Grbl will instead come to a stop to ensure a spindle comes up to speed properly. Spindle speed overrides also work with laser mode so you can tweak the laser power, if you need to during the job. Switch between "laser" mode and "normal" mode via a `$` setting.
+
+	- **Dynamic Laser Power Scaling with Speed** : If your machine has low accelerations, Grbl will automagically scale the laser power based on how fast Grbl is traveling, so you won't have burnt corners when your CNC has to make a turn! Enabled by the `M4` spindle CCW command when laser mode is enabled!
+
+- **Sleep Mode** : Grbl may now be put to "sleep" via a `$SLP` command. This will disable everything, including the stepper drivers. Nice to have when you are leaving your machine unattended and want to power down everything automatically. Only a reset exits the sleep state.
+
+- **Significant Interface Improvements**: Tweaked to increase overall performance, include lots more real-time data, and to simplify maintaining and writing GUIs. Based on direct feedback from multiple GUI developers and bench performance testing. _NOTE: GUIs need to specifically update their code to be compatible with v1.1 and later._
+
+	- **New Status Reports**: To account for the additional override data, status reports have been tweaked to cram more data into it, while still being smaller than before. Documentation is included, outlining how it has been changed. 
+	- **Improved Error/Alarm Feedback** : All Grbl error and alarm messages have been changed to providing a code. Each code is associated with a specific problem, so users will know exactly what is wrong without having to guess. Documentation and an easy to parse CSV is included in the repo.
+	- **Extended-ASCII realtime commands** : All overrides and future real-time commands are defined in the extended-ASCII character space. Unfortunately not easily type-able on a keyboard, but helps prevent accidental commands from a g-code file having these characters and gives lots of space for future expansion.
+	- **Message Prefixes** : Every message type from Grbl has a unique prefix to help GUIs immediately determine what the message is and parse it accordingly without having to know context. The prior interface had several instances of GUIs having to figure out the meaning of a message, which made everything more complicated than it needed to be.
+
+- New OEM specific features, such as safety door parking, single configuration file build option, EEPROM restrictions and restoring controls, and storing product data information.
+ 
+- New safety door parking motion as a compile-option. Grbl will retract, disable the spindle/coolant, and park near Z max. When resumed, it will perform these task in reverse order and continue the program. Highly configurable, even to add more than one parking motion. See config.h for details.
+
+- New '$' Grbl settings for max and min spindle rpm. Allows for tweaking the PWM output to more closely match true spindle rpm. When max rpm is set to zero or less than min rpm, the PWM pin D11 will act like a simple enable on/off output.
+
+- Updated G28 and G30 behavior from NIST to LinuxCNC g-code description. In short, if a intermediate motion is specified, only the axes specified will move to the stored coordinates, not all axes as before.
+
+- Lots of minor bug fixes and refactoring to make the code more efficient and flexible.
+
+- **NOTE:** Arduino Mega2560 support has been moved to an active, official Grbl-Mega [project](http://www.github.com/gnea/grbl-Mega/). All new developments here and there will be synced when it makes sense to.
+
+
+```
+List of Supported G-Codes in Grbl v1.1:
+  - Non-Modal Commands: G4, G10L2, G10L20, G28, G30, G28.1, G30.1, G53, G92, G92.1
+  - Motion Modes: G0, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80
+  - Feed Rate Modes: G93, G94
+  - Unit Modes: G20, G21
+  - Distance Modes: G90, G91
+  - Arc IJK Distance Modes: G91.1
+  - Plane Select Modes: G17, G18, G19
+  - Tool Length Offset Modes: G43.1, G49
+  - Cutter Compensation Modes: G40
+  - Coordinate System Modes: G54, G55, G56, G57, G58, G59
+  - Control Modes: G61
+  - Program Flow: M0, M1, M2, M30*
+  - Coolant Control: M7*, M8, M9
+  - Spindle Control: M3, M4, M5
+  - Valid Non-Command Words: F, I, J, K, L, N, P, R, S, T, X, Y, Z
+```
+
+-------------
+Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you!
+
+[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/.gitignore	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis/core_cm3.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1612 @@
+/**************************************************************************//**
+ * @file     core_cm3.h
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version  V3.01
+ * @date     22. March 2012
+ *
+ * @note
+ * Copyright (C) 2009-2012 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers.  This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M3
+  @{
+ */
+
+/*  CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM3_CMSIS_VERSION_SUB   (0x01)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM3_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x03)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI__VFP_SUPPORT____
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM3_REV
+    #define __CM3_REV               0x0200
+    #warning "__CM3_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL << NVIC_STIR_INTID_Pos)            /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+  __IO uint8_t  SHP[12];                 /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t PFR[2];                  /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t DFR;                     /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ADR;                     /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t MMFR[4];                 /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ISAR[5];                 /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[5];
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register                   */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201)                   /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos               29                                             /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL << SCB_AIRCR_VECTRESET_Pos)               /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL << SCB_CCR_NONBASETHRDENA_Pos)            /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL << SCB_SHCSR_MEMFAULTACT_Pos)             /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos)            /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL << SCB_DFSR_HALTED_Pos)                   /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register      */
+#else
+       uint32_t RESERVED1[1];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos)      /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1                                          /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos)        /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];                                  
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];                                  
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];                                   
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL << ITM_TPR_PRIVMASK_Pos)                /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL << ITM_TCR_ITMENA_Pos)                    /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL << ITM_IWR_ATVALIDM_Pos)                  /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL << ITM_IRR_ATREADYM_Pos)                  /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL << ITM_IMCR_INTEGRATION_Pos)              /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL << ITM_LSR_Present_Pos)                   /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL << DWT_CTRL_CYCCNTENA_Pos)           /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL << DWT_CPICNT_CPICNT_Pos)           /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL << DWT_EXCCNT_EXCCNT_Pos)           /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos)       /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL << DWT_LSUCNT_LSUCNT_Pos)           /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos)         /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL << DWT_MASK_MASK_Pos)               /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL << DWT_FUNCTION_FUNCTION_Pos)        /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL << TPI_ACPR_PRESCALER_Pos)        /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL << TPI_SPPR_TXMODE_Pos)              /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL << TPI_FFSR_FlInProg_Pos)            /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL << TPI_TRIGGER_TRIGGER_Pos)          /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL << TPI_FIFO0_ETM0_Pos)              /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL << TPI_ITATBCTR2_ATREADY_Pos)        /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL << TPI_FIFO1_ITM0_Pos)              /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL << TPI_ITATBCTR0_ATREADY_Pos)        /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL << TPI_ITCTRL_Mode_Pos)              /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL << TPI_DEVID_NrTraceInput_Pos)      /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL << TPI_DEVTYPE_SubType_Pos)          /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL << MPU_RASR_ENABLE_Pos)                   /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos)         /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos)         /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos)      /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                  */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address  */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07);               /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
+  reg_value  =  (reg_value                                 |
+                ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */
+}
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M  System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M  system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
+
+  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if ((ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
+      (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t) ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis/core_cmFunc.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,616 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V3.01
+ * @date     06. March 2012
+ *
+ * @note
+ * Copyright (C) 2009-2012 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers.  This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief  Enable IRQ Interrupts
+
+  This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i");
+}
+
+
+/** \brief  Disable IRQ Interrupts
+
+  This function disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i");
+}
+
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f");
+}
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f");
+}
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  uint32_t result;
+
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CMFUNC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis/core_cmInstr.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,618 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V3.01
+ * @date     06. March 2012
+ *
+ * @note
+ * Copyright (C) 2009-2012 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers.  This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+#define __ISB()                           __isb(0xF)
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()                           __dsb(0xF)
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+#define __DMB()                           __dmb(0xF)
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __RBIT                            __rbit
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr)                     ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr)                     ((uint16_t) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr)                     ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXB(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXH(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXW(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX                           __clrex
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb");
+}
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb");
+}
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb");
+}
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+
+  __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
+  return(op1);
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint8_t result;
+
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint16_t result;
+
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+   return(result);
+}
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex");
+}
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
+{
+  uint8_t result;
+
+  __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis_boot/startup/startup_stm32f10x_md.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,292 @@
+/**
+ ******************************************************************************
+ * @file      startup_stm32f10x_md.c
+ * @author    Coocox
+ * @version   V1.0
+ * @date      12/23/2009
+ * @brief     STM32F10x Medium Density Devices Startup code.
+ *            This module performs:
+ *                - Set the initial SP
+ *                - Set the vector table entries with the exceptions ISR address
+ *                - Initialize data and bss
+ *                - Setup the microcontroller system.
+ *                - Call the application's entry point.
+ *            After Reset the Cortex-M3 processor is in Thread mode,
+ *            priority is Privileged, and the Stack is set to Main.
+ *******************************************************************************
+ */
+ 
+
+/*----------Stack Configuration-----------------------------------------------*/  
+#define STACK_SIZE       0x00000100      /*!< The Stack size suggest using even number     */
+__attribute__ ((section(".co_stack")))
+unsigned long pulStack[STACK_SIZE];      
+
+
+/*----------Macro definition--------------------------------------------------*/  
+#define WEAK __attribute__ ((weak))           
+
+
+/*----------Declaration of the default fault handlers-------------------------*/  
+/* System exception vector handler */
+__attribute__ ((used))
+void WEAK  Reset_Handler(void);
+void WEAK  NMI_Handler(void);
+void WEAK  HardFault_Handler(void);
+void WEAK  MemManage_Handler(void);
+void WEAK  BusFault_Handler(void);
+void WEAK  UsageFault_Handler(void);
+void WEAK  SVC_Handler(void);
+void WEAK  DebugMon_Handler(void);
+void WEAK  PendSV_Handler(void);
+void WEAK  SysTick_Handler(void);
+void WEAK  WWDG_IRQHandler(void);
+void WEAK  PVD_IRQHandler(void);
+void WEAK  TAMPER_IRQHandler(void);
+void WEAK  RTC_IRQHandler(void);
+void WEAK  FLASH_IRQHandler(void);
+void WEAK  RCC_IRQHandler(void);
+void WEAK  EXTI0_IRQHandler(void);
+void WEAK  EXTI1_IRQHandler(void);
+void WEAK  EXTI2_IRQHandler(void);
+void WEAK  EXTI3_IRQHandler(void);
+void WEAK  EXTI4_IRQHandler(void);
+void WEAK  DMA1_Channel1_IRQHandler(void);
+void WEAK  DMA1_Channel2_IRQHandler(void);
+void WEAK  DMA1_Channel3_IRQHandler(void);
+void WEAK  DMA1_Channel4_IRQHandler(void);
+void WEAK  DMA1_Channel5_IRQHandler(void);
+void WEAK  DMA1_Channel6_IRQHandler(void);
+void WEAK  DMA1_Channel7_IRQHandler(void);
+void WEAK  ADC1_2_IRQHandler(void);
+void WEAK  USB_HP_CAN1_TX_IRQHandler(void);
+void WEAK  USB_LP_CAN1_RX0_IRQHandler(void);
+void WEAK  CAN1_RX1_IRQHandler(void);
+void WEAK  CAN1_SCE_IRQHandler(void);
+void WEAK  EXTI9_5_IRQHandler(void);
+void WEAK  TIM1_BRK_IRQHandler(void);
+void WEAK  TIM1_UP_IRQHandler(void);
+void WEAK  TIM1_TRG_COM_IRQHandler(void);
+void WEAK  TIM1_CC_IRQHandler(void);
+void WEAK  TIM2_IRQHandler(void);
+void WEAK  TIM3_IRQHandler(void);
+void WEAK  TIM4_IRQHandler(void);
+void WEAK  I2C1_EV_IRQHandler(void);
+void WEAK  I2C1_ER_IRQHandler(void);
+void WEAK  I2C2_EV_IRQHandler(void);
+void WEAK  I2C2_ER_IRQHandler(void);
+void WEAK  SPI1_IRQHandler(void);
+void WEAK  SPI2_IRQHandler(void);
+void WEAK  USART1_IRQHandler(void);
+void WEAK  USART2_IRQHandler(void);
+void WEAK  USART3_IRQHandler(void);
+void WEAK  EXTI15_10_IRQHandler(void);
+void WEAK  RTCAlarm_IRQHandler(void);
+void WEAK  USBWakeUp_IRQHandler(void); 
+
+
+/*----------Symbols defined in linker script----------------------------------*/  
+extern unsigned long _sidata;    /*!< Start address for the initialization 
+                                      values of the .data section.            */
+extern unsigned long _sdata;     /*!< Start address for the .data section     */    
+extern unsigned long _edata;     /*!< End address for the .data section       */    
+extern unsigned long _sbss;      /*!< Start address for the .bss section      */
+extern unsigned long _ebss;      /*!< End address for the .bss section        */      
+extern void _eram;               /*!< End address for ram                     */
+
+
+/*----------Function prototypes-----------------------------------------------*/  
+extern int main(void);           /*!< The entry point for the application.    */
+extern void SystemInit(void);    /*!< Setup the microcontroller system(CMSIS) */
+void Default_Reset_Handler(void);   /*!< Default reset handler                */
+static void Default_Handler(void);  /*!< Default exception handler            */
+
+
+/**
+  *@brief The minimal vector table for a Cortex M3.  Note that the proper constructs
+  *       must be placed on this to ensure that it ends up at physical address
+  *       0x00000000.  
+  */
+__attribute__ ((used,section(".isr_vector")))
+void (* const g_pfnVectors[])(void) =
+{       
+  /*----------Core Exceptions-------------------------------------------------*/
+  (void *)&pulStack[STACK_SIZE],     /*!< The initial stack pointer         */
+  Reset_Handler,                /*!< Reset Handler                            */
+  NMI_Handler,                  /*!< NMI Handler                              */
+  HardFault_Handler,            /*!< Hard Fault Handler                       */
+  MemManage_Handler,            /*!< MPU Fault Handler                        */
+  BusFault_Handler,             /*!< Bus Fault Handler                        */
+  UsageFault_Handler,           /*!< Usage Fault Handler                      */
+  0,0,0,0,                      /*!< Reserved                                 */
+  SVC_Handler,                  /*!< SVCall Handler                           */
+  DebugMon_Handler,             /*!< Debug Monitor Handler                    */
+  0,                            /*!< Reserved                                 */
+  PendSV_Handler,               /*!< PendSV Handler                           */
+  SysTick_Handler,              /*!< SysTick Handler                          */
+  
+  /*----------External Exceptions---------------------------------------------*/
+  WWDG_IRQHandler,              /*!<  0: Window Watchdog                      */
+  PVD_IRQHandler,               /*!<  1: PVD through EXTI Line detect         */
+  TAMPER_IRQHandler,            /*!<  2: Tamper                               */
+  RTC_IRQHandler,               /*!<  3: RTC                                  */
+  FLASH_IRQHandler,             /*!<  4: Flash                                */
+  RCC_IRQHandler,               /*!<  5: RCC                                  */
+  EXTI0_IRQHandler,             /*!<  6: EXTI Line 0                          */
+  EXTI1_IRQHandler,             /*!<  7: EXTI Line 1                          */
+  EXTI2_IRQHandler,             /*!<  8: EXTI Line 2                          */
+  EXTI3_IRQHandler,             /*!<  9: EXTI Line 3                          */
+  EXTI4_IRQHandler,             /*!< 10: EXTI Line 4                          */
+  DMA1_Channel1_IRQHandler,     /*!< 11: DMA1 Channel 1                       */
+  DMA1_Channel2_IRQHandler,     /*!< 12: DMA1 Channel 2                       */
+  DMA1_Channel3_IRQHandler,     /*!< 13: DMA1 Channel 3                       */
+  DMA1_Channel4_IRQHandler,     /*!< 14: DMA1 Channel 4                       */
+  DMA1_Channel5_IRQHandler,     /*!< 15: DMA1 Channel 5                       */
+  DMA1_Channel6_IRQHandler,     /*!< 16: DMA1 Channel 6                       */
+  DMA1_Channel7_IRQHandler,     /*!< 17: DMA1 Channel 7                       */
+  ADC1_2_IRQHandler,            /*!< 18: ADC1 & ADC2                          */
+  USB_HP_CAN1_TX_IRQHandler,    /*!< 19: USB High Priority or CAN1 TX         */
+  USB_LP_CAN1_RX0_IRQHandler,   /*!< 20: USB Low  Priority or CAN1 RX0        */
+  CAN1_RX1_IRQHandler,          /*!< 21: CAN1 RX1                             */
+  CAN1_SCE_IRQHandler,          /*!< 22: CAN1 SCE                             */
+  EXTI9_5_IRQHandler,           /*!< 23: EXTI Line 9..5                       */
+  TIM1_BRK_IRQHandler,          /*!< 24: TIM1 Break                           */
+  TIM1_UP_IRQHandler,           /*!< 25: TIM1 Update                          */
+  TIM1_TRG_COM_IRQHandler,      /*!< 26: TIM1 Trigger and Commutation         */
+  TIM1_CC_IRQHandler,           /*!< 27: TIM1 Capture Compare                 */
+  TIM2_IRQHandler,              /*!< 28: TIM2                                 */
+  TIM3_IRQHandler,              /*!< 29: TIM3                                 */
+  TIM4_IRQHandler,              /*!< 30: TIM4                                 */
+  I2C1_EV_IRQHandler,           /*!< 31: I2C1 Event                           */
+  I2C1_ER_IRQHandler,           /*!< 32: I2C1 Error                           */
+  I2C2_EV_IRQHandler,           /*!< 33: I2C2 Event                           */
+  I2C2_ER_IRQHandler,           /*!< 34: I2C2 Error                           */
+  SPI1_IRQHandler,              /*!< 35: SPI1                                 */
+  SPI2_IRQHandler,              /*!< 36: SPI2                                 */
+  USART1_IRQHandler,            /*!< 37: USART1                               */
+  USART2_IRQHandler,            /*!< 38: USART2                               */
+  USART3_IRQHandler,            /*!< 39: USART3                               */
+  EXTI15_10_IRQHandler,         /*!< 40: EXTI Line 15..10                     */
+  RTCAlarm_IRQHandler,          /*!< 41: RTC Alarm through EXTI Line          */
+  USBWakeUp_IRQHandler,         /*!< 42: USB Wakeup from suspend              */  
+  0,0,0,0,0,0,0,                /*!< Reserved                                 */ 
+  (void *)0xF108F85F            /*!< Boot in RAM mode                         */
+};        
+
+
+/**
+  * @brief  This is the code that gets called when the processor first
+  *         starts execution following a reset event. Only the absolutely
+  *         necessary set is performed, after which the application
+  *         supplied main() routine is called. 
+  * @param  None
+  * @retval None
+  */
+void Default_Reset_Handler(void)
+{
+  /* Initialize data and bss */
+  unsigned long *pulSrc, *pulDest;
+
+  /* Copy the data segment initializers from flash to SRAM */
+  pulSrc = &_sidata;
+
+  for(pulDest = &_sdata; pulDest < &_edata; )
+  {
+    *(pulDest++) = *(pulSrc++);
+  }
+  
+  /* Zero fill the bss segment.  This is done with inline assembly since this
+     will clear the value of pulDest if it is not kept in a register. */
+  __asm("  ldr     r0, =_sbss\n"
+        "  ldr     r1, =_ebss\n"
+        "  mov     r2, #0\n"
+        "  .thumb_func\n"
+        "zero_loop:\n"
+        "    cmp     r0, r1\n"
+        "    it      lt\n"
+        "    strlt   r2, [r0], #4\n"
+        "    blt     zero_loop");
+  
+  /* Setup the microcontroller system. */
+  SystemInit();
+    
+  /* Call the application's entry point.*/
+  main();
+}
+
+/**
+  *@brief Provide weak aliases for each Exception handler to the Default_Handler. 
+  *       As they are weak aliases, any function with the same name will override 
+  *       this definition.
+  */
+#pragma weak Reset_Handler = Default_Reset_Handler  
+#pragma weak NMI_Handler = Default_Handler
+#pragma weak HardFault_Handler = Default_Handler
+#pragma weak MemManage_Handler = Default_Handler
+#pragma weak BusFault_Handler = Default_Handler
+#pragma weak UsageFault_Handler = Default_Handler
+#pragma weak SVC_Handler = Default_Handler
+#pragma weak DebugMon_Handler = Default_Handler
+#pragma weak PendSV_Handler = Default_Handler
+#pragma weak SysTick_Handler = Default_Handler
+#pragma weak WWDG_IRQHandler = Default_Handler
+#pragma weak PVD_IRQHandler = Default_Handler
+#pragma weak TAMPER_IRQHandler = Default_Handler
+#pragma weak RTC_IRQHandler = Default_Handler
+#pragma weak FLASH_IRQHandler = Default_Handler
+#pragma weak RCC_IRQHandler = Default_Handler
+#pragma weak EXTI0_IRQHandler = Default_Handler
+#pragma weak EXTI1_IRQHandler = Default_Handler
+#pragma weak EXTI2_IRQHandler = Default_Handler
+#pragma weak EXTI3_IRQHandler = Default_Handler
+#pragma weak EXTI4_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel1_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel2_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel3_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel4_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel5_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel6_IRQHandler = Default_Handler
+#pragma weak DMA1_Channel7_IRQHandler = Default_Handler
+#pragma weak ADC1_2_IRQHandler = Default_Handler
+#pragma weak USB_HP_CAN1_TX_IRQHandler = Default_Handler
+#pragma weak USB_LP_CAN1_RX0_IRQHandler = Default_Handler
+#pragma weak CAN1_RX1_IRQHandler = Default_Handler
+#pragma weak CAN1_SCE_IRQHandler = Default_Handler
+#pragma weak EXTI9_5_IRQHandler = Default_Handler
+#pragma weak TIM1_BRK_IRQHandler = Default_Handler
+#pragma weak TIM1_UP_IRQHandler = Default_Handler
+#pragma weak TIM1_TRG_COM_IRQHandler = Default_Handler
+#pragma weak TIM1_CC_IRQHandler = Default_Handler
+#pragma weak TIM2_IRQHandler = Default_Handler
+#pragma weak TIM3_IRQHandler = Default_Handler
+#pragma weak TIM4_IRQHandler = Default_Handler
+#pragma weak I2C1_EV_IRQHandler = Default_Handler
+#pragma weak I2C1_ER_IRQHandler = Default_Handler
+#pragma weak I2C2_EV_IRQHandler = Default_Handler
+#pragma weak I2C2_ER_IRQHandler = Default_Handler
+#pragma weak SPI1_IRQHandler = Default_Handler
+#pragma weak SPI2_IRQHandler = Default_Handler
+#pragma weak USART1_IRQHandler = Default_Handler
+#pragma weak USART2_IRQHandler = Default_Handler
+#pragma weak USART3_IRQHandler = Default_Handler
+#pragma weak EXTI15_10_IRQHandler = Default_Handler
+#pragma weak RTCAlarm_IRQHandler = Default_Handler
+#pragma weak USBWakeUp_IRQHandler = Default_Handler
+
+
+/**
+  * @brief  This is the code that gets called when the processor receives an 
+  *         unexpected interrupt.  This simply enters an infinite loop, 
+  *         preserving the system state for examination by a debugger.
+  * @param  None
+  * @retval None  
+  */
+static void Default_Handler(void) 
+{
+  /* Go into an infinite loop. */
+  while (1) 
+  {
+  }
+}
+
+/*********************** (C) COPYRIGHT 2009 Coocox ************END OF FILE*****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis_boot/stm32f10x.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,8336 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer Header File. 
+  *          This file contains all the peripheral register's definitions, bits 
+  *          definitions and memory mapping for STM32F10x Connectivity line, 
+  *          High density, High density value line, Medium density, 
+  *          Medium density Value line, Low density, Low density Value line 
+  *          and XL-density devices.
+  *
+  *          The file is the unique include file that the application programmer
+  *          is using in the C source code, usually in main.c. This file contains:
+  *           - Configuration section that allows to select:
+  *              - The device used in the target application
+  *              - To use or not the peripheral’s drivers in application code(i.e. 
+  *                code will be based on direct access to peripheral’s registers 
+  *                rather than drivers API), this option is controlled by 
+  *                "#define USE_STDPERIPH_DRIVER"
+  *              - To change few application-specific parameters such as the HSE 
+  *                crystal frequency
+  *           - Data structures and the address mapping for all peripherals
+  *           - Peripheral's registers declarations and bits definition
+  *           - Macros to access peripheral’s registers hardware
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32f10x
+  * @{
+  */
+    
+#ifndef __STM32F10x_H
+#define __STM32F10x_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+  
+/** @addtogroup Library_configuration_section
+  * @{
+  */
+  
+/* Uncomment the line below according to the target STM32 device used in your
+   application 
+  */
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) 
+  /* #define STM32F10X_LD */     /*!< STM32F10X_LD: STM32 Low density devices */
+  /* #define STM32F10X_LD_VL */  /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */  
+  /* #define STM32F10X_MD */     /*!< STM32F10X_MD: STM32 Medium density devices */
+  /* #define STM32F10X_MD_VL */  /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */  
+  /* #define STM32F10X_HD */     /*!< STM32F10X_HD: STM32 High density devices */
+  /* #define STM32F10X_HD_VL */  /*!< STM32F10X_HD_VL: STM32 High density value line devices */  
+  /* #define STM32F10X_XL */     /*!< STM32F10X_XL: STM32 XL-density devices */
+  /* #define STM32F10X_CL */     /*!< STM32F10X_CL: STM32 Connectivity line devices */
+#endif
+/*  Tip: To avoid modifying this file each time you need to switch between these
+        devices, you can define the device in your toolchain compiler preprocessor.
+
+ - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+   where the Flash memory density ranges between 16 and 32 Kbytes.
+ - Low-density value line devices are STM32F100xx microcontrollers where the Flash
+   memory density ranges between 16 and 32 Kbytes.
+ - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+   where the Flash memory density ranges between 64 and 128 Kbytes.
+ - Medium-density value line devices are STM32F100xx microcontrollers where the 
+   Flash memory density ranges between 64 and 128 Kbytes.   
+ - High-density devices are STM32F101xx and STM32F103xx microcontrollers where
+   the Flash memory density ranges between 256 and 512 Kbytes.
+ - High-density value line devices are STM32F100xx microcontrollers where the 
+   Flash memory density ranges between 256 and 512 Kbytes.   
+ - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
+   the Flash memory density ranges between 512 and 1024 Kbytes.
+ - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
+  */
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
+ #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
+#endif
+
+#if !defined  USE_STDPERIPH_DRIVER
+/**
+ * @brief Comment the line below if you will not use the peripherals drivers.
+   In this case, these drivers will not be included and the application code will 
+   be based on direct access to peripherals registers 
+   */
+  /*#define USE_STDPERIPH_DRIVER*/
+#endif
+
+/**
+ * @brief In the following line adjust the value of External High Speed oscillator (HSE)
+   used in your application 
+   
+   Tip: To avoid modifying this file each time you need to use different HSE, you
+        can define the HSE value in your toolchain compiler preprocessor.
+  */           
+#if !defined  HSE_VALUE
+ #ifdef STM32F10X_CL   
+  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
+ #else 
+  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
+ #endif /* STM32F10X_CL */
+#endif /* HSE_VALUE */
+
+
+/**
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup 
+   Timeout value 
+   */
+#define HSE_STARTUP_TIMEOUT   ((uint16_t)0x0500) /*!< Time out for HSE start up */
+
+#define HSI_VALUE    ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
+
+/**
+ * @brief STM32F10x Standard Peripheral Library version number
+   */
+#define __STM32F10X_STDPERIPH_VERSION_MAIN   (0x03) /*!< [31:24] main version */                                  
+#define __STM32F10X_STDPERIPH_VERSION_SUB1   (0x05) /*!< [23:16] sub1 version */
+#define __STM32F10X_STDPERIPH_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version */
+#define __STM32F10X_STDPERIPH_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
+#define __STM32F10X_STDPERIPH_VERSION       ( (__STM32F10X_STDPERIPH_VERSION_MAIN << 24)\
+                                             |(__STM32F10X_STDPERIPH_VERSION_SUB1 << 16)\
+                                             |(__STM32F10X_STDPERIPH_VERSION_SUB2 << 8)\
+                                             |(__STM32F10X_STDPERIPH_VERSION_RC))
+
+/**
+  * @}
+  */
+
+/** @addtogroup Configuration_section_for_CMSIS
+  * @{
+  */
+
+/**
+ * @brief Configuration of the Cortex-M3 Processor and Core Peripherals 
+ */
+#ifdef STM32F10X_XL
+ #define __MPU_PRESENT             1 /*!< STM32 XL-density devices provide an MPU */
+#else
+ #define __MPU_PRESENT             0 /*!< Other STM32 devices does not provide an MPU */
+#endif /* STM32F10X_XL */
+#define __NVIC_PRIO_BITS          4 /*!< STM32 uses 4 Bits for the Priority Levels    */
+#define __Vendor_SysTickConfig    0 /*!< Set to 1 if different SysTick Config is used */
+
+/**
+ * @brief STM32F10x Interrupt Number Definition, according to the selected device 
+ *        in @ref Library_configuration_section 
+ */
+typedef enum IRQn
+{
+/******  Cortex-M3 Processor Exceptions Numbers ***************************************************/
+  NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                             */
+  MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt              */
+  BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                      */
+  UsageFault_IRQn             = -10,    /*!< 6 Cortex-M3 Usage Fault Interrupt                    */
+  SVCall_IRQn                 = -5,     /*!< 11 Cortex-M3 SV Call Interrupt                       */
+  DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M3 Debug Monitor Interrupt                 */
+  PendSV_IRQn                 = -2,     /*!< 14 Cortex-M3 Pend SV Interrupt                       */
+  SysTick_IRQn                = -1,     /*!< 15 Cortex-M3 System Tick Interrupt                   */
+
+/******  STM32 specific Interrupt Numbers *********************************************************/
+  WWDG_IRQn                   = 0,      /*!< Window WatchDog Interrupt                            */
+  PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt            */
+  TAMPER_IRQn                 = 2,      /*!< Tamper Interrupt                                     */
+  RTC_IRQn                    = 3,      /*!< RTC global Interrupt                                 */
+  FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                               */
+  RCC_IRQn                    = 5,      /*!< RCC global Interrupt                                 */
+  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                 */
+  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                 */
+  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                 */
+  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                 */
+  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                 */
+  DMA1_Channel1_IRQn          = 11,     /*!< DMA1 Channel 1 global Interrupt                      */
+  DMA1_Channel2_IRQn          = 12,     /*!< DMA1 Channel 2 global Interrupt                      */
+  DMA1_Channel3_IRQn          = 13,     /*!< DMA1 Channel 3 global Interrupt                      */
+  DMA1_Channel4_IRQn          = 14,     /*!< DMA1 Channel 4 global Interrupt                      */
+  DMA1_Channel5_IRQn          = 15,     /*!< DMA1 Channel 5 global Interrupt                      */
+  DMA1_Channel6_IRQn          = 16,     /*!< DMA1 Channel 6 global Interrupt                      */
+  DMA1_Channel7_IRQn          = 17,     /*!< DMA1 Channel 7 global Interrupt                      */
+
+#ifdef STM32F10X_LD
+  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
+  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
+  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
+  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
+  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
+  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
+  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */    
+#endif /* STM32F10X_LD */  
+
+#ifdef STM32F10X_LD_VL
+  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
+  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
+  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
+  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
+  TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */       
+#endif /* STM32F10X_LD_VL */
+
+#ifdef STM32F10X_MD
+  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
+  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
+  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
+  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
+  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
+  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
+  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */  
+#endif /* STM32F10X_MD */  
+
+#ifdef STM32F10X_MD_VL
+  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
+  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
+  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
+  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
+  TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */       
+#endif /* STM32F10X_MD_VL */
+
+#ifdef STM32F10X_HD
+  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
+  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
+  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
+  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
+  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
+  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
+  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+  TIM8_BRK_IRQn               = 43,     /*!< TIM8 Break Interrupt                                 */
+  TIM8_UP_IRQn                = 44,     /*!< TIM8 Update Interrupt                                */
+  TIM8_TRG_COM_IRQn           = 45,     /*!< TIM8 Trigger and Commutation Interrupt               */
+  TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
+  ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
+  FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
+  SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
+  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
+  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
+  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
+  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
+  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
+  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
+  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
+  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
+  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
+  DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
+#endif /* STM32F10X_HD */  
+
+#ifdef STM32F10X_HD_VL
+  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
+  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
+  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
+  TIM12_IRQn                  = 43,     /*!< TIM12 global Interrupt                               */
+  TIM13_IRQn                  = 44,     /*!< TIM13 global Interrupt                               */
+  TIM14_IRQn                  = 45,     /*!< TIM14 global Interrupt                               */
+  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
+  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
+  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
+  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */  
+  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
+  TIM7_IRQn                   = 55,     /*!< TIM7 Interrupt                                       */  
+  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
+  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
+  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
+  DMA2_Channel4_5_IRQn        = 59,     /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
+  DMA2_Channel5_IRQn          = 60      /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is 
+                                             mapped at position 60 only if the MISC_REMAP bit in 
+                                             the AFIO_MAPR2 register is set)                      */       
+#endif /* STM32F10X_HD_VL */
+
+#ifdef STM32F10X_XL
+  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
+  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
+  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
+  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
+  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_TIM9_IRQn          = 24,     /*!< TIM1 Break Interrupt and TIM9 global Interrupt       */
+  TIM1_UP_TIM10_IRQn          = 25,     /*!< TIM1 Update Interrupt and TIM10 global Interrupt     */
+  TIM1_TRG_COM_TIM11_IRQn     = 26,     /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+  TIM8_BRK_TIM12_IRQn         = 43,     /*!< TIM8 Break Interrupt and TIM12 global Interrupt      */
+  TIM8_UP_TIM13_IRQn          = 44,     /*!< TIM8 Update Interrupt and TIM13 global Interrupt     */
+  TIM8_TRG_COM_TIM14_IRQn     = 45,     /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
+  TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
+  ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
+  FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
+  SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
+  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
+  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
+  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
+  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
+  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
+  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
+  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
+  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
+  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
+  DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
+#endif /* STM32F10X_XL */  
+
+#ifdef STM32F10X_CL
+  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
+  CAN1_TX_IRQn                = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
+  CAN1_RX0_IRQn               = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
+  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
+  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
+  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
+  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
+  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
+  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
+  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
+  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
+  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
+  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
+  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
+  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
+  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
+  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
+  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
+  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
+  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
+  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
+  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
+  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
+  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
+  OTG_FS_WKUP_IRQn            = 42,     /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */
+  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
+  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
+  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
+  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
+  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
+  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
+  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
+  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
+  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
+  DMA2_Channel4_IRQn          = 59,     /*!< DMA2 Channel 4 global Interrupt                      */
+  DMA2_Channel5_IRQn          = 60,     /*!< DMA2 Channel 5 global Interrupt                      */
+  ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                            */
+  ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EXTI line Interrupt          */
+  CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                    */
+  CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                   */
+  CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                   */
+  CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                   */
+  OTG_FS_IRQn                 = 67      /*!< USB OTG FS global Interrupt                          */
+#endif /* STM32F10X_CL */     
+} IRQn_Type;
+
+/**
+  * @}
+  */
+
+#include "core_cm3.h"
+#include "system_stm32f10x.h"
+#include <stdint.h>
+
+/** @addtogroup Exported_types
+  * @{
+  */  
+
+/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
+typedef int32_t  s32;
+typedef int16_t s16;
+typedef int8_t  s8;
+
+typedef const int32_t sc32;  /*!< Read Only */
+typedef const int16_t sc16;  /*!< Read Only */
+typedef const int8_t sc8;   /*!< Read Only */
+
+typedef __IO int32_t  vs32;
+typedef __IO int16_t  vs16;
+typedef __IO int8_t   vs8;
+
+typedef __I int32_t vsc32;  /*!< Read Only */
+typedef __I int16_t vsc16;  /*!< Read Only */
+typedef __I int8_t vsc8;   /*!< Read Only */
+
+typedef uint32_t  u32;
+typedef uint16_t u16;
+typedef uint8_t  u8;
+
+typedef const uint32_t uc32;  /*!< Read Only */
+typedef const uint16_t uc16;  /*!< Read Only */
+typedef const uint8_t uc8;   /*!< Read Only */
+
+typedef __IO uint32_t  vu32;
+typedef __IO uint16_t vu16;
+typedef __IO uint8_t  vu8;
+
+typedef __I uint32_t vuc32;  /*!< Read Only */
+typedef __I uint16_t vuc16;  /*!< Read Only */
+typedef __I uint8_t vuc8;   /*!< Read Only */
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
+
+/*!< STM32F10x Standard Peripheral Library old definitions (maintained for legacy purpose) */
+#define HSEStartUp_TimeOut   HSE_STARTUP_TIMEOUT
+#define HSE_Value            HSE_VALUE
+#define HSI_Value            HSI_VALUE
+/**
+  * @}
+  */
+
+/** @addtogroup Peripheral_registers_structures
+  * @{
+  */   
+
+/** 
+  * @brief Analog to Digital Converter  
+  */
+
+typedef struct
+{
+  __IO uint32_t SR;
+  __IO uint32_t CR1;
+  __IO uint32_t CR2;
+  __IO uint32_t SMPR1;
+  __IO uint32_t SMPR2;
+  __IO uint32_t JOFR1;
+  __IO uint32_t JOFR2;
+  __IO uint32_t JOFR3;
+  __IO uint32_t JOFR4;
+  __IO uint32_t HTR;
+  __IO uint32_t LTR;
+  __IO uint32_t SQR1;
+  __IO uint32_t SQR2;
+  __IO uint32_t SQR3;
+  __IO uint32_t JSQR;
+  __IO uint32_t JDR1;
+  __IO uint32_t JDR2;
+  __IO uint32_t JDR3;
+  __IO uint32_t JDR4;
+  __IO uint32_t DR;
+} ADC_TypeDef;
+
+/** 
+  * @brief Backup Registers  
+  */
+
+typedef struct
+{
+  uint32_t  RESERVED0;
+  __IO uint16_t DR1;
+  uint16_t  RESERVED1;
+  __IO uint16_t DR2;
+  uint16_t  RESERVED2;
+  __IO uint16_t DR3;
+  uint16_t  RESERVED3;
+  __IO uint16_t DR4;
+  uint16_t  RESERVED4;
+  __IO uint16_t DR5;
+  uint16_t  RESERVED5;
+  __IO uint16_t DR6;
+  uint16_t  RESERVED6;
+  __IO uint16_t DR7;
+  uint16_t  RESERVED7;
+  __IO uint16_t DR8;
+  uint16_t  RESERVED8;
+  __IO uint16_t DR9;
+  uint16_t  RESERVED9;
+  __IO uint16_t DR10;
+  uint16_t  RESERVED10; 
+  __IO uint16_t RTCCR;
+  uint16_t  RESERVED11;
+  __IO uint16_t CR;
+  uint16_t  RESERVED12;
+  __IO uint16_t CSR;
+  uint16_t  RESERVED13[5];
+  __IO uint16_t DR11;
+  uint16_t  RESERVED14;
+  __IO uint16_t DR12;
+  uint16_t  RESERVED15;
+  __IO uint16_t DR13;
+  uint16_t  RESERVED16;
+  __IO uint16_t DR14;
+  uint16_t  RESERVED17;
+  __IO uint16_t DR15;
+  uint16_t  RESERVED18;
+  __IO uint16_t DR16;
+  uint16_t  RESERVED19;
+  __IO uint16_t DR17;
+  uint16_t  RESERVED20;
+  __IO uint16_t DR18;
+  uint16_t  RESERVED21;
+  __IO uint16_t DR19;
+  uint16_t  RESERVED22;
+  __IO uint16_t DR20;
+  uint16_t  RESERVED23;
+  __IO uint16_t DR21;
+  uint16_t  RESERVED24;
+  __IO uint16_t DR22;
+  uint16_t  RESERVED25;
+  __IO uint16_t DR23;
+  uint16_t  RESERVED26;
+  __IO uint16_t DR24;
+  uint16_t  RESERVED27;
+  __IO uint16_t DR25;
+  uint16_t  RESERVED28;
+  __IO uint16_t DR26;
+  uint16_t  RESERVED29;
+  __IO uint16_t DR27;
+  uint16_t  RESERVED30;
+  __IO uint16_t DR28;
+  uint16_t  RESERVED31;
+  __IO uint16_t DR29;
+  uint16_t  RESERVED32;
+  __IO uint16_t DR30;
+  uint16_t  RESERVED33; 
+  __IO uint16_t DR31;
+  uint16_t  RESERVED34;
+  __IO uint16_t DR32;
+  uint16_t  RESERVED35;
+  __IO uint16_t DR33;
+  uint16_t  RESERVED36;
+  __IO uint16_t DR34;
+  uint16_t  RESERVED37;
+  __IO uint16_t DR35;
+  uint16_t  RESERVED38;
+  __IO uint16_t DR36;
+  uint16_t  RESERVED39;
+  __IO uint16_t DR37;
+  uint16_t  RESERVED40;
+  __IO uint16_t DR38;
+  uint16_t  RESERVED41;
+  __IO uint16_t DR39;
+  uint16_t  RESERVED42;
+  __IO uint16_t DR40;
+  uint16_t  RESERVED43;
+  __IO uint16_t DR41;
+  uint16_t  RESERVED44;
+  __IO uint16_t DR42;
+  uint16_t  RESERVED45;    
+} BKP_TypeDef;
+  
+/** 
+  * @brief Controller Area Network TxMailBox 
+  */
+
+typedef struct
+{
+  __IO uint32_t TIR;
+  __IO uint32_t TDTR;
+  __IO uint32_t TDLR;
+  __IO uint32_t TDHR;
+} CAN_TxMailBox_TypeDef;
+
+/** 
+  * @brief Controller Area Network FIFOMailBox 
+  */
+  
+typedef struct
+{
+  __IO uint32_t RIR;
+  __IO uint32_t RDTR;
+  __IO uint32_t RDLR;
+  __IO uint32_t RDHR;
+} CAN_FIFOMailBox_TypeDef;
+
+/** 
+  * @brief Controller Area Network FilterRegister 
+  */
+  
+typedef struct
+{
+  __IO uint32_t FR1;
+  __IO uint32_t FR2;
+} CAN_FilterRegister_TypeDef;
+
+/** 
+  * @brief Controller Area Network 
+  */
+  
+typedef struct
+{
+  __IO uint32_t MCR;
+  __IO uint32_t MSR;
+  __IO uint32_t TSR;
+  __IO uint32_t RF0R;
+  __IO uint32_t RF1R;
+  __IO uint32_t IER;
+  __IO uint32_t ESR;
+  __IO uint32_t BTR;
+  uint32_t  RESERVED0[88];
+  CAN_TxMailBox_TypeDef sTxMailBox[3];
+  CAN_FIFOMailBox_TypeDef sFIFOMailBox[2];
+  uint32_t  RESERVED1[12];
+  __IO uint32_t FMR;
+  __IO uint32_t FM1R;
+  uint32_t  RESERVED2;
+  __IO uint32_t FS1R;
+  uint32_t  RESERVED3;
+  __IO uint32_t FFA1R;
+  uint32_t  RESERVED4;
+  __IO uint32_t FA1R;
+  uint32_t  RESERVED5[8];
+#ifndef STM32F10X_CL
+  CAN_FilterRegister_TypeDef sFilterRegister[14];
+#else
+  CAN_FilterRegister_TypeDef sFilterRegister[28];
+#endif /* STM32F10X_CL */  
+} CAN_TypeDef;
+
+/** 
+  * @brief Consumer Electronics Control (CEC)
+  */
+typedef struct
+{
+  __IO uint32_t CFGR;
+  __IO uint32_t OAR;
+  __IO uint32_t PRES;
+  __IO uint32_t ESR;
+  __IO uint32_t CSR;
+  __IO uint32_t TXD;
+  __IO uint32_t RXD;  
+} CEC_TypeDef;
+
+/** 
+  * @brief CRC calculation unit 
+  */
+
+typedef struct
+{
+  __IO uint32_t DR;
+  __IO uint8_t  IDR;
+  uint8_t   RESERVED0;
+  uint16_t  RESERVED1;
+  __IO uint32_t CR;
+} CRC_TypeDef;
+
+/** 
+  * @brief Digital to Analog Converter
+  */
+
+typedef struct
+{
+  __IO uint32_t CR;
+  __IO uint32_t SWTRIGR;
+  __IO uint32_t DHR12R1;
+  __IO uint32_t DHR12L1;
+  __IO uint32_t DHR8R1;
+  __IO uint32_t DHR12R2;
+  __IO uint32_t DHR12L2;
+  __IO uint32_t DHR8R2;
+  __IO uint32_t DHR12RD;
+  __IO uint32_t DHR12LD;
+  __IO uint32_t DHR8RD;
+  __IO uint32_t DOR1;
+  __IO uint32_t DOR2;
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+  __IO uint32_t SR;
+#endif
+} DAC_TypeDef;
+
+/** 
+  * @brief Debug MCU
+  */
+
+typedef struct
+{
+  __IO uint32_t IDCODE;
+  __IO uint32_t CR;	
+}DBGMCU_TypeDef;
+
+/** 
+  * @brief DMA Controller
+  */
+
+typedef struct
+{
+  __IO uint32_t CCR;
+  __IO uint32_t CNDTR;
+  __IO uint32_t CPAR;
+  __IO uint32_t CMAR;
+} DMA_Channel_TypeDef;
+
+typedef struct
+{
+  __IO uint32_t ISR;
+  __IO uint32_t IFCR;
+} DMA_TypeDef;
+
+/** 
+  * @brief Ethernet MAC
+  */
+
+typedef struct
+{
+  __IO uint32_t MACCR;
+  __IO uint32_t MACFFR;
+  __IO uint32_t MACHTHR;
+  __IO uint32_t MACHTLR;
+  __IO uint32_t MACMIIAR;
+  __IO uint32_t MACMIIDR;
+  __IO uint32_t MACFCR;
+  __IO uint32_t MACVLANTR;             /*    8 */
+       uint32_t RESERVED0[2];
+  __IO uint32_t MACRWUFFR;             /*   11 */
+  __IO uint32_t MACPMTCSR;
+       uint32_t RESERVED1[2];
+  __IO uint32_t MACSR;                 /*   15 */
+  __IO uint32_t MACIMR;
+  __IO uint32_t MACA0HR;
+  __IO uint32_t MACA0LR;
+  __IO uint32_t MACA1HR;
+  __IO uint32_t MACA1LR;
+  __IO uint32_t MACA2HR;
+  __IO uint32_t MACA2LR;
+  __IO uint32_t MACA3HR;
+  __IO uint32_t MACA3LR;               /*   24 */
+       uint32_t RESERVED2[40];
+  __IO uint32_t MMCCR;                 /*   65 */
+  __IO uint32_t MMCRIR;
+  __IO uint32_t MMCTIR;
+  __IO uint32_t MMCRIMR;
+  __IO uint32_t MMCTIMR;               /*   69 */
+       uint32_t RESERVED3[14];
+  __IO uint32_t MMCTGFSCCR;            /*   84 */
+  __IO uint32_t MMCTGFMSCCR;
+       uint32_t RESERVED4[5];
+  __IO uint32_t MMCTGFCR;
+       uint32_t RESERVED5[10];
+  __IO uint32_t MMCRFCECR;
+  __IO uint32_t MMCRFAECR;
+       uint32_t RESERVED6[10];
+  __IO uint32_t MMCRGUFCR;
+       uint32_t RESERVED7[334];
+  __IO uint32_t PTPTSCR;
+  __IO uint32_t PTPSSIR;
+  __IO uint32_t PTPTSHR;
+  __IO uint32_t PTPTSLR;
+  __IO uint32_t PTPTSHUR;
+  __IO uint32_t PTPTSLUR;
+  __IO uint32_t PTPTSAR;
+  __IO uint32_t PTPTTHR;
+  __IO uint32_t PTPTTLR;
+       uint32_t RESERVED8[567];
+  __IO uint32_t DMABMR;
+  __IO uint32_t DMATPDR;
+  __IO uint32_t DMARPDR;
+  __IO uint32_t DMARDLAR;
+  __IO uint32_t DMATDLAR;
+  __IO uint32_t DMASR;
+  __IO uint32_t DMAOMR;
+  __IO uint32_t DMAIER;
+  __IO uint32_t DMAMFBOCR;
+       uint32_t RESERVED9[9];
+  __IO uint32_t DMACHTDR;
+  __IO uint32_t DMACHRDR;
+  __IO uint32_t DMACHTBAR;
+  __IO uint32_t DMACHRBAR;
+} ETH_TypeDef;
+
+/** 
+  * @brief External Interrupt/Event Controller
+  */
+
+typedef struct
+{
+  __IO uint32_t IMR;
+  __IO uint32_t EMR;
+  __IO uint32_t RTSR;
+  __IO uint32_t FTSR;
+  __IO uint32_t SWIER;
+  __IO uint32_t PR;
+} EXTI_TypeDef;
+
+/** 
+  * @brief FLASH Registers
+  */
+
+typedef struct
+{
+  __IO uint32_t ACR;
+  __IO uint32_t KEYR;
+  __IO uint32_t OPTKEYR;
+  __IO uint32_t SR;
+  __IO uint32_t CR;
+  __IO uint32_t AR;
+  __IO uint32_t RESERVED;
+  __IO uint32_t OBR;
+  __IO uint32_t WRPR;
+#ifdef STM32F10X_XL
+  uint32_t RESERVED1[8]; 
+  __IO uint32_t KEYR2;
+  uint32_t RESERVED2;   
+  __IO uint32_t SR2;
+  __IO uint32_t CR2;
+  __IO uint32_t AR2; 
+#endif /* STM32F10X_XL */  
+} FLASH_TypeDef;
+
+/** 
+  * @brief Option Bytes Registers
+  */
+  
+typedef struct
+{
+  __IO uint16_t RDP;
+  __IO uint16_t USER;
+  __IO uint16_t Data0;
+  __IO uint16_t Data1;
+  __IO uint16_t WRP0;
+  __IO uint16_t WRP1;
+  __IO uint16_t WRP2;
+  __IO uint16_t WRP3;
+} OB_TypeDef;
+
+/** 
+  * @brief Flexible Static Memory Controller
+  */
+
+typedef struct
+{
+  __IO uint32_t BTCR[8];   
+} FSMC_Bank1_TypeDef; 
+
+/** 
+  * @brief Flexible Static Memory Controller Bank1E
+  */
+  
+typedef struct
+{
+  __IO uint32_t BWTR[7];
+} FSMC_Bank1E_TypeDef;
+
+/** 
+  * @brief Flexible Static Memory Controller Bank2
+  */
+  
+typedef struct
+{
+  __IO uint32_t PCR2;
+  __IO uint32_t SR2;
+  __IO uint32_t PMEM2;
+  __IO uint32_t PATT2;
+  uint32_t  RESERVED0;   
+  __IO uint32_t ECCR2; 
+} FSMC_Bank2_TypeDef;  
+
+/** 
+  * @brief Flexible Static Memory Controller Bank3
+  */
+  
+typedef struct
+{
+  __IO uint32_t PCR3;
+  __IO uint32_t SR3;
+  __IO uint32_t PMEM3;
+  __IO uint32_t PATT3;
+  uint32_t  RESERVED0;   
+  __IO uint32_t ECCR3; 
+} FSMC_Bank3_TypeDef; 
+
+/** 
+  * @brief Flexible Static Memory Controller Bank4
+  */
+  
+typedef struct
+{
+  __IO uint32_t PCR4;
+  __IO uint32_t SR4;
+  __IO uint32_t PMEM4;
+  __IO uint32_t PATT4;
+  __IO uint32_t PIO4; 
+} FSMC_Bank4_TypeDef; 
+
+/** 
+  * @brief General Purpose I/O
+  */
+
+typedef struct
+{
+  __IO uint32_t CRL;
+  __IO uint32_t CRH;
+  __IO uint32_t IDR;
+  __IO uint32_t ODR;
+  __IO uint32_t BSRR;
+  __IO uint32_t BRR;
+  __IO uint32_t LCKR;
+} GPIO_TypeDef;
+
+/** 
+  * @brief Alternate Function I/O
+  */
+
+typedef struct
+{
+  __IO uint32_t EVCR;
+  __IO uint32_t MAPR;
+  __IO uint32_t EXTICR[4];
+  uint32_t RESERVED0;
+  __IO uint32_t MAPR2;  
+} AFIO_TypeDef;
+/** 
+  * @brief Inter Integrated Circuit Interface
+  */
+
+typedef struct
+{
+  __IO uint16_t CR1;
+  uint16_t  RESERVED0;
+  __IO uint16_t CR2;
+  uint16_t  RESERVED1;
+  __IO uint16_t OAR1;
+  uint16_t  RESERVED2;
+  __IO uint16_t OAR2;
+  uint16_t  RESERVED3;
+  __IO uint16_t DR;
+  uint16_t  RESERVED4;
+  __IO uint16_t SR1;
+  uint16_t  RESERVED5;
+  __IO uint16_t SR2;
+  uint16_t  RESERVED6;
+  __IO uint16_t CCR;
+  uint16_t  RESERVED7;
+  __IO uint16_t TRISE;
+  uint16_t  RESERVED8;
+} I2C_TypeDef;
+
+/** 
+  * @brief Independent WATCHDOG
+  */
+
+typedef struct
+{
+  __IO uint32_t KR;
+  __IO uint32_t PR;
+  __IO uint32_t RLR;
+  __IO uint32_t SR;
+} IWDG_TypeDef;
+
+/** 
+  * @brief Power Control
+  */
+
+typedef struct
+{
+  __IO uint32_t CR;
+  __IO uint32_t CSR;
+} PWR_TypeDef;
+
+/** 
+  * @brief Reset and Clock Control
+  */
+
+typedef struct
+{
+  __IO uint32_t CR;
+  __IO uint32_t CFGR;
+  __IO uint32_t CIR;
+  __IO uint32_t APB2RSTR;
+  __IO uint32_t APB1RSTR;
+  __IO uint32_t AHBENR;
+  __IO uint32_t APB2ENR;
+  __IO uint32_t APB1ENR;
+  __IO uint32_t BDCR;
+  __IO uint32_t CSR;
+
+#ifdef STM32F10X_CL  
+  __IO uint32_t AHBRSTR;
+  __IO uint32_t CFGR2;
+#endif /* STM32F10X_CL */ 
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)   
+  uint32_t RESERVED0;
+  __IO uint32_t CFGR2;
+#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */ 
+} RCC_TypeDef;
+
+/** 
+  * @brief Real-Time Clock
+  */
+
+typedef struct
+{
+  __IO uint16_t CRH;
+  uint16_t  RESERVED0;
+  __IO uint16_t CRL;
+  uint16_t  RESERVED1;
+  __IO uint16_t PRLH;
+  uint16_t  RESERVED2;
+  __IO uint16_t PRLL;
+  uint16_t  RESERVED3;
+  __IO uint16_t DIVH;
+  uint16_t  RESERVED4;
+  __IO uint16_t DIVL;
+  uint16_t  RESERVED5;
+  __IO uint16_t CNTH;
+  uint16_t  RESERVED6;
+  __IO uint16_t CNTL;
+  uint16_t  RESERVED7;
+  __IO uint16_t ALRH;
+  uint16_t  RESERVED8;
+  __IO uint16_t ALRL;
+  uint16_t  RESERVED9;
+} RTC_TypeDef;
+
+/** 
+  * @brief SD host Interface
+  */
+
+typedef struct
+{
+  __IO uint32_t POWER;
+  __IO uint32_t CLKCR;
+  __IO uint32_t ARG;
+  __IO uint32_t CMD;
+  __I uint32_t RESPCMD;
+  __I uint32_t RESP1;
+  __I uint32_t RESP2;
+  __I uint32_t RESP3;
+  __I uint32_t RESP4;
+  __IO uint32_t DTIMER;
+  __IO uint32_t DLEN;
+  __IO uint32_t DCTRL;
+  __I uint32_t DCOUNT;
+  __I uint32_t STA;
+  __IO uint32_t ICR;
+  __IO uint32_t MASK;
+  uint32_t  RESERVED0[2];
+  __I uint32_t FIFOCNT;
+  uint32_t  RESERVED1[13];
+  __IO uint32_t FIFO;
+} SDIO_TypeDef;
+
+/** 
+  * @brief Serial Peripheral Interface
+  */
+
+typedef struct
+{
+  __IO uint16_t CR1;
+  uint16_t  RESERVED0;
+  __IO uint16_t CR2;
+  uint16_t  RESERVED1;
+  __IO uint16_t SR;
+  uint16_t  RESERVED2;
+  __IO uint16_t DR;
+  uint16_t  RESERVED3;
+  __IO uint16_t CRCPR;
+  uint16_t  RESERVED4;
+  __IO uint16_t RXCRCR;
+  uint16_t  RESERVED5;
+  __IO uint16_t TXCRCR;
+  uint16_t  RESERVED6;
+  __IO uint16_t I2SCFGR;
+  uint16_t  RESERVED7;
+  __IO uint16_t I2SPR;
+  uint16_t  RESERVED8;  
+} SPI_TypeDef;
+
+/** 
+  * @brief TIM
+  */
+
+typedef struct
+{
+  __IO uint16_t CR1;
+  uint16_t  RESERVED0;
+  __IO uint16_t CR2;
+  uint16_t  RESERVED1;
+  __IO uint16_t SMCR;
+  uint16_t  RESERVED2;
+  __IO uint16_t DIER;
+  uint16_t  RESERVED3;
+  __IO uint16_t SR;
+  uint16_t  RESERVED4;
+  __IO uint16_t EGR;
+  uint16_t  RESERVED5;
+  __IO uint16_t CCMR1;
+  uint16_t  RESERVED6;
+  __IO uint16_t CCMR2;
+  uint16_t  RESERVED7;
+  __IO uint16_t CCER;
+  uint16_t  RESERVED8;
+  __IO uint16_t CNT;
+  uint16_t  RESERVED9;
+  __IO uint16_t PSC;
+  uint16_t  RESERVED10;
+  __IO uint16_t ARR;
+  uint16_t  RESERVED11;
+  __IO uint16_t RCR;
+  uint16_t  RESERVED12;
+  __IO uint16_t CCR1;
+  uint16_t  RESERVED13;
+  __IO uint16_t CCR2;
+  uint16_t  RESERVED14;
+  __IO uint16_t CCR3;
+  uint16_t  RESERVED15;
+  __IO uint16_t CCR4;
+  uint16_t  RESERVED16;
+  __IO uint16_t BDTR;
+  uint16_t  RESERVED17;
+  __IO uint16_t DCR;
+  uint16_t  RESERVED18;
+  __IO uint16_t DMAR;
+  uint16_t  RESERVED19;
+} TIM_TypeDef;
+
+/** 
+  * @brief Universal Synchronous Asynchronous Receiver Transmitter
+  */
+ 
+typedef struct
+{
+  __IO uint16_t SR;
+  uint16_t  RESERVED0;
+  __IO uint16_t DR;
+  uint16_t  RESERVED1;
+  __IO uint16_t BRR;
+  uint16_t  RESERVED2;
+  __IO uint16_t CR1;
+  uint16_t  RESERVED3;
+  __IO uint16_t CR2;
+  uint16_t  RESERVED4;
+  __IO uint16_t CR3;
+  uint16_t  RESERVED5;
+  __IO uint16_t GTPR;
+  uint16_t  RESERVED6;
+} USART_TypeDef;
+
+/** 
+  * @brief Window WATCHDOG
+  */
+
+typedef struct
+{
+  __IO uint32_t CR;
+  __IO uint32_t CFR;
+  __IO uint32_t SR;
+} WWDG_TypeDef;
+
+/**
+  * @}
+  */
+  
+/** @addtogroup Peripheral_memory_map
+  * @{
+  */
+
+
+#define FLASH_BASE            ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
+#define SRAM_BASE             ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
+#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
+
+#define SRAM_BB_BASE          ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
+#define PERIPH_BB_BASE        ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */
+
+#define FSMC_R_BASE           ((uint32_t)0xA0000000) /*!< FSMC registers base address */
+
+/*!< Peripheral memory map */
+#define APB1PERIPH_BASE       PERIPH_BASE
+#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
+#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
+
+#define TIM2_BASE             (APB1PERIPH_BASE + 0x0000)
+#define TIM3_BASE             (APB1PERIPH_BASE + 0x0400)
+#define TIM4_BASE             (APB1PERIPH_BASE + 0x0800)
+#define TIM5_BASE             (APB1PERIPH_BASE + 0x0C00)
+#define TIM6_BASE             (APB1PERIPH_BASE + 0x1000)
+#define TIM7_BASE             (APB1PERIPH_BASE + 0x1400)
+#define TIM12_BASE            (APB1PERIPH_BASE + 0x1800)
+#define TIM13_BASE            (APB1PERIPH_BASE + 0x1C00)
+#define TIM14_BASE            (APB1PERIPH_BASE + 0x2000)
+#define RTC_BASE              (APB1PERIPH_BASE + 0x2800)
+#define WWDG_BASE             (APB1PERIPH_BASE + 0x2C00)
+#define IWDG_BASE             (APB1PERIPH_BASE + 0x3000)
+#define SPI2_BASE             (APB1PERIPH_BASE + 0x3800)
+#define SPI3_BASE             (APB1PERIPH_BASE + 0x3C00)
+#define USART2_BASE           (APB1PERIPH_BASE + 0x4400)
+#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)
+#define UART4_BASE            (APB1PERIPH_BASE + 0x4C00)
+#define UART5_BASE            (APB1PERIPH_BASE + 0x5000)
+#define I2C1_BASE             (APB1PERIPH_BASE + 0x5400)
+#define I2C2_BASE             (APB1PERIPH_BASE + 0x5800)
+#define CAN1_BASE             (APB1PERIPH_BASE + 0x6400)
+#define CAN2_BASE             (APB1PERIPH_BASE + 0x6800)
+#define BKP_BASE              (APB1PERIPH_BASE + 0x6C00)
+#define PWR_BASE              (APB1PERIPH_BASE + 0x7000)
+#define DAC_BASE              (APB1PERIPH_BASE + 0x7400)
+#define CEC_BASE              (APB1PERIPH_BASE + 0x7800)
+
+#define AFIO_BASE             (APB2PERIPH_BASE + 0x0000)
+#define EXTI_BASE             (APB2PERIPH_BASE + 0x0400)
+#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
+#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
+#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
+#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
+#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
+#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
+#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)
+#define ADC1_BASE             (APB2PERIPH_BASE + 0x2400)
+#define ADC2_BASE             (APB2PERIPH_BASE + 0x2800)
+#define TIM1_BASE             (APB2PERIPH_BASE + 0x2C00)
+#define SPI1_BASE             (APB2PERIPH_BASE + 0x3000)
+#define TIM8_BASE             (APB2PERIPH_BASE + 0x3400)
+#define USART1_BASE           (APB2PERIPH_BASE + 0x3800)
+#define ADC3_BASE             (APB2PERIPH_BASE + 0x3C00)
+#define TIM15_BASE            (APB2PERIPH_BASE + 0x4000)
+#define TIM16_BASE            (APB2PERIPH_BASE + 0x4400)
+#define TIM17_BASE            (APB2PERIPH_BASE + 0x4800)
+#define TIM9_BASE             (APB2PERIPH_BASE + 0x4C00)
+#define TIM10_BASE            (APB2PERIPH_BASE + 0x5000)
+#define TIM11_BASE            (APB2PERIPH_BASE + 0x5400)
+
+#define SDIO_BASE             (PERIPH_BASE + 0x18000)
+
+#define DMA1_BASE             (AHBPERIPH_BASE + 0x0000)
+#define DMA1_Channel1_BASE    (AHBPERIPH_BASE + 0x0008)
+#define DMA1_Channel2_BASE    (AHBPERIPH_BASE + 0x001C)
+#define DMA1_Channel3_BASE    (AHBPERIPH_BASE + 0x0030)
+#define DMA1_Channel4_BASE    (AHBPERIPH_BASE + 0x0044)
+#define DMA1_Channel5_BASE    (AHBPERIPH_BASE + 0x0058)
+#define DMA1_Channel6_BASE    (AHBPERIPH_BASE + 0x006C)
+#define DMA1_Channel7_BASE    (AHBPERIPH_BASE + 0x0080)
+#define DMA2_BASE             (AHBPERIPH_BASE + 0x0400)
+#define DMA2_Channel1_BASE    (AHBPERIPH_BASE + 0x0408)
+#define DMA2_Channel2_BASE    (AHBPERIPH_BASE + 0x041C)
+#define DMA2_Channel3_BASE    (AHBPERIPH_BASE + 0x0430)
+#define DMA2_Channel4_BASE    (AHBPERIPH_BASE + 0x0444)
+#define DMA2_Channel5_BASE    (AHBPERIPH_BASE + 0x0458)
+#define RCC_BASE              (AHBPERIPH_BASE + 0x1000)
+#define CRC_BASE              (AHBPERIPH_BASE + 0x3000)
+
+#define FLASH_R_BASE          (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */
+#define OB_BASE               ((uint32_t)0x1FFFF800)    /*!< Flash Option Bytes base address */
+
+#define ETH_BASE              (AHBPERIPH_BASE + 0x8000)
+#define ETH_MAC_BASE          (ETH_BASE)
+#define ETH_MMC_BASE          (ETH_BASE + 0x0100)
+#define ETH_PTP_BASE          (ETH_BASE + 0x0700)
+#define ETH_DMA_BASE          (ETH_BASE + 0x1000)
+
+#define FSMC_Bank1_R_BASE     (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */
+#define FSMC_Bank1E_R_BASE    (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */
+#define FSMC_Bank2_R_BASE     (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */
+#define FSMC_Bank3_R_BASE     (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */
+#define FSMC_Bank4_R_BASE     (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */
+
+#define DBGMCU_BASE          ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */
+
+/**
+  * @}
+  */
+  
+/** @addtogroup Peripheral_declaration
+  * @{
+  */  
+
+#define TIM2                ((TIM_TypeDef *) TIM2_BASE)
+#define TIM3                ((TIM_TypeDef *) TIM3_BASE)
+#define TIM4                ((TIM_TypeDef *) TIM4_BASE)
+#define TIM5                ((TIM_TypeDef *) TIM5_BASE)
+#define TIM6                ((TIM_TypeDef *) TIM6_BASE)
+#define TIM7                ((TIM_TypeDef *) TIM7_BASE)
+#define TIM12               ((TIM_TypeDef *) TIM12_BASE)
+#define TIM13               ((TIM_TypeDef *) TIM13_BASE)
+#define TIM14               ((TIM_TypeDef *) TIM14_BASE)
+#define RTC                 ((RTC_TypeDef *) RTC_BASE)
+#define WWDG                ((WWDG_TypeDef *) WWDG_BASE)
+#define IWDG                ((IWDG_TypeDef *) IWDG_BASE)
+#define SPI2                ((SPI_TypeDef *) SPI2_BASE)
+#define SPI3                ((SPI_TypeDef *) SPI3_BASE)
+#define USART2              ((USART_TypeDef *) USART2_BASE)
+#define USART3              ((USART_TypeDef *) USART3_BASE)
+#define UART4               ((USART_TypeDef *) UART4_BASE)
+#define UART5               ((USART_TypeDef *) UART5_BASE)
+#define I2C1                ((I2C_TypeDef *) I2C1_BASE)
+#define I2C2                ((I2C_TypeDef *) I2C2_BASE)
+#define CAN1                ((CAN_TypeDef *) CAN1_BASE)
+#define CAN2                ((CAN_TypeDef *) CAN2_BASE)
+#define BKP                 ((BKP_TypeDef *) BKP_BASE)
+#define PWR                 ((PWR_TypeDef *) PWR_BASE)
+#define DAC                 ((DAC_TypeDef *) DAC_BASE)
+#define CEC                 ((CEC_TypeDef *) CEC_BASE)
+#define AFIO                ((AFIO_TypeDef *) AFIO_BASE)
+#define EXTI                ((EXTI_TypeDef *) EXTI_BASE)
+#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
+#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
+#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
+#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
+#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
+#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
+#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
+#define ADC1                ((ADC_TypeDef *) ADC1_BASE)
+#define ADC2                ((ADC_TypeDef *) ADC2_BASE)
+#define TIM1                ((TIM_TypeDef *) TIM1_BASE)
+#define SPI1                ((SPI_TypeDef *) SPI1_BASE)
+#define TIM8                ((TIM_TypeDef *) TIM8_BASE)
+#define USART1              ((USART_TypeDef *) USART1_BASE)
+#define ADC3                ((ADC_TypeDef *) ADC3_BASE)
+#define TIM15               ((TIM_TypeDef *) TIM15_BASE)
+#define TIM16               ((TIM_TypeDef *) TIM16_BASE)
+#define TIM17               ((TIM_TypeDef *) TIM17_BASE)
+#define TIM9                ((TIM_TypeDef *) TIM9_BASE)
+#define TIM10               ((TIM_TypeDef *) TIM10_BASE)
+#define TIM11               ((TIM_TypeDef *) TIM11_BASE)
+#define SDIO                ((SDIO_TypeDef *) SDIO_BASE)
+#define DMA1                ((DMA_TypeDef *) DMA1_BASE)
+#define DMA2                ((DMA_TypeDef *) DMA2_BASE)
+#define DMA1_Channel1       ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE)
+#define DMA1_Channel2       ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE)
+#define DMA1_Channel3       ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE)
+#define DMA1_Channel4       ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE)
+#define DMA1_Channel5       ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE)
+#define DMA1_Channel6       ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE)
+#define DMA1_Channel7       ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE)
+#define DMA2_Channel1       ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE)
+#define DMA2_Channel2       ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE)
+#define DMA2_Channel3       ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE)
+#define DMA2_Channel4       ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE)
+#define DMA2_Channel5       ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE)
+#define RCC                 ((RCC_TypeDef *) RCC_BASE)
+#define CRC                 ((CRC_TypeDef *) CRC_BASE)
+#define FLASH               ((FLASH_TypeDef *) FLASH_R_BASE)
+#define OB                  ((OB_TypeDef *) OB_BASE) 
+#define ETH                 ((ETH_TypeDef *) ETH_BASE)
+#define FSMC_Bank1          ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
+#define FSMC_Bank1E         ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
+#define FSMC_Bank2          ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)
+#define FSMC_Bank3          ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)
+#define FSMC_Bank4          ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)
+#define DBGMCU              ((DBGMCU_TypeDef *) DBGMCU_BASE)
+
+/**
+  * @}
+  */
+
+/** @addtogroup Exported_constants
+  * @{
+  */
+  
+  /** @addtogroup Peripheral_Registers_Bits_Definition
+  * @{
+  */
+    
+/******************************************************************************/
+/*                         Peripheral Registers_Bits_Definition               */
+/******************************************************************************/
+
+/******************************************************************************/
+/*                                                                            */
+/*                          CRC calculation unit                              */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for CRC_DR register  *********************/
+#define  CRC_DR_DR                           ((uint32_t)0xFFFFFFFF) /*!< Data register bits */
+
+
+/*******************  Bit definition for CRC_IDR register  ********************/
+#define  CRC_IDR_IDR                         ((uint8_t)0xFF)        /*!< General-purpose 8-bit data register bits */
+
+
+/********************  Bit definition for CRC_CR register  ********************/
+#define  CRC_CR_RESET                        ((uint8_t)0x01)        /*!< RESET bit */
+
+/******************************************************************************/
+/*                                                                            */
+/*                             Power Control                                  */
+/*                                                                            */
+/******************************************************************************/
+
+/********************  Bit definition for PWR_CR register  ********************/
+#define  PWR_CR_LPDS                         ((uint16_t)0x0001)     /*!< Low-Power Deepsleep */
+#define  PWR_CR_PDDS                         ((uint16_t)0x0002)     /*!< Power Down Deepsleep */
+#define  PWR_CR_CWUF                         ((uint16_t)0x0004)     /*!< Clear Wakeup Flag */
+#define  PWR_CR_CSBF                         ((uint16_t)0x0008)     /*!< Clear Standby Flag */
+#define  PWR_CR_PVDE                         ((uint16_t)0x0010)     /*!< Power Voltage Detector Enable */
+
+#define  PWR_CR_PLS                          ((uint16_t)0x00E0)     /*!< PLS[2:0] bits (PVD Level Selection) */
+#define  PWR_CR_PLS_0                        ((uint16_t)0x0020)     /*!< Bit 0 */
+#define  PWR_CR_PLS_1                        ((uint16_t)0x0040)     /*!< Bit 1 */
+#define  PWR_CR_PLS_2                        ((uint16_t)0x0080)     /*!< Bit 2 */
+
+/*!< PVD level configuration */
+#define  PWR_CR_PLS_2V2                      ((uint16_t)0x0000)     /*!< PVD level 2.2V */
+#define  PWR_CR_PLS_2V3                      ((uint16_t)0x0020)     /*!< PVD level 2.3V */
+#define  PWR_CR_PLS_2V4                      ((uint16_t)0x0040)     /*!< PVD level 2.4V */
+#define  PWR_CR_PLS_2V5                      ((uint16_t)0x0060)     /*!< PVD level 2.5V */
+#define  PWR_CR_PLS_2V6                      ((uint16_t)0x0080)     /*!< PVD level 2.6V */
+#define  PWR_CR_PLS_2V7                      ((uint16_t)0x00A0)     /*!< PVD level 2.7V */
+#define  PWR_CR_PLS_2V8                      ((uint16_t)0x00C0)     /*!< PVD level 2.8V */
+#define  PWR_CR_PLS_2V9                      ((uint16_t)0x00E0)     /*!< PVD level 2.9V */
+
+#define  PWR_CR_DBP                          ((uint16_t)0x0100)     /*!< Disable Backup Domain write protection */
+
+
+/*******************  Bit definition for PWR_CSR register  ********************/
+#define  PWR_CSR_WUF                         ((uint16_t)0x0001)     /*!< Wakeup Flag */
+#define  PWR_CSR_SBF                         ((uint16_t)0x0002)     /*!< Standby Flag */
+#define  PWR_CSR_PVDO                        ((uint16_t)0x0004)     /*!< PVD Output */
+#define  PWR_CSR_EWUP                        ((uint16_t)0x0100)     /*!< Enable WKUP pin */
+
+/******************************************************************************/
+/*                                                                            */
+/*                            Backup registers                                */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for BKP_DR1 register  ********************/
+#define  BKP_DR1_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR2 register  ********************/
+#define  BKP_DR2_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR3 register  ********************/
+#define  BKP_DR3_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR4 register  ********************/
+#define  BKP_DR4_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR5 register  ********************/
+#define  BKP_DR5_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR6 register  ********************/
+#define  BKP_DR6_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR7 register  ********************/
+#define  BKP_DR7_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR8 register  ********************/
+#define  BKP_DR8_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR9 register  ********************/
+#define  BKP_DR9_D                           ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR10 register  *******************/
+#define  BKP_DR10_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR11 register  *******************/
+#define  BKP_DR11_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR12 register  *******************/
+#define  BKP_DR12_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR13 register  *******************/
+#define  BKP_DR13_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR14 register  *******************/
+#define  BKP_DR14_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR15 register  *******************/
+#define  BKP_DR15_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR16 register  *******************/
+#define  BKP_DR16_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR17 register  *******************/
+#define  BKP_DR17_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/******************  Bit definition for BKP_DR18 register  ********************/
+#define  BKP_DR18_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR19 register  *******************/
+#define  BKP_DR19_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR20 register  *******************/
+#define  BKP_DR20_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR21 register  *******************/
+#define  BKP_DR21_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR22 register  *******************/
+#define  BKP_DR22_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR23 register  *******************/
+#define  BKP_DR23_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR24 register  *******************/
+#define  BKP_DR24_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR25 register  *******************/
+#define  BKP_DR25_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR26 register  *******************/
+#define  BKP_DR26_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR27 register  *******************/
+#define  BKP_DR27_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR28 register  *******************/
+#define  BKP_DR28_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR29 register  *******************/
+#define  BKP_DR29_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR30 register  *******************/
+#define  BKP_DR30_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR31 register  *******************/
+#define  BKP_DR31_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR32 register  *******************/
+#define  BKP_DR32_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR33 register  *******************/
+#define  BKP_DR33_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR34 register  *******************/
+#define  BKP_DR34_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR35 register  *******************/
+#define  BKP_DR35_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR36 register  *******************/
+#define  BKP_DR36_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR37 register  *******************/
+#define  BKP_DR37_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR38 register  *******************/
+#define  BKP_DR38_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR39 register  *******************/
+#define  BKP_DR39_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR40 register  *******************/
+#define  BKP_DR40_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR41 register  *******************/
+#define  BKP_DR41_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/*******************  Bit definition for BKP_DR42 register  *******************/
+#define  BKP_DR42_D                          ((uint16_t)0xFFFF)     /*!< Backup data */
+
+/******************  Bit definition for BKP_RTCCR register  *******************/
+#define  BKP_RTCCR_CAL                       ((uint16_t)0x007F)     /*!< Calibration value */
+#define  BKP_RTCCR_CCO                       ((uint16_t)0x0080)     /*!< Calibration Clock Output */
+#define  BKP_RTCCR_ASOE                      ((uint16_t)0x0100)     /*!< Alarm or Second Output Enable */
+#define  BKP_RTCCR_ASOS                      ((uint16_t)0x0200)     /*!< Alarm or Second Output Selection */
+
+/********************  Bit definition for BKP_CR register  ********************/
+#define  BKP_CR_TPE                          ((uint8_t)0x01)        /*!< TAMPER pin enable */
+#define  BKP_CR_TPAL                         ((uint8_t)0x02)        /*!< TAMPER pin active level */
+
+/*******************  Bit definition for BKP_CSR register  ********************/
+#define  BKP_CSR_CTE                         ((uint16_t)0x0001)     /*!< Clear Tamper event */
+#define  BKP_CSR_CTI                         ((uint16_t)0x0002)     /*!< Clear Tamper Interrupt */
+#define  BKP_CSR_TPIE                        ((uint16_t)0x0004)     /*!< TAMPER Pin interrupt enable */
+#define  BKP_CSR_TEF                         ((uint16_t)0x0100)     /*!< Tamper Event Flag */
+#define  BKP_CSR_TIF                         ((uint16_t)0x0200)     /*!< Tamper Interrupt Flag */
+
+/******************************************************************************/
+/*                                                                            */
+/*                         Reset and Clock Control                            */
+/*                                                                            */
+/******************************************************************************/
+
+/********************  Bit definition for RCC_CR register  ********************/
+#define  RCC_CR_HSION                        ((uint32_t)0x00000001)        /*!< Internal High Speed clock enable */
+#define  RCC_CR_HSIRDY                       ((uint32_t)0x00000002)        /*!< Internal High Speed clock ready flag */
+#define  RCC_CR_HSITRIM                      ((uint32_t)0x000000F8)        /*!< Internal High Speed clock trimming */
+#define  RCC_CR_HSICAL                       ((uint32_t)0x0000FF00)        /*!< Internal High Speed clock Calibration */
+#define  RCC_CR_HSEON                        ((uint32_t)0x00010000)        /*!< External High Speed clock enable */
+#define  RCC_CR_HSERDY                       ((uint32_t)0x00020000)        /*!< External High Speed clock ready flag */
+#define  RCC_CR_HSEBYP                       ((uint32_t)0x00040000)        /*!< External High Speed clock Bypass */
+#define  RCC_CR_CSSON                        ((uint32_t)0x00080000)        /*!< Clock Security System enable */
+#define  RCC_CR_PLLON                        ((uint32_t)0x01000000)        /*!< PLL enable */
+#define  RCC_CR_PLLRDY                       ((uint32_t)0x02000000)        /*!< PLL clock ready flag */
+
+#ifdef STM32F10X_CL
+ #define  RCC_CR_PLL2ON                       ((uint32_t)0x04000000)        /*!< PLL2 enable */
+ #define  RCC_CR_PLL2RDY                      ((uint32_t)0x08000000)        /*!< PLL2 clock ready flag */
+ #define  RCC_CR_PLL3ON                       ((uint32_t)0x10000000)        /*!< PLL3 enable */
+ #define  RCC_CR_PLL3RDY                      ((uint32_t)0x20000000)        /*!< PLL3 clock ready flag */
+#endif /* STM32F10X_CL */
+
+/*******************  Bit definition for RCC_CFGR register  *******************/
+/*!< SW configuration */
+#define  RCC_CFGR_SW                         ((uint32_t)0x00000003)        /*!< SW[1:0] bits (System clock Switch) */
+#define  RCC_CFGR_SW_0                       ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  RCC_CFGR_SW_1                       ((uint32_t)0x00000002)        /*!< Bit 1 */
+
+#define  RCC_CFGR_SW_HSI                     ((uint32_t)0x00000000)        /*!< HSI selected as system clock */
+#define  RCC_CFGR_SW_HSE                     ((uint32_t)0x00000001)        /*!< HSE selected as system clock */
+#define  RCC_CFGR_SW_PLL                     ((uint32_t)0x00000002)        /*!< PLL selected as system clock */
+
+/*!< SWS configuration */
+#define  RCC_CFGR_SWS                        ((uint32_t)0x0000000C)        /*!< SWS[1:0] bits (System Clock Switch Status) */
+#define  RCC_CFGR_SWS_0                      ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  RCC_CFGR_SWS_1                      ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  RCC_CFGR_SWS_HSI                    ((uint32_t)0x00000000)        /*!< HSI oscillator used as system clock */
+#define  RCC_CFGR_SWS_HSE                    ((uint32_t)0x00000004)        /*!< HSE oscillator used as system clock */
+#define  RCC_CFGR_SWS_PLL                    ((uint32_t)0x00000008)        /*!< PLL used as system clock */
+
+/*!< HPRE configuration */
+#define  RCC_CFGR_HPRE                       ((uint32_t)0x000000F0)        /*!< HPRE[3:0] bits (AHB prescaler) */
+#define  RCC_CFGR_HPRE_0                     ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  RCC_CFGR_HPRE_1                     ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  RCC_CFGR_HPRE_2                     ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  RCC_CFGR_HPRE_3                     ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  RCC_CFGR_HPRE_DIV1                  ((uint32_t)0x00000000)        /*!< SYSCLK not divided */
+#define  RCC_CFGR_HPRE_DIV2                  ((uint32_t)0x00000080)        /*!< SYSCLK divided by 2 */
+#define  RCC_CFGR_HPRE_DIV4                  ((uint32_t)0x00000090)        /*!< SYSCLK divided by 4 */
+#define  RCC_CFGR_HPRE_DIV8                  ((uint32_t)0x000000A0)        /*!< SYSCLK divided by 8 */
+#define  RCC_CFGR_HPRE_DIV16                 ((uint32_t)0x000000B0)        /*!< SYSCLK divided by 16 */
+#define  RCC_CFGR_HPRE_DIV64                 ((uint32_t)0x000000C0)        /*!< SYSCLK divided by 64 */
+#define  RCC_CFGR_HPRE_DIV128                ((uint32_t)0x000000D0)        /*!< SYSCLK divided by 128 */
+#define  RCC_CFGR_HPRE_DIV256                ((uint32_t)0x000000E0)        /*!< SYSCLK divided by 256 */
+#define  RCC_CFGR_HPRE_DIV512                ((uint32_t)0x000000F0)        /*!< SYSCLK divided by 512 */
+
+/*!< PPRE1 configuration */
+#define  RCC_CFGR_PPRE1                      ((uint32_t)0x00000700)        /*!< PRE1[2:0] bits (APB1 prescaler) */
+#define  RCC_CFGR_PPRE1_0                    ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  RCC_CFGR_PPRE1_1                    ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  RCC_CFGR_PPRE1_2                    ((uint32_t)0x00000400)        /*!< Bit 2 */
+
+#define  RCC_CFGR_PPRE1_DIV1                 ((uint32_t)0x00000000)        /*!< HCLK not divided */
+#define  RCC_CFGR_PPRE1_DIV2                 ((uint32_t)0x00000400)        /*!< HCLK divided by 2 */
+#define  RCC_CFGR_PPRE1_DIV4                 ((uint32_t)0x00000500)        /*!< HCLK divided by 4 */
+#define  RCC_CFGR_PPRE1_DIV8                 ((uint32_t)0x00000600)        /*!< HCLK divided by 8 */
+#define  RCC_CFGR_PPRE1_DIV16                ((uint32_t)0x00000700)        /*!< HCLK divided by 16 */
+
+/*!< PPRE2 configuration */
+#define  RCC_CFGR_PPRE2                      ((uint32_t)0x00003800)        /*!< PRE2[2:0] bits (APB2 prescaler) */
+#define  RCC_CFGR_PPRE2_0                    ((uint32_t)0x00000800)        /*!< Bit 0 */
+#define  RCC_CFGR_PPRE2_1                    ((uint32_t)0x00001000)        /*!< Bit 1 */
+#define  RCC_CFGR_PPRE2_2                    ((uint32_t)0x00002000)        /*!< Bit 2 */
+
+#define  RCC_CFGR_PPRE2_DIV1                 ((uint32_t)0x00000000)        /*!< HCLK not divided */
+#define  RCC_CFGR_PPRE2_DIV2                 ((uint32_t)0x00002000)        /*!< HCLK divided by 2 */
+#define  RCC_CFGR_PPRE2_DIV4                 ((uint32_t)0x00002800)        /*!< HCLK divided by 4 */
+#define  RCC_CFGR_PPRE2_DIV8                 ((uint32_t)0x00003000)        /*!< HCLK divided by 8 */
+#define  RCC_CFGR_PPRE2_DIV16                ((uint32_t)0x00003800)        /*!< HCLK divided by 16 */
+
+/*!< ADCPPRE configuration */
+#define  RCC_CFGR_ADCPRE                     ((uint32_t)0x0000C000)        /*!< ADCPRE[1:0] bits (ADC prescaler) */
+#define  RCC_CFGR_ADCPRE_0                   ((uint32_t)0x00004000)        /*!< Bit 0 */
+#define  RCC_CFGR_ADCPRE_1                   ((uint32_t)0x00008000)        /*!< Bit 1 */
+
+#define  RCC_CFGR_ADCPRE_DIV2                ((uint32_t)0x00000000)        /*!< PCLK2 divided by 2 */
+#define  RCC_CFGR_ADCPRE_DIV4                ((uint32_t)0x00004000)        /*!< PCLK2 divided by 4 */
+#define  RCC_CFGR_ADCPRE_DIV6                ((uint32_t)0x00008000)        /*!< PCLK2 divided by 6 */
+#define  RCC_CFGR_ADCPRE_DIV8                ((uint32_t)0x0000C000)        /*!< PCLK2 divided by 8 */
+
+#define  RCC_CFGR_PLLSRC                     ((uint32_t)0x00010000)        /*!< PLL entry clock source */
+
+#define  RCC_CFGR_PLLXTPRE                   ((uint32_t)0x00020000)        /*!< HSE divider for PLL entry */
+
+/*!< PLLMUL configuration */
+#define  RCC_CFGR_PLLMULL                    ((uint32_t)0x003C0000)        /*!< PLLMUL[3:0] bits (PLL multiplication factor) */
+#define  RCC_CFGR_PLLMULL_0                  ((uint32_t)0x00040000)        /*!< Bit 0 */
+#define  RCC_CFGR_PLLMULL_1                  ((uint32_t)0x00080000)        /*!< Bit 1 */
+#define  RCC_CFGR_PLLMULL_2                  ((uint32_t)0x00100000)        /*!< Bit 2 */
+#define  RCC_CFGR_PLLMULL_3                  ((uint32_t)0x00200000)        /*!< Bit 3 */
+
+#ifdef STM32F10X_CL
+ #define  RCC_CFGR_PLLSRC_HSI_Div2           ((uint32_t)0x00000000)        /*!< HSI clock divided by 2 selected as PLL entry clock source */
+ #define  RCC_CFGR_PLLSRC_PREDIV1            ((uint32_t)0x00010000)        /*!< PREDIV1 clock selected as PLL entry clock source */
+
+ #define  RCC_CFGR_PLLXTPRE_PREDIV1          ((uint32_t)0x00000000)        /*!< PREDIV1 clock not divided for PLL entry */
+ #define  RCC_CFGR_PLLXTPRE_PREDIV1_Div2     ((uint32_t)0x00020000)        /*!< PREDIV1 clock divided by 2 for PLL entry */
+
+ #define  RCC_CFGR_PLLMULL4                  ((uint32_t)0x00080000)        /*!< PLL input clock * 4 */
+ #define  RCC_CFGR_PLLMULL5                  ((uint32_t)0x000C0000)        /*!< PLL input clock * 5 */
+ #define  RCC_CFGR_PLLMULL6                  ((uint32_t)0x00100000)        /*!< PLL input clock * 6 */
+ #define  RCC_CFGR_PLLMULL7                  ((uint32_t)0x00140000)        /*!< PLL input clock * 7 */
+ #define  RCC_CFGR_PLLMULL8                  ((uint32_t)0x00180000)        /*!< PLL input clock * 8 */
+ #define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)        /*!< PLL input clock * 9 */
+ #define  RCC_CFGR_PLLMULL6_5                ((uint32_t)0x00340000)        /*!< PLL input clock * 6.5 */
+ 
+ #define  RCC_CFGR_OTGFSPRE                  ((uint32_t)0x00400000)        /*!< USB OTG FS prescaler */
+ 
+/*!< MCO configuration */
+ #define  RCC_CFGR_MCO                       ((uint32_t)0x0F000000)        /*!< MCO[3:0] bits (Microcontroller Clock Output) */
+ #define  RCC_CFGR_MCO_0                     ((uint32_t)0x01000000)        /*!< Bit 0 */
+ #define  RCC_CFGR_MCO_1                     ((uint32_t)0x02000000)        /*!< Bit 1 */
+ #define  RCC_CFGR_MCO_2                     ((uint32_t)0x04000000)        /*!< Bit 2 */
+ #define  RCC_CFGR_MCO_3                     ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+ #define  RCC_CFGR_MCO_NOCLOCK               ((uint32_t)0x00000000)        /*!< No clock */
+ #define  RCC_CFGR_MCO_SYSCLK                ((uint32_t)0x04000000)        /*!< System clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSI                   ((uint32_t)0x05000000)        /*!< HSI clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSE                   ((uint32_t)0x06000000)        /*!< HSE clock selected as MCO source */
+ #define  RCC_CFGR_MCO_PLLCLK_Div2           ((uint32_t)0x07000000)        /*!< PLL clock divided by 2 selected as MCO source */
+ #define  RCC_CFGR_MCO_PLL2CLK               ((uint32_t)0x08000000)        /*!< PLL2 clock selected as MCO source*/
+ #define  RCC_CFGR_MCO_PLL3CLK_Div2          ((uint32_t)0x09000000)        /*!< PLL3 clock divided by 2 selected as MCO source*/
+ #define  RCC_CFGR_MCO_Ext_HSE               ((uint32_t)0x0A000000)        /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */
+ #define  RCC_CFGR_MCO_PLL3CLK               ((uint32_t)0x0B000000)        /*!< PLL3 clock selected as MCO source */
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+ #define  RCC_CFGR_PLLSRC_HSI_Div2           ((uint32_t)0x00000000)        /*!< HSI clock divided by 2 selected as PLL entry clock source */
+ #define  RCC_CFGR_PLLSRC_PREDIV1            ((uint32_t)0x00010000)        /*!< PREDIV1 clock selected as PLL entry clock source */
+
+ #define  RCC_CFGR_PLLXTPRE_PREDIV1          ((uint32_t)0x00000000)        /*!< PREDIV1 clock not divided for PLL entry */
+ #define  RCC_CFGR_PLLXTPRE_PREDIV1_Div2     ((uint32_t)0x00020000)        /*!< PREDIV1 clock divided by 2 for PLL entry */
+
+ #define  RCC_CFGR_PLLMULL2                  ((uint32_t)0x00000000)        /*!< PLL input clock*2 */
+ #define  RCC_CFGR_PLLMULL3                  ((uint32_t)0x00040000)        /*!< PLL input clock*3 */
+ #define  RCC_CFGR_PLLMULL4                  ((uint32_t)0x00080000)        /*!< PLL input clock*4 */
+ #define  RCC_CFGR_PLLMULL5                  ((uint32_t)0x000C0000)        /*!< PLL input clock*5 */
+ #define  RCC_CFGR_PLLMULL6                  ((uint32_t)0x00100000)        /*!< PLL input clock*6 */
+ #define  RCC_CFGR_PLLMULL7                  ((uint32_t)0x00140000)        /*!< PLL input clock*7 */
+ #define  RCC_CFGR_PLLMULL8                  ((uint32_t)0x00180000)        /*!< PLL input clock*8 */
+ #define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)        /*!< PLL input clock*9 */
+ #define  RCC_CFGR_PLLMULL10                 ((uint32_t)0x00200000)        /*!< PLL input clock10 */
+ #define  RCC_CFGR_PLLMULL11                 ((uint32_t)0x00240000)        /*!< PLL input clock*11 */
+ #define  RCC_CFGR_PLLMULL12                 ((uint32_t)0x00280000)        /*!< PLL input clock*12 */
+ #define  RCC_CFGR_PLLMULL13                 ((uint32_t)0x002C0000)        /*!< PLL input clock*13 */
+ #define  RCC_CFGR_PLLMULL14                 ((uint32_t)0x00300000)        /*!< PLL input clock*14 */
+ #define  RCC_CFGR_PLLMULL15                 ((uint32_t)0x00340000)        /*!< PLL input clock*15 */
+ #define  RCC_CFGR_PLLMULL16                 ((uint32_t)0x00380000)        /*!< PLL input clock*16 */
+
+/*!< MCO configuration */
+ #define  RCC_CFGR_MCO                       ((uint32_t)0x07000000)        /*!< MCO[2:0] bits (Microcontroller Clock Output) */
+ #define  RCC_CFGR_MCO_0                     ((uint32_t)0x01000000)        /*!< Bit 0 */
+ #define  RCC_CFGR_MCO_1                     ((uint32_t)0x02000000)        /*!< Bit 1 */
+ #define  RCC_CFGR_MCO_2                     ((uint32_t)0x04000000)        /*!< Bit 2 */
+
+ #define  RCC_CFGR_MCO_NOCLOCK               ((uint32_t)0x00000000)        /*!< No clock */
+ #define  RCC_CFGR_MCO_SYSCLK                ((uint32_t)0x04000000)        /*!< System clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSI                   ((uint32_t)0x05000000)        /*!< HSI clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSE                   ((uint32_t)0x06000000)        /*!< HSE clock selected as MCO source  */
+ #define  RCC_CFGR_MCO_PLL                   ((uint32_t)0x07000000)        /*!< PLL clock divided by 2 selected as MCO source */
+#else
+ #define  RCC_CFGR_PLLSRC_HSI_Div2           ((uint32_t)0x00000000)        /*!< HSI clock divided by 2 selected as PLL entry clock source */
+ #define  RCC_CFGR_PLLSRC_HSE                ((uint32_t)0x00010000)        /*!< HSE clock selected as PLL entry clock source */
+
+ #define  RCC_CFGR_PLLXTPRE_HSE              ((uint32_t)0x00000000)        /*!< HSE clock not divided for PLL entry */
+ #define  RCC_CFGR_PLLXTPRE_HSE_Div2         ((uint32_t)0x00020000)        /*!< HSE clock divided by 2 for PLL entry */
+
+ #define  RCC_CFGR_PLLMULL2                  ((uint32_t)0x00000000)        /*!< PLL input clock*2 */
+ #define  RCC_CFGR_PLLMULL3                  ((uint32_t)0x00040000)        /*!< PLL input clock*3 */
+ #define  RCC_CFGR_PLLMULL4                  ((uint32_t)0x00080000)        /*!< PLL input clock*4 */
+ #define  RCC_CFGR_PLLMULL5                  ((uint32_t)0x000C0000)        /*!< PLL input clock*5 */
+ #define  RCC_CFGR_PLLMULL6                  ((uint32_t)0x00100000)        /*!< PLL input clock*6 */
+ #define  RCC_CFGR_PLLMULL7                  ((uint32_t)0x00140000)        /*!< PLL input clock*7 */
+ #define  RCC_CFGR_PLLMULL8                  ((uint32_t)0x00180000)        /*!< PLL input clock*8 */
+ #define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)        /*!< PLL input clock*9 */
+ #define  RCC_CFGR_PLLMULL10                 ((uint32_t)0x00200000)        /*!< PLL input clock10 */
+ #define  RCC_CFGR_PLLMULL11                 ((uint32_t)0x00240000)        /*!< PLL input clock*11 */
+ #define  RCC_CFGR_PLLMULL12                 ((uint32_t)0x00280000)        /*!< PLL input clock*12 */
+ #define  RCC_CFGR_PLLMULL13                 ((uint32_t)0x002C0000)        /*!< PLL input clock*13 */
+ #define  RCC_CFGR_PLLMULL14                 ((uint32_t)0x00300000)        /*!< PLL input clock*14 */
+ #define  RCC_CFGR_PLLMULL15                 ((uint32_t)0x00340000)        /*!< PLL input clock*15 */
+ #define  RCC_CFGR_PLLMULL16                 ((uint32_t)0x00380000)        /*!< PLL input clock*16 */
+ #define  RCC_CFGR_USBPRE                    ((uint32_t)0x00400000)        /*!< USB Device prescaler */
+
+/*!< MCO configuration */
+ #define  RCC_CFGR_MCO                       ((uint32_t)0x07000000)        /*!< MCO[2:0] bits (Microcontroller Clock Output) */
+ #define  RCC_CFGR_MCO_0                     ((uint32_t)0x01000000)        /*!< Bit 0 */
+ #define  RCC_CFGR_MCO_1                     ((uint32_t)0x02000000)        /*!< Bit 1 */
+ #define  RCC_CFGR_MCO_2                     ((uint32_t)0x04000000)        /*!< Bit 2 */
+
+ #define  RCC_CFGR_MCO_NOCLOCK               ((uint32_t)0x00000000)        /*!< No clock */
+ #define  RCC_CFGR_MCO_SYSCLK                ((uint32_t)0x04000000)        /*!< System clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSI                   ((uint32_t)0x05000000)        /*!< HSI clock selected as MCO source */
+ #define  RCC_CFGR_MCO_HSE                   ((uint32_t)0x06000000)        /*!< HSE clock selected as MCO source  */
+ #define  RCC_CFGR_MCO_PLL                   ((uint32_t)0x07000000)        /*!< PLL clock divided by 2 selected as MCO source */
+#endif /* STM32F10X_CL */
+
+/*!<******************  Bit definition for RCC_CIR register  ********************/
+#define  RCC_CIR_LSIRDYF                     ((uint32_t)0x00000001)        /*!< LSI Ready Interrupt flag */
+#define  RCC_CIR_LSERDYF                     ((uint32_t)0x00000002)        /*!< LSE Ready Interrupt flag */
+#define  RCC_CIR_HSIRDYF                     ((uint32_t)0x00000004)        /*!< HSI Ready Interrupt flag */
+#define  RCC_CIR_HSERDYF                     ((uint32_t)0x00000008)        /*!< HSE Ready Interrupt flag */
+#define  RCC_CIR_PLLRDYF                     ((uint32_t)0x00000010)        /*!< PLL Ready Interrupt flag */
+#define  RCC_CIR_CSSF                        ((uint32_t)0x00000080)        /*!< Clock Security System Interrupt flag */
+#define  RCC_CIR_LSIRDYIE                    ((uint32_t)0x00000100)        /*!< LSI Ready Interrupt Enable */
+#define  RCC_CIR_LSERDYIE                    ((uint32_t)0x00000200)        /*!< LSE Ready Interrupt Enable */
+#define  RCC_CIR_HSIRDYIE                    ((uint32_t)0x00000400)        /*!< HSI Ready Interrupt Enable */
+#define  RCC_CIR_HSERDYIE                    ((uint32_t)0x00000800)        /*!< HSE Ready Interrupt Enable */
+#define  RCC_CIR_PLLRDYIE                    ((uint32_t)0x00001000)        /*!< PLL Ready Interrupt Enable */
+#define  RCC_CIR_LSIRDYC                     ((uint32_t)0x00010000)        /*!< LSI Ready Interrupt Clear */
+#define  RCC_CIR_LSERDYC                     ((uint32_t)0x00020000)        /*!< LSE Ready Interrupt Clear */
+#define  RCC_CIR_HSIRDYC                     ((uint32_t)0x00040000)        /*!< HSI Ready Interrupt Clear */
+#define  RCC_CIR_HSERDYC                     ((uint32_t)0x00080000)        /*!< HSE Ready Interrupt Clear */
+#define  RCC_CIR_PLLRDYC                     ((uint32_t)0x00100000)        /*!< PLL Ready Interrupt Clear */
+#define  RCC_CIR_CSSC                        ((uint32_t)0x00800000)        /*!< Clock Security System Interrupt Clear */
+
+#ifdef STM32F10X_CL
+ #define  RCC_CIR_PLL2RDYF                    ((uint32_t)0x00000020)        /*!< PLL2 Ready Interrupt flag */
+ #define  RCC_CIR_PLL3RDYF                    ((uint32_t)0x00000040)        /*!< PLL3 Ready Interrupt flag */
+ #define  RCC_CIR_PLL2RDYIE                   ((uint32_t)0x00002000)        /*!< PLL2 Ready Interrupt Enable */
+ #define  RCC_CIR_PLL3RDYIE                   ((uint32_t)0x00004000)        /*!< PLL3 Ready Interrupt Enable */
+ #define  RCC_CIR_PLL2RDYC                    ((uint32_t)0x00200000)        /*!< PLL2 Ready Interrupt Clear */
+ #define  RCC_CIR_PLL3RDYC                    ((uint32_t)0x00400000)        /*!< PLL3 Ready Interrupt Clear */
+#endif /* STM32F10X_CL */
+
+/*****************  Bit definition for RCC_APB2RSTR register  *****************/
+#define  RCC_APB2RSTR_AFIORST                ((uint32_t)0x00000001)        /*!< Alternate Function I/O reset */
+#define  RCC_APB2RSTR_IOPARST                ((uint32_t)0x00000004)        /*!< I/O port A reset */
+#define  RCC_APB2RSTR_IOPBRST                ((uint32_t)0x00000008)        /*!< I/O port B reset */
+#define  RCC_APB2RSTR_IOPCRST                ((uint32_t)0x00000010)        /*!< I/O port C reset */
+#define  RCC_APB2RSTR_IOPDRST                ((uint32_t)0x00000020)        /*!< I/O port D reset */
+#define  RCC_APB2RSTR_ADC1RST                ((uint32_t)0x00000200)        /*!< ADC 1 interface reset */
+
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
+#define  RCC_APB2RSTR_ADC2RST                ((uint32_t)0x00000400)        /*!< ADC 2 interface reset */
+#endif
+
+#define  RCC_APB2RSTR_TIM1RST                ((uint32_t)0x00000800)        /*!< TIM1 Timer reset */
+#define  RCC_APB2RSTR_SPI1RST                ((uint32_t)0x00001000)        /*!< SPI 1 reset */
+#define  RCC_APB2RSTR_USART1RST              ((uint32_t)0x00004000)        /*!< USART1 reset */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+#define  RCC_APB2RSTR_TIM15RST               ((uint32_t)0x00010000)        /*!< TIM15 Timer reset */
+#define  RCC_APB2RSTR_TIM16RST               ((uint32_t)0x00020000)        /*!< TIM16 Timer reset */
+#define  RCC_APB2RSTR_TIM17RST               ((uint32_t)0x00040000)        /*!< TIM17 Timer reset */
+#endif
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL)
+ #define  RCC_APB2RSTR_IOPERST               ((uint32_t)0x00000040)        /*!< I/O port E reset */
+#endif /* STM32F10X_LD && STM32F10X_LD_VL */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_XL)
+ #define  RCC_APB2RSTR_IOPFRST               ((uint32_t)0x00000080)        /*!< I/O port F reset */
+ #define  RCC_APB2RSTR_IOPGRST               ((uint32_t)0x00000100)        /*!< I/O port G reset */
+ #define  RCC_APB2RSTR_TIM8RST               ((uint32_t)0x00002000)        /*!< TIM8 Timer reset */
+ #define  RCC_APB2RSTR_ADC3RST               ((uint32_t)0x00008000)        /*!< ADC3 interface reset */
+#endif
+
+#if defined (STM32F10X_HD_VL)
+ #define  RCC_APB2RSTR_IOPFRST               ((uint32_t)0x00000080)        /*!< I/O port F reset */
+ #define  RCC_APB2RSTR_IOPGRST               ((uint32_t)0x00000100)        /*!< I/O port G reset */
+#endif
+
+#ifdef STM32F10X_XL
+ #define  RCC_APB2RSTR_TIM9RST               ((uint32_t)0x00080000)         /*!< TIM9 Timer reset */
+ #define  RCC_APB2RSTR_TIM10RST              ((uint32_t)0x00100000)         /*!< TIM10 Timer reset */
+ #define  RCC_APB2RSTR_TIM11RST              ((uint32_t)0x00200000)         /*!< TIM11 Timer reset */
+#endif /* STM32F10X_XL */
+
+/*****************  Bit definition for RCC_APB1RSTR register  *****************/
+#define  RCC_APB1RSTR_TIM2RST                ((uint32_t)0x00000001)        /*!< Timer 2 reset */
+#define  RCC_APB1RSTR_TIM3RST                ((uint32_t)0x00000002)        /*!< Timer 3 reset */
+#define  RCC_APB1RSTR_WWDGRST                ((uint32_t)0x00000800)        /*!< Window Watchdog reset */
+#define  RCC_APB1RSTR_USART2RST              ((uint32_t)0x00020000)        /*!< USART 2 reset */
+#define  RCC_APB1RSTR_I2C1RST                ((uint32_t)0x00200000)        /*!< I2C 1 reset */
+
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
+#define  RCC_APB1RSTR_CAN1RST                ((uint32_t)0x02000000)        /*!< CAN1 reset */
+#endif
+
+#define  RCC_APB1RSTR_BKPRST                 ((uint32_t)0x08000000)        /*!< Backup interface reset */
+#define  RCC_APB1RSTR_PWRRST                 ((uint32_t)0x10000000)        /*!< Power interface reset */
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL)
+ #define  RCC_APB1RSTR_TIM4RST               ((uint32_t)0x00000004)        /*!< Timer 4 reset */
+ #define  RCC_APB1RSTR_SPI2RST               ((uint32_t)0x00004000)        /*!< SPI 2 reset */
+ #define  RCC_APB1RSTR_USART3RST             ((uint32_t)0x00040000)        /*!< USART 3 reset */
+ #define  RCC_APB1RSTR_I2C2RST               ((uint32_t)0x00400000)        /*!< I2C 2 reset */
+#endif /* STM32F10X_LD && STM32F10X_LD_VL */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) || defined  (STM32F10X_XL)
+ #define  RCC_APB1RSTR_USBRST                ((uint32_t)0x00800000)        /*!< USB Device reset */
+#endif
+
+#if defined (STM32F10X_HD) || defined  (STM32F10X_CL) || defined  (STM32F10X_XL)
+ #define  RCC_APB1RSTR_TIM5RST                ((uint32_t)0x00000008)        /*!< Timer 5 reset */
+ #define  RCC_APB1RSTR_TIM6RST                ((uint32_t)0x00000010)        /*!< Timer 6 reset */
+ #define  RCC_APB1RSTR_TIM7RST                ((uint32_t)0x00000020)        /*!< Timer 7 reset */
+ #define  RCC_APB1RSTR_SPI3RST                ((uint32_t)0x00008000)        /*!< SPI 3 reset */
+ #define  RCC_APB1RSTR_UART4RST               ((uint32_t)0x00080000)        /*!< UART 4 reset */
+ #define  RCC_APB1RSTR_UART5RST               ((uint32_t)0x00100000)        /*!< UART 5 reset */
+ #define  RCC_APB1RSTR_DACRST                 ((uint32_t)0x20000000)        /*!< DAC interface reset */
+#endif
+
+#if defined (STM32F10X_LD_VL) || defined  (STM32F10X_MD_VL) || defined  (STM32F10X_HD_VL)
+ #define  RCC_APB1RSTR_TIM6RST                ((uint32_t)0x00000010)        /*!< Timer 6 reset */
+ #define  RCC_APB1RSTR_TIM7RST                ((uint32_t)0x00000020)        /*!< Timer 7 reset */
+ #define  RCC_APB1RSTR_DACRST                 ((uint32_t)0x20000000)        /*!< DAC interface reset */
+ #define  RCC_APB1RSTR_CECRST                 ((uint32_t)0x40000000)        /*!< CEC interface reset */ 
+#endif
+
+#if defined  (STM32F10X_HD_VL)
+ #define  RCC_APB1RSTR_TIM5RST                ((uint32_t)0x00000008)        /*!< Timer 5 reset */
+ #define  RCC_APB1RSTR_TIM12RST               ((uint32_t)0x00000040)        /*!< TIM12 Timer reset */
+ #define  RCC_APB1RSTR_TIM13RST               ((uint32_t)0x00000080)        /*!< TIM13 Timer reset */
+ #define  RCC_APB1RSTR_TIM14RST               ((uint32_t)0x00000100)        /*!< TIM14 Timer reset */
+ #define  RCC_APB1RSTR_SPI3RST                ((uint32_t)0x00008000)        /*!< SPI 3 reset */ 
+ #define  RCC_APB1RSTR_UART4RST               ((uint32_t)0x00080000)        /*!< UART 4 reset */
+ #define  RCC_APB1RSTR_UART5RST               ((uint32_t)0x00100000)        /*!< UART 5 reset */ 
+#endif
+
+#ifdef STM32F10X_CL
+ #define  RCC_APB1RSTR_CAN2RST                ((uint32_t)0x04000000)        /*!< CAN2 reset */
+#endif /* STM32F10X_CL */
+
+#ifdef STM32F10X_XL
+ #define  RCC_APB1RSTR_TIM12RST               ((uint32_t)0x00000040)         /*!< TIM12 Timer reset */
+ #define  RCC_APB1RSTR_TIM13RST               ((uint32_t)0x00000080)         /*!< TIM13 Timer reset */
+ #define  RCC_APB1RSTR_TIM14RST               ((uint32_t)0x00000100)         /*!< TIM14 Timer reset */
+#endif /* STM32F10X_XL */
+
+/******************  Bit definition for RCC_AHBENR register  ******************/
+#define  RCC_AHBENR_DMA1EN                   ((uint16_t)0x0001)            /*!< DMA1 clock enable */
+#define  RCC_AHBENR_SRAMEN                   ((uint16_t)0x0004)            /*!< SRAM interface clock enable */
+#define  RCC_AHBENR_FLITFEN                  ((uint16_t)0x0010)            /*!< FLITF clock enable */
+#define  RCC_AHBENR_CRCEN                    ((uint16_t)0x0040)            /*!< CRC clock enable */
+
+#if defined (STM32F10X_HD) || defined  (STM32F10X_CL) || defined  (STM32F10X_HD_VL)
+ #define  RCC_AHBENR_DMA2EN                  ((uint16_t)0x0002)            /*!< DMA2 clock enable */
+#endif
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_XL)
+ #define  RCC_AHBENR_FSMCEN                  ((uint16_t)0x0100)            /*!< FSMC clock enable */
+ #define  RCC_AHBENR_SDIOEN                  ((uint16_t)0x0400)            /*!< SDIO clock enable */
+#endif
+
+#if defined (STM32F10X_HD_VL)
+ #define  RCC_AHBENR_FSMCEN                  ((uint16_t)0x0100)            /*!< FSMC clock enable */
+#endif
+
+#ifdef STM32F10X_CL
+ #define  RCC_AHBENR_OTGFSEN                 ((uint32_t)0x00001000)         /*!< USB OTG FS clock enable */
+ #define  RCC_AHBENR_ETHMACEN                ((uint32_t)0x00004000)         /*!< ETHERNET MAC clock enable */
+ #define  RCC_AHBENR_ETHMACTXEN              ((uint32_t)0x00008000)         /*!< ETHERNET MAC Tx clock enable */
+ #define  RCC_AHBENR_ETHMACRXEN              ((uint32_t)0x00010000)         /*!< ETHERNET MAC Rx clock enable */
+#endif /* STM32F10X_CL */
+
+/******************  Bit definition for RCC_APB2ENR register  *****************/
+#define  RCC_APB2ENR_AFIOEN                  ((uint32_t)0x00000001)         /*!< Alternate Function I/O clock enable */
+#define  RCC_APB2ENR_IOPAEN                  ((uint32_t)0x00000004)         /*!< I/O port A clock enable */
+#define  RCC_APB2ENR_IOPBEN                  ((uint32_t)0x00000008)         /*!< I/O port B clock enable */
+#define  RCC_APB2ENR_IOPCEN                  ((uint32_t)0x00000010)         /*!< I/O port C clock enable */
+#define  RCC_APB2ENR_IOPDEN                  ((uint32_t)0x00000020)         /*!< I/O port D clock enable */
+#define  RCC_APB2ENR_ADC1EN                  ((uint32_t)0x00000200)         /*!< ADC 1 interface clock enable */
+
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
+#define  RCC_APB2ENR_ADC2EN                  ((uint32_t)0x00000400)         /*!< ADC 2 interface clock enable */
+#endif
+
+#define  RCC_APB2ENR_TIM1EN                  ((uint32_t)0x00000800)         /*!< TIM1 Timer clock enable */
+#define  RCC_APB2ENR_SPI1EN                  ((uint32_t)0x00001000)         /*!< SPI 1 clock enable */
+#define  RCC_APB2ENR_USART1EN                ((uint32_t)0x00004000)         /*!< USART1 clock enable */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+#define  RCC_APB2ENR_TIM15EN                 ((uint32_t)0x00010000)         /*!< TIM15 Timer clock enable */
+#define  RCC_APB2ENR_TIM16EN                 ((uint32_t)0x00020000)         /*!< TIM16 Timer clock enable */
+#define  RCC_APB2ENR_TIM17EN                 ((uint32_t)0x00040000)         /*!< TIM17 Timer clock enable */
+#endif
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL)
+ #define  RCC_APB2ENR_IOPEEN                 ((uint32_t)0x00000040)         /*!< I/O port E clock enable */
+#endif /* STM32F10X_LD && STM32F10X_LD_VL */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_XL)
+ #define  RCC_APB2ENR_IOPFEN                 ((uint32_t)0x00000080)         /*!< I/O port F clock enable */
+ #define  RCC_APB2ENR_IOPGEN                 ((uint32_t)0x00000100)         /*!< I/O port G clock enable */
+ #define  RCC_APB2ENR_TIM8EN                 ((uint32_t)0x00002000)         /*!< TIM8 Timer clock enable */
+ #define  RCC_APB2ENR_ADC3EN                 ((uint32_t)0x00008000)         /*!< DMA1 clock enable */
+#endif
+
+#if defined (STM32F10X_HD_VL)
+ #define  RCC_APB2ENR_IOPFEN                 ((uint32_t)0x00000080)         /*!< I/O port F clock enable */
+ #define  RCC_APB2ENR_IOPGEN                 ((uint32_t)0x00000100)         /*!< I/O port G clock enable */
+#endif
+
+#ifdef STM32F10X_XL
+ #define  RCC_APB2ENR_TIM9EN                 ((uint32_t)0x00080000)         /*!< TIM9 Timer clock enable  */
+ #define  RCC_APB2ENR_TIM10EN                ((uint32_t)0x00100000)         /*!< TIM10 Timer clock enable  */
+ #define  RCC_APB2ENR_TIM11EN                ((uint32_t)0x00200000)         /*!< TIM11 Timer clock enable */
+#endif
+
+/*****************  Bit definition for RCC_APB1ENR register  ******************/
+#define  RCC_APB1ENR_TIM2EN                  ((uint32_t)0x00000001)        /*!< Timer 2 clock enabled*/
+#define  RCC_APB1ENR_TIM3EN                  ((uint32_t)0x00000002)        /*!< Timer 3 clock enable */
+#define  RCC_APB1ENR_WWDGEN                  ((uint32_t)0x00000800)        /*!< Window Watchdog clock enable */
+#define  RCC_APB1ENR_USART2EN                ((uint32_t)0x00020000)        /*!< USART 2 clock enable */
+#define  RCC_APB1ENR_I2C1EN                  ((uint32_t)0x00200000)        /*!< I2C 1 clock enable */
+
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL)
+#define  RCC_APB1ENR_CAN1EN                  ((uint32_t)0x02000000)        /*!< CAN1 clock enable */
+#endif
+
+#define  RCC_APB1ENR_BKPEN                   ((uint32_t)0x08000000)        /*!< Backup interface clock enable */
+#define  RCC_APB1ENR_PWREN                   ((uint32_t)0x10000000)        /*!< Power interface clock enable */
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL)
+ #define  RCC_APB1ENR_TIM4EN                 ((uint32_t)0x00000004)        /*!< Timer 4 clock enable */
+ #define  RCC_APB1ENR_SPI2EN                 ((uint32_t)0x00004000)        /*!< SPI 2 clock enable */
+ #define  RCC_APB1ENR_USART3EN               ((uint32_t)0x00040000)        /*!< USART 3 clock enable */
+ #define  RCC_APB1ENR_I2C2EN                 ((uint32_t)0x00400000)        /*!< I2C 2 clock enable */
+#endif /* STM32F10X_LD && STM32F10X_LD_VL */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined  (STM32F10X_LD)
+ #define  RCC_APB1ENR_USBEN                  ((uint32_t)0x00800000)        /*!< USB Device clock enable */
+#endif
+
+#if defined (STM32F10X_HD) || defined  (STM32F10X_CL)
+ #define  RCC_APB1ENR_TIM5EN                 ((uint32_t)0x00000008)        /*!< Timer 5 clock enable */
+ #define  RCC_APB1ENR_TIM6EN                 ((uint32_t)0x00000010)        /*!< Timer 6 clock enable */
+ #define  RCC_APB1ENR_TIM7EN                 ((uint32_t)0x00000020)        /*!< Timer 7 clock enable */
+ #define  RCC_APB1ENR_SPI3EN                 ((uint32_t)0x00008000)        /*!< SPI 3 clock enable */
+ #define  RCC_APB1ENR_UART4EN                ((uint32_t)0x00080000)        /*!< UART 4 clock enable */
+ #define  RCC_APB1ENR_UART5EN                ((uint32_t)0x00100000)        /*!< UART 5 clock enable */
+ #define  RCC_APB1ENR_DACEN                  ((uint32_t)0x20000000)        /*!< DAC interface clock enable */
+#endif
+
+#if defined (STM32F10X_LD_VL) || defined  (STM32F10X_MD_VL) || defined  (STM32F10X_HD_VL)
+ #define  RCC_APB1ENR_TIM6EN                 ((uint32_t)0x00000010)        /*!< Timer 6 clock enable */
+ #define  RCC_APB1ENR_TIM7EN                 ((uint32_t)0x00000020)        /*!< Timer 7 clock enable */
+ #define  RCC_APB1ENR_DACEN                  ((uint32_t)0x20000000)        /*!< DAC interface clock enable */
+ #define  RCC_APB1ENR_CECEN                  ((uint32_t)0x40000000)        /*!< CEC interface clock enable */ 
+#endif
+
+#ifdef STM32F10X_HD_VL
+ #define  RCC_APB1ENR_TIM5EN                 ((uint32_t)0x00000008)        /*!< Timer 5 clock enable */
+ #define  RCC_APB1ENR_TIM12EN                ((uint32_t)0x00000040)         /*!< TIM12 Timer clock enable  */
+ #define  RCC_APB1ENR_TIM13EN                ((uint32_t)0x00000080)         /*!< TIM13 Timer clock enable  */
+ #define  RCC_APB1ENR_TIM14EN                ((uint32_t)0x00000100)         /*!< TIM14 Timer clock enable */
+ #define  RCC_APB1ENR_SPI3EN                 ((uint32_t)0x00008000)        /*!< SPI 3 clock enable */
+ #define  RCC_APB1ENR_UART4EN                ((uint32_t)0x00080000)        /*!< UART 4 clock enable */
+ #define  RCC_APB1ENR_UART5EN                ((uint32_t)0x00100000)        /*!< UART 5 clock enable */ 
+#endif /* STM32F10X_HD_VL */
+
+#ifdef STM32F10X_CL
+ #define  RCC_APB1ENR_CAN2EN                  ((uint32_t)0x04000000)        /*!< CAN2 clock enable */
+#endif /* STM32F10X_CL */
+
+#ifdef STM32F10X_XL
+ #define  RCC_APB1ENR_TIM12EN                ((uint32_t)0x00000040)         /*!< TIM12 Timer clock enable  */
+ #define  RCC_APB1ENR_TIM13EN                ((uint32_t)0x00000080)         /*!< TIM13 Timer clock enable  */
+ #define  RCC_APB1ENR_TIM14EN                ((uint32_t)0x00000100)         /*!< TIM14 Timer clock enable */
+#endif /* STM32F10X_XL */
+
+/*******************  Bit definition for RCC_BDCR register  *******************/
+#define  RCC_BDCR_LSEON                      ((uint32_t)0x00000001)        /*!< External Low Speed oscillator enable */
+#define  RCC_BDCR_LSERDY                     ((uint32_t)0x00000002)        /*!< External Low Speed oscillator Ready */
+#define  RCC_BDCR_LSEBYP                     ((uint32_t)0x00000004)        /*!< External Low Speed oscillator Bypass */
+
+#define  RCC_BDCR_RTCSEL                     ((uint32_t)0x00000300)        /*!< RTCSEL[1:0] bits (RTC clock source selection) */
+#define  RCC_BDCR_RTCSEL_0                   ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  RCC_BDCR_RTCSEL_1                   ((uint32_t)0x00000200)        /*!< Bit 1 */
+
+/*!< RTC congiguration */
+#define  RCC_BDCR_RTCSEL_NOCLOCK             ((uint32_t)0x00000000)        /*!< No clock */
+#define  RCC_BDCR_RTCSEL_LSE                 ((uint32_t)0x00000100)        /*!< LSE oscillator clock used as RTC clock */
+#define  RCC_BDCR_RTCSEL_LSI                 ((uint32_t)0x00000200)        /*!< LSI oscillator clock used as RTC clock */
+#define  RCC_BDCR_RTCSEL_HSE                 ((uint32_t)0x00000300)        /*!< HSE oscillator clock divided by 128 used as RTC clock */
+
+#define  RCC_BDCR_RTCEN                      ((uint32_t)0x00008000)        /*!< RTC clock enable */
+#define  RCC_BDCR_BDRST                      ((uint32_t)0x00010000)        /*!< Backup domain software reset  */
+
+/*******************  Bit definition for RCC_CSR register  ********************/  
+#define  RCC_CSR_LSION                       ((uint32_t)0x00000001)        /*!< Internal Low Speed oscillator enable */
+#define  RCC_CSR_LSIRDY                      ((uint32_t)0x00000002)        /*!< Internal Low Speed oscillator Ready */
+#define  RCC_CSR_RMVF                        ((uint32_t)0x01000000)        /*!< Remove reset flag */
+#define  RCC_CSR_PINRSTF                     ((uint32_t)0x04000000)        /*!< PIN reset flag */
+#define  RCC_CSR_PORRSTF                     ((uint32_t)0x08000000)        /*!< POR/PDR reset flag */
+#define  RCC_CSR_SFTRSTF                     ((uint32_t)0x10000000)        /*!< Software Reset flag */
+#define  RCC_CSR_IWDGRSTF                    ((uint32_t)0x20000000)        /*!< Independent Watchdog reset flag */
+#define  RCC_CSR_WWDGRSTF                    ((uint32_t)0x40000000)        /*!< Window watchdog reset flag */
+#define  RCC_CSR_LPWRRSTF                    ((uint32_t)0x80000000)        /*!< Low-Power reset flag */
+
+#ifdef STM32F10X_CL
+/*******************  Bit definition for RCC_AHBRSTR register  ****************/
+ #define  RCC_AHBRSTR_OTGFSRST               ((uint32_t)0x00001000)         /*!< USB OTG FS reset */
+ #define  RCC_AHBRSTR_ETHMACRST              ((uint32_t)0x00004000)         /*!< ETHERNET MAC reset */
+
+/*******************  Bit definition for RCC_CFGR2 register  ******************/
+/*!< PREDIV1 configuration */
+ #define  RCC_CFGR2_PREDIV1                  ((uint32_t)0x0000000F)        /*!< PREDIV1[3:0] bits */
+ #define  RCC_CFGR2_PREDIV1_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+ #define  RCC_CFGR2_PREDIV1_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+ #define  RCC_CFGR2_PREDIV1_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+ #define  RCC_CFGR2_PREDIV1_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+ #define  RCC_CFGR2_PREDIV1_DIV1             ((uint32_t)0x00000000)        /*!< PREDIV1 input clock not divided */
+ #define  RCC_CFGR2_PREDIV1_DIV2             ((uint32_t)0x00000001)        /*!< PREDIV1 input clock divided by 2 */
+ #define  RCC_CFGR2_PREDIV1_DIV3             ((uint32_t)0x00000002)        /*!< PREDIV1 input clock divided by 3 */
+ #define  RCC_CFGR2_PREDIV1_DIV4             ((uint32_t)0x00000003)        /*!< PREDIV1 input clock divided by 4 */
+ #define  RCC_CFGR2_PREDIV1_DIV5             ((uint32_t)0x00000004)        /*!< PREDIV1 input clock divided by 5 */
+ #define  RCC_CFGR2_PREDIV1_DIV6             ((uint32_t)0x00000005)        /*!< PREDIV1 input clock divided by 6 */
+ #define  RCC_CFGR2_PREDIV1_DIV7             ((uint32_t)0x00000006)        /*!< PREDIV1 input clock divided by 7 */
+ #define  RCC_CFGR2_PREDIV1_DIV8             ((uint32_t)0x00000007)        /*!< PREDIV1 input clock divided by 8 */
+ #define  RCC_CFGR2_PREDIV1_DIV9             ((uint32_t)0x00000008)        /*!< PREDIV1 input clock divided by 9 */
+ #define  RCC_CFGR2_PREDIV1_DIV10            ((uint32_t)0x00000009)        /*!< PREDIV1 input clock divided by 10 */
+ #define  RCC_CFGR2_PREDIV1_DIV11            ((uint32_t)0x0000000A)        /*!< PREDIV1 input clock divided by 11 */
+ #define  RCC_CFGR2_PREDIV1_DIV12            ((uint32_t)0x0000000B)        /*!< PREDIV1 input clock divided by 12 */
+ #define  RCC_CFGR2_PREDIV1_DIV13            ((uint32_t)0x0000000C)        /*!< PREDIV1 input clock divided by 13 */
+ #define  RCC_CFGR2_PREDIV1_DIV14            ((uint32_t)0x0000000D)        /*!< PREDIV1 input clock divided by 14 */
+ #define  RCC_CFGR2_PREDIV1_DIV15            ((uint32_t)0x0000000E)        /*!< PREDIV1 input clock divided by 15 */
+ #define  RCC_CFGR2_PREDIV1_DIV16            ((uint32_t)0x0000000F)        /*!< PREDIV1 input clock divided by 16 */
+
+/*!< PREDIV2 configuration */
+ #define  RCC_CFGR2_PREDIV2                  ((uint32_t)0x000000F0)        /*!< PREDIV2[3:0] bits */
+ #define  RCC_CFGR2_PREDIV2_0                ((uint32_t)0x00000010)        /*!< Bit 0 */
+ #define  RCC_CFGR2_PREDIV2_1                ((uint32_t)0x00000020)        /*!< Bit 1 */
+ #define  RCC_CFGR2_PREDIV2_2                ((uint32_t)0x00000040)        /*!< Bit 2 */
+ #define  RCC_CFGR2_PREDIV2_3                ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+ #define  RCC_CFGR2_PREDIV2_DIV1             ((uint32_t)0x00000000)        /*!< PREDIV2 input clock not divided */
+ #define  RCC_CFGR2_PREDIV2_DIV2             ((uint32_t)0x00000010)        /*!< PREDIV2 input clock divided by 2 */
+ #define  RCC_CFGR2_PREDIV2_DIV3             ((uint32_t)0x00000020)        /*!< PREDIV2 input clock divided by 3 */
+ #define  RCC_CFGR2_PREDIV2_DIV4             ((uint32_t)0x00000030)        /*!< PREDIV2 input clock divided by 4 */
+ #define  RCC_CFGR2_PREDIV2_DIV5             ((uint32_t)0x00000040)        /*!< PREDIV2 input clock divided by 5 */
+ #define  RCC_CFGR2_PREDIV2_DIV6             ((uint32_t)0x00000050)        /*!< PREDIV2 input clock divided by 6 */
+ #define  RCC_CFGR2_PREDIV2_DIV7             ((uint32_t)0x00000060)        /*!< PREDIV2 input clock divided by 7 */
+ #define  RCC_CFGR2_PREDIV2_DIV8             ((uint32_t)0x00000070)        /*!< PREDIV2 input clock divided by 8 */
+ #define  RCC_CFGR2_PREDIV2_DIV9             ((uint32_t)0x00000080)        /*!< PREDIV2 input clock divided by 9 */
+ #define  RCC_CFGR2_PREDIV2_DIV10            ((uint32_t)0x00000090)        /*!< PREDIV2 input clock divided by 10 */
+ #define  RCC_CFGR2_PREDIV2_DIV11            ((uint32_t)0x000000A0)        /*!< PREDIV2 input clock divided by 11 */
+ #define  RCC_CFGR2_PREDIV2_DIV12            ((uint32_t)0x000000B0)        /*!< PREDIV2 input clock divided by 12 */
+ #define  RCC_CFGR2_PREDIV2_DIV13            ((uint32_t)0x000000C0)        /*!< PREDIV2 input clock divided by 13 */
+ #define  RCC_CFGR2_PREDIV2_DIV14            ((uint32_t)0x000000D0)        /*!< PREDIV2 input clock divided by 14 */
+ #define  RCC_CFGR2_PREDIV2_DIV15            ((uint32_t)0x000000E0)        /*!< PREDIV2 input clock divided by 15 */
+ #define  RCC_CFGR2_PREDIV2_DIV16            ((uint32_t)0x000000F0)        /*!< PREDIV2 input clock divided by 16 */
+
+/*!< PLL2MUL configuration */
+ #define  RCC_CFGR2_PLL2MUL                  ((uint32_t)0x00000F00)        /*!< PLL2MUL[3:0] bits */
+ #define  RCC_CFGR2_PLL2MUL_0                ((uint32_t)0x00000100)        /*!< Bit 0 */
+ #define  RCC_CFGR2_PLL2MUL_1                ((uint32_t)0x00000200)        /*!< Bit 1 */
+ #define  RCC_CFGR2_PLL2MUL_2                ((uint32_t)0x00000400)        /*!< Bit 2 */
+ #define  RCC_CFGR2_PLL2MUL_3                ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+ #define  RCC_CFGR2_PLL2MUL8                 ((uint32_t)0x00000600)        /*!< PLL2 input clock * 8 */
+ #define  RCC_CFGR2_PLL2MUL9                 ((uint32_t)0x00000700)        /*!< PLL2 input clock * 9 */
+ #define  RCC_CFGR2_PLL2MUL10                ((uint32_t)0x00000800)        /*!< PLL2 input clock * 10 */
+ #define  RCC_CFGR2_PLL2MUL11                ((uint32_t)0x00000900)        /*!< PLL2 input clock * 11 */
+ #define  RCC_CFGR2_PLL2MUL12                ((uint32_t)0x00000A00)        /*!< PLL2 input clock * 12 */
+ #define  RCC_CFGR2_PLL2MUL13                ((uint32_t)0x00000B00)        /*!< PLL2 input clock * 13 */
+ #define  RCC_CFGR2_PLL2MUL14                ((uint32_t)0x00000C00)        /*!< PLL2 input clock * 14 */
+ #define  RCC_CFGR2_PLL2MUL16                ((uint32_t)0x00000E00)        /*!< PLL2 input clock * 16 */
+ #define  RCC_CFGR2_PLL2MUL20                ((uint32_t)0x00000F00)        /*!< PLL2 input clock * 20 */
+
+/*!< PLL3MUL configuration */
+ #define  RCC_CFGR2_PLL3MUL                  ((uint32_t)0x0000F000)        /*!< PLL3MUL[3:0] bits */
+ #define  RCC_CFGR2_PLL3MUL_0                ((uint32_t)0x00001000)        /*!< Bit 0 */
+ #define  RCC_CFGR2_PLL3MUL_1                ((uint32_t)0x00002000)        /*!< Bit 1 */
+ #define  RCC_CFGR2_PLL3MUL_2                ((uint32_t)0x00004000)        /*!< Bit 2 */
+ #define  RCC_CFGR2_PLL3MUL_3                ((uint32_t)0x00008000)        /*!< Bit 3 */
+
+ #define  RCC_CFGR2_PLL3MUL8                 ((uint32_t)0x00006000)        /*!< PLL3 input clock * 8 */
+ #define  RCC_CFGR2_PLL3MUL9                 ((uint32_t)0x00007000)        /*!< PLL3 input clock * 9 */
+ #define  RCC_CFGR2_PLL3MUL10                ((uint32_t)0x00008000)        /*!< PLL3 input clock * 10 */
+ #define  RCC_CFGR2_PLL3MUL11                ((uint32_t)0x00009000)        /*!< PLL3 input clock * 11 */
+ #define  RCC_CFGR2_PLL3MUL12                ((uint32_t)0x0000A000)        /*!< PLL3 input clock * 12 */
+ #define  RCC_CFGR2_PLL3MUL13                ((uint32_t)0x0000B000)        /*!< PLL3 input clock * 13 */
+ #define  RCC_CFGR2_PLL3MUL14                ((uint32_t)0x0000C000)        /*!< PLL3 input clock * 14 */
+ #define  RCC_CFGR2_PLL3MUL16                ((uint32_t)0x0000E000)        /*!< PLL3 input clock * 16 */
+ #define  RCC_CFGR2_PLL3MUL20                ((uint32_t)0x0000F000)        /*!< PLL3 input clock * 20 */
+
+ #define  RCC_CFGR2_PREDIV1SRC               ((uint32_t)0x00010000)        /*!< PREDIV1 entry clock source */
+ #define  RCC_CFGR2_PREDIV1SRC_PLL2          ((uint32_t)0x00010000)        /*!< PLL2 selected as PREDIV1 entry clock source */
+ #define  RCC_CFGR2_PREDIV1SRC_HSE           ((uint32_t)0x00000000)        /*!< HSE selected as PREDIV1 entry clock source */
+ #define  RCC_CFGR2_I2S2SRC                  ((uint32_t)0x00020000)        /*!< I2S2 entry clock source */
+ #define  RCC_CFGR2_I2S3SRC                  ((uint32_t)0x00040000)        /*!< I2S3 clock source */
+#endif /* STM32F10X_CL */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+/*******************  Bit definition for RCC_CFGR2 register  ******************/
+/*!< PREDIV1 configuration */
+ #define  RCC_CFGR2_PREDIV1                  ((uint32_t)0x0000000F)        /*!< PREDIV1[3:0] bits */
+ #define  RCC_CFGR2_PREDIV1_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+ #define  RCC_CFGR2_PREDIV1_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+ #define  RCC_CFGR2_PREDIV1_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+ #define  RCC_CFGR2_PREDIV1_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+ #define  RCC_CFGR2_PREDIV1_DIV1             ((uint32_t)0x00000000)        /*!< PREDIV1 input clock not divided */
+ #define  RCC_CFGR2_PREDIV1_DIV2             ((uint32_t)0x00000001)        /*!< PREDIV1 input clock divided by 2 */
+ #define  RCC_CFGR2_PREDIV1_DIV3             ((uint32_t)0x00000002)        /*!< PREDIV1 input clock divided by 3 */
+ #define  RCC_CFGR2_PREDIV1_DIV4             ((uint32_t)0x00000003)        /*!< PREDIV1 input clock divided by 4 */
+ #define  RCC_CFGR2_PREDIV1_DIV5             ((uint32_t)0x00000004)        /*!< PREDIV1 input clock divided by 5 */
+ #define  RCC_CFGR2_PREDIV1_DIV6             ((uint32_t)0x00000005)        /*!< PREDIV1 input clock divided by 6 */
+ #define  RCC_CFGR2_PREDIV1_DIV7             ((uint32_t)0x00000006)        /*!< PREDIV1 input clock divided by 7 */
+ #define  RCC_CFGR2_PREDIV1_DIV8             ((uint32_t)0x00000007)        /*!< PREDIV1 input clock divided by 8 */
+ #define  RCC_CFGR2_PREDIV1_DIV9             ((uint32_t)0x00000008)        /*!< PREDIV1 input clock divided by 9 */
+ #define  RCC_CFGR2_PREDIV1_DIV10            ((uint32_t)0x00000009)        /*!< PREDIV1 input clock divided by 10 */
+ #define  RCC_CFGR2_PREDIV1_DIV11            ((uint32_t)0x0000000A)        /*!< PREDIV1 input clock divided by 11 */
+ #define  RCC_CFGR2_PREDIV1_DIV12            ((uint32_t)0x0000000B)        /*!< PREDIV1 input clock divided by 12 */
+ #define  RCC_CFGR2_PREDIV1_DIV13            ((uint32_t)0x0000000C)        /*!< PREDIV1 input clock divided by 13 */
+ #define  RCC_CFGR2_PREDIV1_DIV14            ((uint32_t)0x0000000D)        /*!< PREDIV1 input clock divided by 14 */
+ #define  RCC_CFGR2_PREDIV1_DIV15            ((uint32_t)0x0000000E)        /*!< PREDIV1 input clock divided by 15 */
+ #define  RCC_CFGR2_PREDIV1_DIV16            ((uint32_t)0x0000000F)        /*!< PREDIV1 input clock divided by 16 */
+#endif
+ 
+/******************************************************************************/
+/*                                                                            */
+/*                General Purpose and Alternate Function I/O                  */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for GPIO_CRL register  *******************/
+#define  GPIO_CRL_MODE                       ((uint32_t)0x33333333)        /*!< Port x mode bits */
+
+#define  GPIO_CRL_MODE0                      ((uint32_t)0x00000003)        /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */
+#define  GPIO_CRL_MODE0_0                    ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE0_1                    ((uint32_t)0x00000002)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE1                      ((uint32_t)0x00000030)        /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */
+#define  GPIO_CRL_MODE1_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE1_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE2                      ((uint32_t)0x00000300)        /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */
+#define  GPIO_CRL_MODE2_0                    ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE2_1                    ((uint32_t)0x00000200)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE3                      ((uint32_t)0x00003000)        /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */
+#define  GPIO_CRL_MODE3_0                    ((uint32_t)0x00001000)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE3_1                    ((uint32_t)0x00002000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE4                      ((uint32_t)0x00030000)        /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */
+#define  GPIO_CRL_MODE4_0                    ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE4_1                    ((uint32_t)0x00020000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE5                      ((uint32_t)0x00300000)        /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */
+#define  GPIO_CRL_MODE5_0                    ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE5_1                    ((uint32_t)0x00200000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE6                      ((uint32_t)0x03000000)        /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */
+#define  GPIO_CRL_MODE6_0                    ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE6_1                    ((uint32_t)0x02000000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_MODE7                      ((uint32_t)0x30000000)        /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */
+#define  GPIO_CRL_MODE7_0                    ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  GPIO_CRL_MODE7_1                    ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF                        ((uint32_t)0xCCCCCCCC)        /*!< Port x configuration bits */
+
+#define  GPIO_CRL_CNF0                       ((uint32_t)0x0000000C)        /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */
+#define  GPIO_CRL_CNF0_0                     ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF0_1                     ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF1                       ((uint32_t)0x000000C0)        /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */
+#define  GPIO_CRL_CNF1_0                     ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF1_1                     ((uint32_t)0x00000080)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF2                       ((uint32_t)0x00000C00)        /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */
+#define  GPIO_CRL_CNF2_0                     ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF2_1                     ((uint32_t)0x00000800)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF3                       ((uint32_t)0x0000C000)        /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */
+#define  GPIO_CRL_CNF3_0                     ((uint32_t)0x00004000)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF3_1                     ((uint32_t)0x00008000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF4                       ((uint32_t)0x000C0000)        /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */
+#define  GPIO_CRL_CNF4_0                     ((uint32_t)0x00040000)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF4_1                     ((uint32_t)0x00080000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF5                       ((uint32_t)0x00C00000)        /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */
+#define  GPIO_CRL_CNF5_0                     ((uint32_t)0x00400000)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF5_1                     ((uint32_t)0x00800000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF6                       ((uint32_t)0x0C000000)        /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */
+#define  GPIO_CRL_CNF6_0                     ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF6_1                     ((uint32_t)0x08000000)        /*!< Bit 1 */
+
+#define  GPIO_CRL_CNF7                       ((uint32_t)0xC0000000)        /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */
+#define  GPIO_CRL_CNF7_0                     ((uint32_t)0x40000000)        /*!< Bit 0 */
+#define  GPIO_CRL_CNF7_1                     ((uint32_t)0x80000000)        /*!< Bit 1 */
+
+/*******************  Bit definition for GPIO_CRH register  *******************/
+#define  GPIO_CRH_MODE                       ((uint32_t)0x33333333)        /*!< Port x mode bits */
+
+#define  GPIO_CRH_MODE8                      ((uint32_t)0x00000003)        /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */
+#define  GPIO_CRH_MODE8_0                    ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE8_1                    ((uint32_t)0x00000002)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE9                      ((uint32_t)0x00000030)        /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */
+#define  GPIO_CRH_MODE9_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE9_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE10                     ((uint32_t)0x00000300)        /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */
+#define  GPIO_CRH_MODE10_0                   ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE10_1                   ((uint32_t)0x00000200)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE11                     ((uint32_t)0x00003000)        /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */
+#define  GPIO_CRH_MODE11_0                   ((uint32_t)0x00001000)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE11_1                   ((uint32_t)0x00002000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE12                     ((uint32_t)0x00030000)        /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */
+#define  GPIO_CRH_MODE12_0                   ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE12_1                   ((uint32_t)0x00020000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE13                     ((uint32_t)0x00300000)        /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */
+#define  GPIO_CRH_MODE13_0                   ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE13_1                   ((uint32_t)0x00200000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE14                     ((uint32_t)0x03000000)        /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */
+#define  GPIO_CRH_MODE14_0                   ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE14_1                   ((uint32_t)0x02000000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_MODE15                     ((uint32_t)0x30000000)        /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */
+#define  GPIO_CRH_MODE15_0                   ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  GPIO_CRH_MODE15_1                   ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF                        ((uint32_t)0xCCCCCCCC)        /*!< Port x configuration bits */
+
+#define  GPIO_CRH_CNF8                       ((uint32_t)0x0000000C)        /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */
+#define  GPIO_CRH_CNF8_0                     ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF8_1                     ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF9                       ((uint32_t)0x000000C0)        /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */
+#define  GPIO_CRH_CNF9_0                     ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF9_1                     ((uint32_t)0x00000080)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF10                      ((uint32_t)0x00000C00)        /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */
+#define  GPIO_CRH_CNF10_0                    ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF10_1                    ((uint32_t)0x00000800)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF11                      ((uint32_t)0x0000C000)        /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */
+#define  GPIO_CRH_CNF11_0                    ((uint32_t)0x00004000)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF11_1                    ((uint32_t)0x00008000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF12                      ((uint32_t)0x000C0000)        /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */
+#define  GPIO_CRH_CNF12_0                    ((uint32_t)0x00040000)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF12_1                    ((uint32_t)0x00080000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF13                      ((uint32_t)0x00C00000)        /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */
+#define  GPIO_CRH_CNF13_0                    ((uint32_t)0x00400000)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF13_1                    ((uint32_t)0x00800000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF14                      ((uint32_t)0x0C000000)        /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */
+#define  GPIO_CRH_CNF14_0                    ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF14_1                    ((uint32_t)0x08000000)        /*!< Bit 1 */
+
+#define  GPIO_CRH_CNF15                      ((uint32_t)0xC0000000)        /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */
+#define  GPIO_CRH_CNF15_0                    ((uint32_t)0x40000000)        /*!< Bit 0 */
+#define  GPIO_CRH_CNF15_1                    ((uint32_t)0x80000000)        /*!< Bit 1 */
+
+/*!<******************  Bit definition for GPIO_IDR register  *******************/
+#define GPIO_IDR_IDR0                        ((uint16_t)0x0001)            /*!< Port input data, bit 0 */
+#define GPIO_IDR_IDR1                        ((uint16_t)0x0002)            /*!< Port input data, bit 1 */
+#define GPIO_IDR_IDR2                        ((uint16_t)0x0004)            /*!< Port input data, bit 2 */
+#define GPIO_IDR_IDR3                        ((uint16_t)0x0008)            /*!< Port input data, bit 3 */
+#define GPIO_IDR_IDR4                        ((uint16_t)0x0010)            /*!< Port input data, bit 4 */
+#define GPIO_IDR_IDR5                        ((uint16_t)0x0020)            /*!< Port input data, bit 5 */
+#define GPIO_IDR_IDR6                        ((uint16_t)0x0040)            /*!< Port input data, bit 6 */
+#define GPIO_IDR_IDR7                        ((uint16_t)0x0080)            /*!< Port input data, bit 7 */
+#define GPIO_IDR_IDR8                        ((uint16_t)0x0100)            /*!< Port input data, bit 8 */
+#define GPIO_IDR_IDR9                        ((uint16_t)0x0200)            /*!< Port input data, bit 9 */
+#define GPIO_IDR_IDR10                       ((uint16_t)0x0400)            /*!< Port input data, bit 10 */
+#define GPIO_IDR_IDR11                       ((uint16_t)0x0800)            /*!< Port input data, bit 11 */
+#define GPIO_IDR_IDR12                       ((uint16_t)0x1000)            /*!< Port input data, bit 12 */
+#define GPIO_IDR_IDR13                       ((uint16_t)0x2000)            /*!< Port input data, bit 13 */
+#define GPIO_IDR_IDR14                       ((uint16_t)0x4000)            /*!< Port input data, bit 14 */
+#define GPIO_IDR_IDR15                       ((uint16_t)0x8000)            /*!< Port input data, bit 15 */
+
+/*******************  Bit definition for GPIO_ODR register  *******************/
+#define GPIO_ODR_ODR0                        ((uint16_t)0x0001)            /*!< Port output data, bit 0 */
+#define GPIO_ODR_ODR1                        ((uint16_t)0x0002)            /*!< Port output data, bit 1 */
+#define GPIO_ODR_ODR2                        ((uint16_t)0x0004)            /*!< Port output data, bit 2 */
+#define GPIO_ODR_ODR3                        ((uint16_t)0x0008)            /*!< Port output data, bit 3 */
+#define GPIO_ODR_ODR4                        ((uint16_t)0x0010)            /*!< Port output data, bit 4 */
+#define GPIO_ODR_ODR5                        ((uint16_t)0x0020)            /*!< Port output data, bit 5 */
+#define GPIO_ODR_ODR6                        ((uint16_t)0x0040)            /*!< Port output data, bit 6 */
+#define GPIO_ODR_ODR7                        ((uint16_t)0x0080)            /*!< Port output data, bit 7 */
+#define GPIO_ODR_ODR8                        ((uint16_t)0x0100)            /*!< Port output data, bit 8 */
+#define GPIO_ODR_ODR9                        ((uint16_t)0x0200)            /*!< Port output data, bit 9 */
+#define GPIO_ODR_ODR10                       ((uint16_t)0x0400)            /*!< Port output data, bit 10 */
+#define GPIO_ODR_ODR11                       ((uint16_t)0x0800)            /*!< Port output data, bit 11 */
+#define GPIO_ODR_ODR12                       ((uint16_t)0x1000)            /*!< Port output data, bit 12 */
+#define GPIO_ODR_ODR13                       ((uint16_t)0x2000)            /*!< Port output data, bit 13 */
+#define GPIO_ODR_ODR14                       ((uint16_t)0x4000)            /*!< Port output data, bit 14 */
+#define GPIO_ODR_ODR15                       ((uint16_t)0x8000)            /*!< Port output data, bit 15 */
+
+/******************  Bit definition for GPIO_BSRR register  *******************/
+#define GPIO_BSRR_BS0                        ((uint32_t)0x00000001)        /*!< Port x Set bit 0 */
+#define GPIO_BSRR_BS1                        ((uint32_t)0x00000002)        /*!< Port x Set bit 1 */
+#define GPIO_BSRR_BS2                        ((uint32_t)0x00000004)        /*!< Port x Set bit 2 */
+#define GPIO_BSRR_BS3                        ((uint32_t)0x00000008)        /*!< Port x Set bit 3 */
+#define GPIO_BSRR_BS4                        ((uint32_t)0x00000010)        /*!< Port x Set bit 4 */
+#define GPIO_BSRR_BS5                        ((uint32_t)0x00000020)        /*!< Port x Set bit 5 */
+#define GPIO_BSRR_BS6                        ((uint32_t)0x00000040)        /*!< Port x Set bit 6 */
+#define GPIO_BSRR_BS7                        ((uint32_t)0x00000080)        /*!< Port x Set bit 7 */
+#define GPIO_BSRR_BS8                        ((uint32_t)0x00000100)        /*!< Port x Set bit 8 */
+#define GPIO_BSRR_BS9                        ((uint32_t)0x00000200)        /*!< Port x Set bit 9 */
+#define GPIO_BSRR_BS10                       ((uint32_t)0x00000400)        /*!< Port x Set bit 10 */
+#define GPIO_BSRR_BS11                       ((uint32_t)0x00000800)        /*!< Port x Set bit 11 */
+#define GPIO_BSRR_BS12                       ((uint32_t)0x00001000)        /*!< Port x Set bit 12 */
+#define GPIO_BSRR_BS13                       ((uint32_t)0x00002000)        /*!< Port x Set bit 13 */
+#define GPIO_BSRR_BS14                       ((uint32_t)0x00004000)        /*!< Port x Set bit 14 */
+#define GPIO_BSRR_BS15                       ((uint32_t)0x00008000)        /*!< Port x Set bit 15 */
+
+#define GPIO_BSRR_BR0                        ((uint32_t)0x00010000)        /*!< Port x Reset bit 0 */
+#define GPIO_BSRR_BR1                        ((uint32_t)0x00020000)        /*!< Port x Reset bit 1 */
+#define GPIO_BSRR_BR2                        ((uint32_t)0x00040000)        /*!< Port x Reset bit 2 */
+#define GPIO_BSRR_BR3                        ((uint32_t)0x00080000)        /*!< Port x Reset bit 3 */
+#define GPIO_BSRR_BR4                        ((uint32_t)0x00100000)        /*!< Port x Reset bit 4 */
+#define GPIO_BSRR_BR5                        ((uint32_t)0x00200000)        /*!< Port x Reset bit 5 */
+#define GPIO_BSRR_BR6                        ((uint32_t)0x00400000)        /*!< Port x Reset bit 6 */
+#define GPIO_BSRR_BR7                        ((uint32_t)0x00800000)        /*!< Port x Reset bit 7 */
+#define GPIO_BSRR_BR8                        ((uint32_t)0x01000000)        /*!< Port x Reset bit 8 */
+#define GPIO_BSRR_BR9                        ((uint32_t)0x02000000)        /*!< Port x Reset bit 9 */
+#define GPIO_BSRR_BR10                       ((uint32_t)0x04000000)        /*!< Port x Reset bit 10 */
+#define GPIO_BSRR_BR11                       ((uint32_t)0x08000000)        /*!< Port x Reset bit 11 */
+#define GPIO_BSRR_BR12                       ((uint32_t)0x10000000)        /*!< Port x Reset bit 12 */
+#define GPIO_BSRR_BR13                       ((uint32_t)0x20000000)        /*!< Port x Reset bit 13 */
+#define GPIO_BSRR_BR14                       ((uint32_t)0x40000000)        /*!< Port x Reset bit 14 */
+#define GPIO_BSRR_BR15                       ((uint32_t)0x80000000)        /*!< Port x Reset bit 15 */
+
+/*******************  Bit definition for GPIO_BRR register  *******************/
+#define GPIO_BRR_BR0                         ((uint16_t)0x0001)            /*!< Port x Reset bit 0 */
+#define GPIO_BRR_BR1                         ((uint16_t)0x0002)            /*!< Port x Reset bit 1 */
+#define GPIO_BRR_BR2                         ((uint16_t)0x0004)            /*!< Port x Reset bit 2 */
+#define GPIO_BRR_BR3                         ((uint16_t)0x0008)            /*!< Port x Reset bit 3 */
+#define GPIO_BRR_BR4                         ((uint16_t)0x0010)            /*!< Port x Reset bit 4 */
+#define GPIO_BRR_BR5                         ((uint16_t)0x0020)            /*!< Port x Reset bit 5 */
+#define GPIO_BRR_BR6                         ((uint16_t)0x0040)            /*!< Port x Reset bit 6 */
+#define GPIO_BRR_BR7                         ((uint16_t)0x0080)            /*!< Port x Reset bit 7 */
+#define GPIO_BRR_BR8                         ((uint16_t)0x0100)            /*!< Port x Reset bit 8 */
+#define GPIO_BRR_BR9                         ((uint16_t)0x0200)            /*!< Port x Reset bit 9 */
+#define GPIO_BRR_BR10                        ((uint16_t)0x0400)            /*!< Port x Reset bit 10 */
+#define GPIO_BRR_BR11                        ((uint16_t)0x0800)            /*!< Port x Reset bit 11 */
+#define GPIO_BRR_BR12                        ((uint16_t)0x1000)            /*!< Port x Reset bit 12 */
+#define GPIO_BRR_BR13                        ((uint16_t)0x2000)            /*!< Port x Reset bit 13 */
+#define GPIO_BRR_BR14                        ((uint16_t)0x4000)            /*!< Port x Reset bit 14 */
+#define GPIO_BRR_BR15                        ((uint16_t)0x8000)            /*!< Port x Reset bit 15 */
+
+/******************  Bit definition for GPIO_LCKR register  *******************/
+#define GPIO_LCKR_LCK0                       ((uint32_t)0x00000001)        /*!< Port x Lock bit 0 */
+#define GPIO_LCKR_LCK1                       ((uint32_t)0x00000002)        /*!< Port x Lock bit 1 */
+#define GPIO_LCKR_LCK2                       ((uint32_t)0x00000004)        /*!< Port x Lock bit 2 */
+#define GPIO_LCKR_LCK3                       ((uint32_t)0x00000008)        /*!< Port x Lock bit 3 */
+#define GPIO_LCKR_LCK4                       ((uint32_t)0x00000010)        /*!< Port x Lock bit 4 */
+#define GPIO_LCKR_LCK5                       ((uint32_t)0x00000020)        /*!< Port x Lock bit 5 */
+#define GPIO_LCKR_LCK6                       ((uint32_t)0x00000040)        /*!< Port x Lock bit 6 */
+#define GPIO_LCKR_LCK7                       ((uint32_t)0x00000080)        /*!< Port x Lock bit 7 */
+#define GPIO_LCKR_LCK8                       ((uint32_t)0x00000100)        /*!< Port x Lock bit 8 */
+#define GPIO_LCKR_LCK9                       ((uint32_t)0x00000200)        /*!< Port x Lock bit 9 */
+#define GPIO_LCKR_LCK10                      ((uint32_t)0x00000400)        /*!< Port x Lock bit 10 */
+#define GPIO_LCKR_LCK11                      ((uint32_t)0x00000800)        /*!< Port x Lock bit 11 */
+#define GPIO_LCKR_LCK12                      ((uint32_t)0x00001000)        /*!< Port x Lock bit 12 */
+#define GPIO_LCKR_LCK13                      ((uint32_t)0x00002000)        /*!< Port x Lock bit 13 */
+#define GPIO_LCKR_LCK14                      ((uint32_t)0x00004000)        /*!< Port x Lock bit 14 */
+#define GPIO_LCKR_LCK15                      ((uint32_t)0x00008000)        /*!< Port x Lock bit 15 */
+#define GPIO_LCKR_LCKK                       ((uint32_t)0x00010000)        /*!< Lock key */
+
+/*----------------------------------------------------------------------------*/
+
+/******************  Bit definition for AFIO_EVCR register  *******************/
+#define AFIO_EVCR_PIN                        ((uint8_t)0x0F)               /*!< PIN[3:0] bits (Pin selection) */
+#define AFIO_EVCR_PIN_0                      ((uint8_t)0x01)               /*!< Bit 0 */
+#define AFIO_EVCR_PIN_1                      ((uint8_t)0x02)               /*!< Bit 1 */
+#define AFIO_EVCR_PIN_2                      ((uint8_t)0x04)               /*!< Bit 2 */
+#define AFIO_EVCR_PIN_3                      ((uint8_t)0x08)               /*!< Bit 3 */
+
+/*!< PIN configuration */
+#define AFIO_EVCR_PIN_PX0                    ((uint8_t)0x00)               /*!< Pin 0 selected */
+#define AFIO_EVCR_PIN_PX1                    ((uint8_t)0x01)               /*!< Pin 1 selected */
+#define AFIO_EVCR_PIN_PX2                    ((uint8_t)0x02)               /*!< Pin 2 selected */
+#define AFIO_EVCR_PIN_PX3                    ((uint8_t)0x03)               /*!< Pin 3 selected */
+#define AFIO_EVCR_PIN_PX4                    ((uint8_t)0x04)               /*!< Pin 4 selected */
+#define AFIO_EVCR_PIN_PX5                    ((uint8_t)0x05)               /*!< Pin 5 selected */
+#define AFIO_EVCR_PIN_PX6                    ((uint8_t)0x06)               /*!< Pin 6 selected */
+#define AFIO_EVCR_PIN_PX7                    ((uint8_t)0x07)               /*!< Pin 7 selected */
+#define AFIO_EVCR_PIN_PX8                    ((uint8_t)0x08)               /*!< Pin 8 selected */
+#define AFIO_EVCR_PIN_PX9                    ((uint8_t)0x09)               /*!< Pin 9 selected */
+#define AFIO_EVCR_PIN_PX10                   ((uint8_t)0x0A)               /*!< Pin 10 selected */
+#define AFIO_EVCR_PIN_PX11                   ((uint8_t)0x0B)               /*!< Pin 11 selected */
+#define AFIO_EVCR_PIN_PX12                   ((uint8_t)0x0C)               /*!< Pin 12 selected */
+#define AFIO_EVCR_PIN_PX13                   ((uint8_t)0x0D)               /*!< Pin 13 selected */
+#define AFIO_EVCR_PIN_PX14                   ((uint8_t)0x0E)               /*!< Pin 14 selected */
+#define AFIO_EVCR_PIN_PX15                   ((uint8_t)0x0F)               /*!< Pin 15 selected */
+
+#define AFIO_EVCR_PORT                       ((uint8_t)0x70)               /*!< PORT[2:0] bits (Port selection) */
+#define AFIO_EVCR_PORT_0                     ((uint8_t)0x10)               /*!< Bit 0 */
+#define AFIO_EVCR_PORT_1                     ((uint8_t)0x20)               /*!< Bit 1 */
+#define AFIO_EVCR_PORT_2                     ((uint8_t)0x40)               /*!< Bit 2 */
+
+/*!< PORT configuration */
+#define AFIO_EVCR_PORT_PA                    ((uint8_t)0x00)               /*!< Port A selected */
+#define AFIO_EVCR_PORT_PB                    ((uint8_t)0x10)               /*!< Port B selected */
+#define AFIO_EVCR_PORT_PC                    ((uint8_t)0x20)               /*!< Port C selected */
+#define AFIO_EVCR_PORT_PD                    ((uint8_t)0x30)               /*!< Port D selected */
+#define AFIO_EVCR_PORT_PE                    ((uint8_t)0x40)               /*!< Port E selected */
+
+#define AFIO_EVCR_EVOE                       ((uint8_t)0x80)               /*!< Event Output Enable */
+
+/******************  Bit definition for AFIO_MAPR register  *******************/
+#define AFIO_MAPR_SPI1_REMAP                 ((uint32_t)0x00000001)        /*!< SPI1 remapping */
+#define AFIO_MAPR_I2C1_REMAP                 ((uint32_t)0x00000002)        /*!< I2C1 remapping */
+#define AFIO_MAPR_USART1_REMAP               ((uint32_t)0x00000004)        /*!< USART1 remapping */
+#define AFIO_MAPR_USART2_REMAP               ((uint32_t)0x00000008)        /*!< USART2 remapping */
+
+#define AFIO_MAPR_USART3_REMAP               ((uint32_t)0x00000030)        /*!< USART3_REMAP[1:0] bits (USART3 remapping) */
+#define AFIO_MAPR_USART3_REMAP_0             ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define AFIO_MAPR_USART3_REMAP_1             ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+/* USART3_REMAP configuration */
+#define AFIO_MAPR_USART3_REMAP_NOREMAP       ((uint32_t)0x00000000)        /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */
+#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP  ((uint32_t)0x00000010)        /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */
+#define AFIO_MAPR_USART3_REMAP_FULLREMAP     ((uint32_t)0x00000030)        /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */
+
+#define AFIO_MAPR_TIM1_REMAP                 ((uint32_t)0x000000C0)        /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */
+#define AFIO_MAPR_TIM1_REMAP_0               ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define AFIO_MAPR_TIM1_REMAP_1               ((uint32_t)0x00000080)        /*!< Bit 1 */
+
+/*!< TIM1_REMAP configuration */
+#define AFIO_MAPR_TIM1_REMAP_NOREMAP         ((uint32_t)0x00000000)        /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */
+#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP    ((uint32_t)0x00000040)        /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */
+#define AFIO_MAPR_TIM1_REMAP_FULLREMAP       ((uint32_t)0x000000C0)        /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */
+
+#define AFIO_MAPR_TIM2_REMAP                 ((uint32_t)0x00000300)        /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */
+#define AFIO_MAPR_TIM2_REMAP_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define AFIO_MAPR_TIM2_REMAP_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+
+/*!< TIM2_REMAP configuration */
+#define AFIO_MAPR_TIM2_REMAP_NOREMAP         ((uint32_t)0x00000000)        /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */
+#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1   ((uint32_t)0x00000100)        /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */
+#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2   ((uint32_t)0x00000200)        /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */
+#define AFIO_MAPR_TIM2_REMAP_FULLREMAP       ((uint32_t)0x00000300)        /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */
+
+#define AFIO_MAPR_TIM3_REMAP                 ((uint32_t)0x00000C00)        /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */
+#define AFIO_MAPR_TIM3_REMAP_0               ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define AFIO_MAPR_TIM3_REMAP_1               ((uint32_t)0x00000800)        /*!< Bit 1 */
+
+/*!< TIM3_REMAP configuration */
+#define AFIO_MAPR_TIM3_REMAP_NOREMAP         ((uint32_t)0x00000000)        /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */
+#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP    ((uint32_t)0x00000800)        /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */
+#define AFIO_MAPR_TIM3_REMAP_FULLREMAP       ((uint32_t)0x00000C00)        /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */
+
+#define AFIO_MAPR_TIM4_REMAP                 ((uint32_t)0x00001000)        /*!< TIM4_REMAP bit (TIM4 remapping) */
+
+#define AFIO_MAPR_CAN_REMAP                  ((uint32_t)0x00006000)        /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */
+#define AFIO_MAPR_CAN_REMAP_0                ((uint32_t)0x00002000)        /*!< Bit 0 */
+#define AFIO_MAPR_CAN_REMAP_1                ((uint32_t)0x00004000)        /*!< Bit 1 */
+
+/*!< CAN_REMAP configuration */
+#define AFIO_MAPR_CAN_REMAP_REMAP1           ((uint32_t)0x00000000)        /*!< CANRX mapped to PA11, CANTX mapped to PA12 */
+#define AFIO_MAPR_CAN_REMAP_REMAP2           ((uint32_t)0x00004000)        /*!< CANRX mapped to PB8, CANTX mapped to PB9 */
+#define AFIO_MAPR_CAN_REMAP_REMAP3           ((uint32_t)0x00006000)        /*!< CANRX mapped to PD0, CANTX mapped to PD1 */
+
+#define AFIO_MAPR_PD01_REMAP                 ((uint32_t)0x00008000)        /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
+#define AFIO_MAPR_TIM5CH4_IREMAP             ((uint32_t)0x00010000)        /*!< TIM5 Channel4 Internal Remap */
+#define AFIO_MAPR_ADC1_ETRGINJ_REMAP         ((uint32_t)0x00020000)        /*!< ADC 1 External Trigger Injected Conversion remapping */
+#define AFIO_MAPR_ADC1_ETRGREG_REMAP         ((uint32_t)0x00040000)        /*!< ADC 1 External Trigger Regular Conversion remapping */
+#define AFIO_MAPR_ADC2_ETRGINJ_REMAP         ((uint32_t)0x00080000)        /*!< ADC 2 External Trigger Injected Conversion remapping */
+#define AFIO_MAPR_ADC2_ETRGREG_REMAP         ((uint32_t)0x00100000)        /*!< ADC 2 External Trigger Regular Conversion remapping */
+
+/*!< SWJ_CFG configuration */
+#define AFIO_MAPR_SWJ_CFG                    ((uint32_t)0x07000000)        /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */
+#define AFIO_MAPR_SWJ_CFG_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define AFIO_MAPR_SWJ_CFG_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define AFIO_MAPR_SWJ_CFG_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+
+#define AFIO_MAPR_SWJ_CFG_RESET              ((uint32_t)0x00000000)        /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */
+#define AFIO_MAPR_SWJ_CFG_NOJNTRST           ((uint32_t)0x01000000)        /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */
+#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE        ((uint32_t)0x02000000)        /*!< JTAG-DP Disabled and SW-DP Enabled */
+#define AFIO_MAPR_SWJ_CFG_DISABLE            ((uint32_t)0x04000000)        /*!< JTAG-DP Disabled and SW-DP Disabled */
+
+#ifdef STM32F10X_CL
+/*!< ETH_REMAP configuration */
+ #define AFIO_MAPR_ETH_REMAP                  ((uint32_t)0x00200000)        /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */
+
+/*!< CAN2_REMAP configuration */
+ #define AFIO_MAPR_CAN2_REMAP                 ((uint32_t)0x00400000)        /*!< CAN2_REMAP bit (CAN2 I/O remapping) */
+
+/*!< MII_RMII_SEL configuration */
+ #define AFIO_MAPR_MII_RMII_SEL               ((uint32_t)0x00800000)        /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */
+
+/*!< SPI3_REMAP configuration */
+ #define AFIO_MAPR_SPI3_REMAP                 ((uint32_t)0x10000000)        /*!< SPI3_REMAP bit (SPI3 remapping) */
+
+/*!< TIM2ITR1_IREMAP configuration */
+ #define AFIO_MAPR_TIM2ITR1_IREMAP            ((uint32_t)0x20000000)        /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */
+
+/*!< PTP_PPS_REMAP configuration */
+ #define AFIO_MAPR_PTP_PPS_REMAP              ((uint32_t)0x40000000)        /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */
+#endif
+
+/*****************  Bit definition for AFIO_EXTICR1 register  *****************/
+#define AFIO_EXTICR1_EXTI0                   ((uint16_t)0x000F)            /*!< EXTI 0 configuration */
+#define AFIO_EXTICR1_EXTI1                   ((uint16_t)0x00F0)            /*!< EXTI 1 configuration */
+#define AFIO_EXTICR1_EXTI2                   ((uint16_t)0x0F00)            /*!< EXTI 2 configuration */
+#define AFIO_EXTICR1_EXTI3                   ((uint16_t)0xF000)            /*!< EXTI 3 configuration */
+
+/*!< EXTI0 configuration */
+#define AFIO_EXTICR1_EXTI0_PA                ((uint16_t)0x0000)            /*!< PA[0] pin */
+#define AFIO_EXTICR1_EXTI0_PB                ((uint16_t)0x0001)            /*!< PB[0] pin */
+#define AFIO_EXTICR1_EXTI0_PC                ((uint16_t)0x0002)            /*!< PC[0] pin */
+#define AFIO_EXTICR1_EXTI0_PD                ((uint16_t)0x0003)            /*!< PD[0] pin */
+#define AFIO_EXTICR1_EXTI0_PE                ((uint16_t)0x0004)            /*!< PE[0] pin */
+#define AFIO_EXTICR1_EXTI0_PF                ((uint16_t)0x0005)            /*!< PF[0] pin */
+#define AFIO_EXTICR1_EXTI0_PG                ((uint16_t)0x0006)            /*!< PG[0] pin */
+
+/*!< EXTI1 configuration */
+#define AFIO_EXTICR1_EXTI1_PA                ((uint16_t)0x0000)            /*!< PA[1] pin */
+#define AFIO_EXTICR1_EXTI1_PB                ((uint16_t)0x0010)            /*!< PB[1] pin */
+#define AFIO_EXTICR1_EXTI1_PC                ((uint16_t)0x0020)            /*!< PC[1] pin */
+#define AFIO_EXTICR1_EXTI1_PD                ((uint16_t)0x0030)            /*!< PD[1] pin */
+#define AFIO_EXTICR1_EXTI1_PE                ((uint16_t)0x0040)            /*!< PE[1] pin */
+#define AFIO_EXTICR1_EXTI1_PF                ((uint16_t)0x0050)            /*!< PF[1] pin */
+#define AFIO_EXTICR1_EXTI1_PG                ((uint16_t)0x0060)            /*!< PG[1] pin */
+
+/*!< EXTI2 configuration */  
+#define AFIO_EXTICR1_EXTI2_PA                ((uint16_t)0x0000)            /*!< PA[2] pin */
+#define AFIO_EXTICR1_EXTI2_PB                ((uint16_t)0x0100)            /*!< PB[2] pin */
+#define AFIO_EXTICR1_EXTI2_PC                ((uint16_t)0x0200)            /*!< PC[2] pin */
+#define AFIO_EXTICR1_EXTI2_PD                ((uint16_t)0x0300)            /*!< PD[2] pin */
+#define AFIO_EXTICR1_EXTI2_PE                ((uint16_t)0x0400)            /*!< PE[2] pin */
+#define AFIO_EXTICR1_EXTI2_PF                ((uint16_t)0x0500)            /*!< PF[2] pin */
+#define AFIO_EXTICR1_EXTI2_PG                ((uint16_t)0x0600)            /*!< PG[2] pin */
+
+/*!< EXTI3 configuration */
+#define AFIO_EXTICR1_EXTI3_PA                ((uint16_t)0x0000)            /*!< PA[3] pin */
+#define AFIO_EXTICR1_EXTI3_PB                ((uint16_t)0x1000)            /*!< PB[3] pin */
+#define AFIO_EXTICR1_EXTI3_PC                ((uint16_t)0x2000)            /*!< PC[3] pin */
+#define AFIO_EXTICR1_EXTI3_PD                ((uint16_t)0x3000)            /*!< PD[3] pin */
+#define AFIO_EXTICR1_EXTI3_PE                ((uint16_t)0x4000)            /*!< PE[3] pin */
+#define AFIO_EXTICR1_EXTI3_PF                ((uint16_t)0x5000)            /*!< PF[3] pin */
+#define AFIO_EXTICR1_EXTI3_PG                ((uint16_t)0x6000)            /*!< PG[3] pin */
+
+/*****************  Bit definition for AFIO_EXTICR2 register  *****************/
+#define AFIO_EXTICR2_EXTI4                   ((uint16_t)0x000F)            /*!< EXTI 4 configuration */
+#define AFIO_EXTICR2_EXTI5                   ((uint16_t)0x00F0)            /*!< EXTI 5 configuration */
+#define AFIO_EXTICR2_EXTI6                   ((uint16_t)0x0F00)            /*!< EXTI 6 configuration */
+#define AFIO_EXTICR2_EXTI7                   ((uint16_t)0xF000)            /*!< EXTI 7 configuration */
+
+/*!< EXTI4 configuration */
+#define AFIO_EXTICR2_EXTI4_PA                ((uint16_t)0x0000)            /*!< PA[4] pin */
+#define AFIO_EXTICR2_EXTI4_PB                ((uint16_t)0x0001)            /*!< PB[4] pin */
+#define AFIO_EXTICR2_EXTI4_PC                ((uint16_t)0x0002)            /*!< PC[4] pin */
+#define AFIO_EXTICR2_EXTI4_PD                ((uint16_t)0x0003)            /*!< PD[4] pin */
+#define AFIO_EXTICR2_EXTI4_PE                ((uint16_t)0x0004)            /*!< PE[4] pin */
+#define AFIO_EXTICR2_EXTI4_PF                ((uint16_t)0x0005)            /*!< PF[4] pin */
+#define AFIO_EXTICR2_EXTI4_PG                ((uint16_t)0x0006)            /*!< PG[4] pin */
+
+/* EXTI5 configuration */
+#define AFIO_EXTICR2_EXTI5_PA                ((uint16_t)0x0000)            /*!< PA[5] pin */
+#define AFIO_EXTICR2_EXTI5_PB                ((uint16_t)0x0010)            /*!< PB[5] pin */
+#define AFIO_EXTICR2_EXTI5_PC                ((uint16_t)0x0020)            /*!< PC[5] pin */
+#define AFIO_EXTICR2_EXTI5_PD                ((uint16_t)0x0030)            /*!< PD[5] pin */
+#define AFIO_EXTICR2_EXTI5_PE                ((uint16_t)0x0040)            /*!< PE[5] pin */
+#define AFIO_EXTICR2_EXTI5_PF                ((uint16_t)0x0050)            /*!< PF[5] pin */
+#define AFIO_EXTICR2_EXTI5_PG                ((uint16_t)0x0060)            /*!< PG[5] pin */
+
+/*!< EXTI6 configuration */  
+#define AFIO_EXTICR2_EXTI6_PA                ((uint16_t)0x0000)            /*!< PA[6] pin */
+#define AFIO_EXTICR2_EXTI6_PB                ((uint16_t)0x0100)            /*!< PB[6] pin */
+#define AFIO_EXTICR2_EXTI6_PC                ((uint16_t)0x0200)            /*!< PC[6] pin */
+#define AFIO_EXTICR2_EXTI6_PD                ((uint16_t)0x0300)            /*!< PD[6] pin */
+#define AFIO_EXTICR2_EXTI6_PE                ((uint16_t)0x0400)            /*!< PE[6] pin */
+#define AFIO_EXTICR2_EXTI6_PF                ((uint16_t)0x0500)            /*!< PF[6] pin */
+#define AFIO_EXTICR2_EXTI6_PG                ((uint16_t)0x0600)            /*!< PG[6] pin */
+
+/*!< EXTI7 configuration */
+#define AFIO_EXTICR2_EXTI7_PA                ((uint16_t)0x0000)            /*!< PA[7] pin */
+#define AFIO_EXTICR2_EXTI7_PB                ((uint16_t)0x1000)            /*!< PB[7] pin */
+#define AFIO_EXTICR2_EXTI7_PC                ((uint16_t)0x2000)            /*!< PC[7] pin */
+#define AFIO_EXTICR2_EXTI7_PD                ((uint16_t)0x3000)            /*!< PD[7] pin */
+#define AFIO_EXTICR2_EXTI7_PE                ((uint16_t)0x4000)            /*!< PE[7] pin */
+#define AFIO_EXTICR2_EXTI7_PF                ((uint16_t)0x5000)            /*!< PF[7] pin */
+#define AFIO_EXTICR2_EXTI7_PG                ((uint16_t)0x6000)            /*!< PG[7] pin */
+
+/*****************  Bit definition for AFIO_EXTICR3 register  *****************/
+#define AFIO_EXTICR3_EXTI8                   ((uint16_t)0x000F)            /*!< EXTI 8 configuration */
+#define AFIO_EXTICR3_EXTI9                   ((uint16_t)0x00F0)            /*!< EXTI 9 configuration */
+#define AFIO_EXTICR3_EXTI10                  ((uint16_t)0x0F00)            /*!< EXTI 10 configuration */
+#define AFIO_EXTICR3_EXTI11                  ((uint16_t)0xF000)            /*!< EXTI 11 configuration */
+
+/*!< EXTI8 configuration */
+#define AFIO_EXTICR3_EXTI8_PA                ((uint16_t)0x0000)            /*!< PA[8] pin */
+#define AFIO_EXTICR3_EXTI8_PB                ((uint16_t)0x0001)            /*!< PB[8] pin */
+#define AFIO_EXTICR3_EXTI8_PC                ((uint16_t)0x0002)            /*!< PC[8] pin */
+#define AFIO_EXTICR3_EXTI8_PD                ((uint16_t)0x0003)            /*!< PD[8] pin */
+#define AFIO_EXTICR3_EXTI8_PE                ((uint16_t)0x0004)            /*!< PE[8] pin */
+#define AFIO_EXTICR3_EXTI8_PF                ((uint16_t)0x0005)            /*!< PF[8] pin */
+#define AFIO_EXTICR3_EXTI8_PG                ((uint16_t)0x0006)            /*!< PG[8] pin */
+
+/*!< EXTI9 configuration */
+#define AFIO_EXTICR3_EXTI9_PA                ((uint16_t)0x0000)            /*!< PA[9] pin */
+#define AFIO_EXTICR3_EXTI9_PB                ((uint16_t)0x0010)            /*!< PB[9] pin */
+#define AFIO_EXTICR3_EXTI9_PC                ((uint16_t)0x0020)            /*!< PC[9] pin */
+#define AFIO_EXTICR3_EXTI9_PD                ((uint16_t)0x0030)            /*!< PD[9] pin */
+#define AFIO_EXTICR3_EXTI9_PE                ((uint16_t)0x0040)            /*!< PE[9] pin */
+#define AFIO_EXTICR3_EXTI9_PF                ((uint16_t)0x0050)            /*!< PF[9] pin */
+#define AFIO_EXTICR3_EXTI9_PG                ((uint16_t)0x0060)            /*!< PG[9] pin */
+
+/*!< EXTI10 configuration */  
+#define AFIO_EXTICR3_EXTI10_PA               ((uint16_t)0x0000)            /*!< PA[10] pin */
+#define AFIO_EXTICR3_EXTI10_PB               ((uint16_t)0x0100)            /*!< PB[10] pin */
+#define AFIO_EXTICR3_EXTI10_PC               ((uint16_t)0x0200)            /*!< PC[10] pin */
+#define AFIO_EXTICR3_EXTI10_PD               ((uint16_t)0x0300)            /*!< PD[10] pin */
+#define AFIO_EXTICR3_EXTI10_PE               ((uint16_t)0x0400)            /*!< PE[10] pin */
+#define AFIO_EXTICR3_EXTI10_PF               ((uint16_t)0x0500)            /*!< PF[10] pin */
+#define AFIO_EXTICR3_EXTI10_PG               ((uint16_t)0x0600)            /*!< PG[10] pin */
+
+/*!< EXTI11 configuration */
+#define AFIO_EXTICR3_EXTI11_PA               ((uint16_t)0x0000)            /*!< PA[11] pin */
+#define AFIO_EXTICR3_EXTI11_PB               ((uint16_t)0x1000)            /*!< PB[11] pin */
+#define AFIO_EXTICR3_EXTI11_PC               ((uint16_t)0x2000)            /*!< PC[11] pin */
+#define AFIO_EXTICR3_EXTI11_PD               ((uint16_t)0x3000)            /*!< PD[11] pin */
+#define AFIO_EXTICR3_EXTI11_PE               ((uint16_t)0x4000)            /*!< PE[11] pin */
+#define AFIO_EXTICR3_EXTI11_PF               ((uint16_t)0x5000)            /*!< PF[11] pin */
+#define AFIO_EXTICR3_EXTI11_PG               ((uint16_t)0x6000)            /*!< PG[11] pin */
+
+/*****************  Bit definition for AFIO_EXTICR4 register  *****************/
+#define AFIO_EXTICR4_EXTI12                  ((uint16_t)0x000F)            /*!< EXTI 12 configuration */
+#define AFIO_EXTICR4_EXTI13                  ((uint16_t)0x00F0)            /*!< EXTI 13 configuration */
+#define AFIO_EXTICR4_EXTI14                  ((uint16_t)0x0F00)            /*!< EXTI 14 configuration */
+#define AFIO_EXTICR4_EXTI15                  ((uint16_t)0xF000)            /*!< EXTI 15 configuration */
+
+/* EXTI12 configuration */
+#define AFIO_EXTICR4_EXTI12_PA               ((uint16_t)0x0000)            /*!< PA[12] pin */
+#define AFIO_EXTICR4_EXTI12_PB               ((uint16_t)0x0001)            /*!< PB[12] pin */
+#define AFIO_EXTICR4_EXTI12_PC               ((uint16_t)0x0002)            /*!< PC[12] pin */
+#define AFIO_EXTICR4_EXTI12_PD               ((uint16_t)0x0003)            /*!< PD[12] pin */
+#define AFIO_EXTICR4_EXTI12_PE               ((uint16_t)0x0004)            /*!< PE[12] pin */
+#define AFIO_EXTICR4_EXTI12_PF               ((uint16_t)0x0005)            /*!< PF[12] pin */
+#define AFIO_EXTICR4_EXTI12_PG               ((uint16_t)0x0006)            /*!< PG[12] pin */
+
+/* EXTI13 configuration */
+#define AFIO_EXTICR4_EXTI13_PA               ((uint16_t)0x0000)            /*!< PA[13] pin */
+#define AFIO_EXTICR4_EXTI13_PB               ((uint16_t)0x0010)            /*!< PB[13] pin */
+#define AFIO_EXTICR4_EXTI13_PC               ((uint16_t)0x0020)            /*!< PC[13] pin */
+#define AFIO_EXTICR4_EXTI13_PD               ((uint16_t)0x0030)            /*!< PD[13] pin */
+#define AFIO_EXTICR4_EXTI13_PE               ((uint16_t)0x0040)            /*!< PE[13] pin */
+#define AFIO_EXTICR4_EXTI13_PF               ((uint16_t)0x0050)            /*!< PF[13] pin */
+#define AFIO_EXTICR4_EXTI13_PG               ((uint16_t)0x0060)            /*!< PG[13] pin */
+
+/*!< EXTI14 configuration */  
+#define AFIO_EXTICR4_EXTI14_PA               ((uint16_t)0x0000)            /*!< PA[14] pin */
+#define AFIO_EXTICR4_EXTI14_PB               ((uint16_t)0x0100)            /*!< PB[14] pin */
+#define AFIO_EXTICR4_EXTI14_PC               ((uint16_t)0x0200)            /*!< PC[14] pin */
+#define AFIO_EXTICR4_EXTI14_PD               ((uint16_t)0x0300)            /*!< PD[14] pin */
+#define AFIO_EXTICR4_EXTI14_PE               ((uint16_t)0x0400)            /*!< PE[14] pin */
+#define AFIO_EXTICR4_EXTI14_PF               ((uint16_t)0x0500)            /*!< PF[14] pin */
+#define AFIO_EXTICR4_EXTI14_PG               ((uint16_t)0x0600)            /*!< PG[14] pin */
+
+/*!< EXTI15 configuration */
+#define AFIO_EXTICR4_EXTI15_PA               ((uint16_t)0x0000)            /*!< PA[15] pin */
+#define AFIO_EXTICR4_EXTI15_PB               ((uint16_t)0x1000)            /*!< PB[15] pin */
+#define AFIO_EXTICR4_EXTI15_PC               ((uint16_t)0x2000)            /*!< PC[15] pin */
+#define AFIO_EXTICR4_EXTI15_PD               ((uint16_t)0x3000)            /*!< PD[15] pin */
+#define AFIO_EXTICR4_EXTI15_PE               ((uint16_t)0x4000)            /*!< PE[15] pin */
+#define AFIO_EXTICR4_EXTI15_PF               ((uint16_t)0x5000)            /*!< PF[15] pin */
+#define AFIO_EXTICR4_EXTI15_PG               ((uint16_t)0x6000)            /*!< PG[15] pin */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+/******************  Bit definition for AFIO_MAPR2 register  ******************/
+#define AFIO_MAPR2_TIM15_REMAP               ((uint32_t)0x00000001)        /*!< TIM15 remapping */
+#define AFIO_MAPR2_TIM16_REMAP               ((uint32_t)0x00000002)        /*!< TIM16 remapping */
+#define AFIO_MAPR2_TIM17_REMAP               ((uint32_t)0x00000004)        /*!< TIM17 remapping */
+#define AFIO_MAPR2_CEC_REMAP                 ((uint32_t)0x00000008)        /*!< CEC remapping */
+#define AFIO_MAPR2_TIM1_DMA_REMAP            ((uint32_t)0x00000010)        /*!< TIM1_DMA remapping */
+#endif
+
+#ifdef STM32F10X_HD_VL
+#define AFIO_MAPR2_TIM13_REMAP               ((uint32_t)0x00000100)        /*!< TIM13 remapping */
+#define AFIO_MAPR2_TIM14_REMAP               ((uint32_t)0x00000200)        /*!< TIM14 remapping */
+#define AFIO_MAPR2_FSMC_NADV_REMAP           ((uint32_t)0x00000400)        /*!< FSMC NADV remapping */
+#define AFIO_MAPR2_TIM67_DAC_DMA_REMAP       ((uint32_t)0x00000800)        /*!< TIM6/TIM7 and DAC DMA remapping */
+#define AFIO_MAPR2_TIM12_REMAP               ((uint32_t)0x00001000)        /*!< TIM12 remapping */
+#define AFIO_MAPR2_MISC_REMAP                ((uint32_t)0x00002000)        /*!< Miscellaneous remapping */
+#endif
+
+#ifdef STM32F10X_XL 
+/******************  Bit definition for AFIO_MAPR2 register  ******************/
+#define AFIO_MAPR2_TIM9_REMAP                ((uint32_t)0x00000020)        /*!< TIM9 remapping */
+#define AFIO_MAPR2_TIM10_REMAP               ((uint32_t)0x00000040)        /*!< TIM10 remapping */
+#define AFIO_MAPR2_TIM11_REMAP               ((uint32_t)0x00000080)        /*!< TIM11 remapping */
+#define AFIO_MAPR2_TIM13_REMAP               ((uint32_t)0x00000100)        /*!< TIM13 remapping */
+#define AFIO_MAPR2_TIM14_REMAP               ((uint32_t)0x00000200)        /*!< TIM14 remapping */
+#define AFIO_MAPR2_FSMC_NADV_REMAP           ((uint32_t)0x00000400)        /*!< FSMC NADV remapping */
+#endif
+
+/******************************************************************************/
+/*                                                                            */
+/*                               SystemTick                                   */
+/*                                                                            */
+/******************************************************************************/
+
+/*****************  Bit definition for SysTick_CTRL register  *****************/
+#define  SysTick_CTRL_ENABLE                 ((uint32_t)0x00000001)        /*!< Counter enable */
+#define  SysTick_CTRL_TICKINT                ((uint32_t)0x00000002)        /*!< Counting down to 0 pends the SysTick handler */
+#define  SysTick_CTRL_CLKSOURCE              ((uint32_t)0x00000004)        /*!< Clock source */
+#define  SysTick_CTRL_COUNTFLAG              ((uint32_t)0x00010000)        /*!< Count Flag */
+
+/*****************  Bit definition for SysTick_LOAD register  *****************/
+#define  SysTick_LOAD_RELOAD                 ((uint32_t)0x00FFFFFF)        /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */
+
+/*****************  Bit definition for SysTick_VAL register  ******************/
+#define  SysTick_VAL_CURRENT                 ((uint32_t)0x00FFFFFF)        /*!< Current value at the time the register is accessed */
+
+/*****************  Bit definition for SysTick_CALIB register  ****************/
+#define  SysTick_CALIB_TENMS                 ((uint32_t)0x00FFFFFF)        /*!< Reload value to use for 10ms timing */
+#define  SysTick_CALIB_SKEW                  ((uint32_t)0x40000000)        /*!< Calibration value is not exactly 10 ms */
+#define  SysTick_CALIB_NOREF                 ((uint32_t)0x80000000)        /*!< The reference clock is not provided */
+
+/******************************************************************************/
+/*                                                                            */
+/*                  Nested Vectored Interrupt Controller                      */
+/*                                                                            */
+/******************************************************************************/
+
+/******************  Bit definition for NVIC_ISER register  *******************/
+#define  NVIC_ISER_SETENA                    ((uint32_t)0xFFFFFFFF)        /*!< Interrupt set enable bits */
+#define  NVIC_ISER_SETENA_0                  ((uint32_t)0x00000001)        /*!< bit 0 */
+#define  NVIC_ISER_SETENA_1                  ((uint32_t)0x00000002)        /*!< bit 1 */
+#define  NVIC_ISER_SETENA_2                  ((uint32_t)0x00000004)        /*!< bit 2 */
+#define  NVIC_ISER_SETENA_3                  ((uint32_t)0x00000008)        /*!< bit 3 */
+#define  NVIC_ISER_SETENA_4                  ((uint32_t)0x00000010)        /*!< bit 4 */
+#define  NVIC_ISER_SETENA_5                  ((uint32_t)0x00000020)        /*!< bit 5 */
+#define  NVIC_ISER_SETENA_6                  ((uint32_t)0x00000040)        /*!< bit 6 */
+#define  NVIC_ISER_SETENA_7                  ((uint32_t)0x00000080)        /*!< bit 7 */
+#define  NVIC_ISER_SETENA_8                  ((uint32_t)0x00000100)        /*!< bit 8 */
+#define  NVIC_ISER_SETENA_9                  ((uint32_t)0x00000200)        /*!< bit 9 */
+#define  NVIC_ISER_SETENA_10                 ((uint32_t)0x00000400)        /*!< bit 10 */
+#define  NVIC_ISER_SETENA_11                 ((uint32_t)0x00000800)        /*!< bit 11 */
+#define  NVIC_ISER_SETENA_12                 ((uint32_t)0x00001000)        /*!< bit 12 */
+#define  NVIC_ISER_SETENA_13                 ((uint32_t)0x00002000)        /*!< bit 13 */
+#define  NVIC_ISER_SETENA_14                 ((uint32_t)0x00004000)        /*!< bit 14 */
+#define  NVIC_ISER_SETENA_15                 ((uint32_t)0x00008000)        /*!< bit 15 */
+#define  NVIC_ISER_SETENA_16                 ((uint32_t)0x00010000)        /*!< bit 16 */
+#define  NVIC_ISER_SETENA_17                 ((uint32_t)0x00020000)        /*!< bit 17 */
+#define  NVIC_ISER_SETENA_18                 ((uint32_t)0x00040000)        /*!< bit 18 */
+#define  NVIC_ISER_SETENA_19                 ((uint32_t)0x00080000)        /*!< bit 19 */
+#define  NVIC_ISER_SETENA_20                 ((uint32_t)0x00100000)        /*!< bit 20 */
+#define  NVIC_ISER_SETENA_21                 ((uint32_t)0x00200000)        /*!< bit 21 */
+#define  NVIC_ISER_SETENA_22                 ((uint32_t)0x00400000)        /*!< bit 22 */
+#define  NVIC_ISER_SETENA_23                 ((uint32_t)0x00800000)        /*!< bit 23 */
+#define  NVIC_ISER_SETENA_24                 ((uint32_t)0x01000000)        /*!< bit 24 */
+#define  NVIC_ISER_SETENA_25                 ((uint32_t)0x02000000)        /*!< bit 25 */
+#define  NVIC_ISER_SETENA_26                 ((uint32_t)0x04000000)        /*!< bit 26 */
+#define  NVIC_ISER_SETENA_27                 ((uint32_t)0x08000000)        /*!< bit 27 */
+#define  NVIC_ISER_SETENA_28                 ((uint32_t)0x10000000)        /*!< bit 28 */
+#define  NVIC_ISER_SETENA_29                 ((uint32_t)0x20000000)        /*!< bit 29 */
+#define  NVIC_ISER_SETENA_30                 ((uint32_t)0x40000000)        /*!< bit 30 */
+#define  NVIC_ISER_SETENA_31                 ((uint32_t)0x80000000)        /*!< bit 31 */
+
+/******************  Bit definition for NVIC_ICER register  *******************/
+#define  NVIC_ICER_CLRENA                   ((uint32_t)0xFFFFFFFF)        /*!< Interrupt clear-enable bits */
+#define  NVIC_ICER_CLRENA_0                  ((uint32_t)0x00000001)        /*!< bit 0 */
+#define  NVIC_ICER_CLRENA_1                  ((uint32_t)0x00000002)        /*!< bit 1 */
+#define  NVIC_ICER_CLRENA_2                  ((uint32_t)0x00000004)        /*!< bit 2 */
+#define  NVIC_ICER_CLRENA_3                  ((uint32_t)0x00000008)        /*!< bit 3 */
+#define  NVIC_ICER_CLRENA_4                  ((uint32_t)0x00000010)        /*!< bit 4 */
+#define  NVIC_ICER_CLRENA_5                  ((uint32_t)0x00000020)        /*!< bit 5 */
+#define  NVIC_ICER_CLRENA_6                  ((uint32_t)0x00000040)        /*!< bit 6 */
+#define  NVIC_ICER_CLRENA_7                  ((uint32_t)0x00000080)        /*!< bit 7 */
+#define  NVIC_ICER_CLRENA_8                  ((uint32_t)0x00000100)        /*!< bit 8 */
+#define  NVIC_ICER_CLRENA_9                  ((uint32_t)0x00000200)        /*!< bit 9 */
+#define  NVIC_ICER_CLRENA_10                 ((uint32_t)0x00000400)        /*!< bit 10 */
+#define  NVIC_ICER_CLRENA_11                 ((uint32_t)0x00000800)        /*!< bit 11 */
+#define  NVIC_ICER_CLRENA_12                 ((uint32_t)0x00001000)        /*!< bit 12 */
+#define  NVIC_ICER_CLRENA_13                 ((uint32_t)0x00002000)        /*!< bit 13 */
+#define  NVIC_ICER_CLRENA_14                 ((uint32_t)0x00004000)        /*!< bit 14 */
+#define  NVIC_ICER_CLRENA_15                 ((uint32_t)0x00008000)        /*!< bit 15 */
+#define  NVIC_ICER_CLRENA_16                 ((uint32_t)0x00010000)        /*!< bit 16 */
+#define  NVIC_ICER_CLRENA_17                 ((uint32_t)0x00020000)        /*!< bit 17 */
+#define  NVIC_ICER_CLRENA_18                 ((uint32_t)0x00040000)        /*!< bit 18 */
+#define  NVIC_ICER_CLRENA_19                 ((uint32_t)0x00080000)        /*!< bit 19 */
+#define  NVIC_ICER_CLRENA_20                 ((uint32_t)0x00100000)        /*!< bit 20 */
+#define  NVIC_ICER_CLRENA_21                 ((uint32_t)0x00200000)        /*!< bit 21 */
+#define  NVIC_ICER_CLRENA_22                 ((uint32_t)0x00400000)        /*!< bit 22 */
+#define  NVIC_ICER_CLRENA_23                 ((uint32_t)0x00800000)        /*!< bit 23 */
+#define  NVIC_ICER_CLRENA_24                 ((uint32_t)0x01000000)        /*!< bit 24 */
+#define  NVIC_ICER_CLRENA_25                 ((uint32_t)0x02000000)        /*!< bit 25 */
+#define  NVIC_ICER_CLRENA_26                 ((uint32_t)0x04000000)        /*!< bit 26 */
+#define  NVIC_ICER_CLRENA_27                 ((uint32_t)0x08000000)        /*!< bit 27 */
+#define  NVIC_ICER_CLRENA_28                 ((uint32_t)0x10000000)        /*!< bit 28 */
+#define  NVIC_ICER_CLRENA_29                 ((uint32_t)0x20000000)        /*!< bit 29 */
+#define  NVIC_ICER_CLRENA_30                 ((uint32_t)0x40000000)        /*!< bit 30 */
+#define  NVIC_ICER_CLRENA_31                 ((uint32_t)0x80000000)        /*!< bit 31 */
+
+/******************  Bit definition for NVIC_ISPR register  *******************/
+#define  NVIC_ISPR_SETPEND                   ((uint32_t)0xFFFFFFFF)        /*!< Interrupt set-pending bits */
+#define  NVIC_ISPR_SETPEND_0                 ((uint32_t)0x00000001)        /*!< bit 0 */
+#define  NVIC_ISPR_SETPEND_1                 ((uint32_t)0x00000002)        /*!< bit 1 */
+#define  NVIC_ISPR_SETPEND_2                 ((uint32_t)0x00000004)        /*!< bit 2 */
+#define  NVIC_ISPR_SETPEND_3                 ((uint32_t)0x00000008)        /*!< bit 3 */
+#define  NVIC_ISPR_SETPEND_4                 ((uint32_t)0x00000010)        /*!< bit 4 */
+#define  NVIC_ISPR_SETPEND_5                 ((uint32_t)0x00000020)        /*!< bit 5 */
+#define  NVIC_ISPR_SETPEND_6                 ((uint32_t)0x00000040)        /*!< bit 6 */
+#define  NVIC_ISPR_SETPEND_7                 ((uint32_t)0x00000080)        /*!< bit 7 */
+#define  NVIC_ISPR_SETPEND_8                 ((uint32_t)0x00000100)        /*!< bit 8 */
+#define  NVIC_ISPR_SETPEND_9                 ((uint32_t)0x00000200)        /*!< bit 9 */
+#define  NVIC_ISPR_SETPEND_10                ((uint32_t)0x00000400)        /*!< bit 10 */
+#define  NVIC_ISPR_SETPEND_11                ((uint32_t)0x00000800)        /*!< bit 11 */
+#define  NVIC_ISPR_SETPEND_12                ((uint32_t)0x00001000)        /*!< bit 12 */
+#define  NVIC_ISPR_SETPEND_13                ((uint32_t)0x00002000)        /*!< bit 13 */
+#define  NVIC_ISPR_SETPEND_14                ((uint32_t)0x00004000)        /*!< bit 14 */
+#define  NVIC_ISPR_SETPEND_15                ((uint32_t)0x00008000)        /*!< bit 15 */
+#define  NVIC_ISPR_SETPEND_16                ((uint32_t)0x00010000)        /*!< bit 16 */
+#define  NVIC_ISPR_SETPEND_17                ((uint32_t)0x00020000)        /*!< bit 17 */
+#define  NVIC_ISPR_SETPEND_18                ((uint32_t)0x00040000)        /*!< bit 18 */
+#define  NVIC_ISPR_SETPEND_19                ((uint32_t)0x00080000)        /*!< bit 19 */
+#define  NVIC_ISPR_SETPEND_20                ((uint32_t)0x00100000)        /*!< bit 20 */
+#define  NVIC_ISPR_SETPEND_21                ((uint32_t)0x00200000)        /*!< bit 21 */
+#define  NVIC_ISPR_SETPEND_22                ((uint32_t)0x00400000)        /*!< bit 22 */
+#define  NVIC_ISPR_SETPEND_23                ((uint32_t)0x00800000)        /*!< bit 23 */
+#define  NVIC_ISPR_SETPEND_24                ((uint32_t)0x01000000)        /*!< bit 24 */
+#define  NVIC_ISPR_SETPEND_25                ((uint32_t)0x02000000)        /*!< bit 25 */
+#define  NVIC_ISPR_SETPEND_26                ((uint32_t)0x04000000)        /*!< bit 26 */
+#define  NVIC_ISPR_SETPEND_27                ((uint32_t)0x08000000)        /*!< bit 27 */
+#define  NVIC_ISPR_SETPEND_28                ((uint32_t)0x10000000)        /*!< bit 28 */
+#define  NVIC_ISPR_SETPEND_29                ((uint32_t)0x20000000)        /*!< bit 29 */
+#define  NVIC_ISPR_SETPEND_30                ((uint32_t)0x40000000)        /*!< bit 30 */
+#define  NVIC_ISPR_SETPEND_31                ((uint32_t)0x80000000)        /*!< bit 31 */
+
+/******************  Bit definition for NVIC_ICPR register  *******************/
+#define  NVIC_ICPR_CLRPEND                   ((uint32_t)0xFFFFFFFF)        /*!< Interrupt clear-pending bits */
+#define  NVIC_ICPR_CLRPEND_0                 ((uint32_t)0x00000001)        /*!< bit 0 */
+#define  NVIC_ICPR_CLRPEND_1                 ((uint32_t)0x00000002)        /*!< bit 1 */
+#define  NVIC_ICPR_CLRPEND_2                 ((uint32_t)0x00000004)        /*!< bit 2 */
+#define  NVIC_ICPR_CLRPEND_3                 ((uint32_t)0x00000008)        /*!< bit 3 */
+#define  NVIC_ICPR_CLRPEND_4                 ((uint32_t)0x00000010)        /*!< bit 4 */
+#define  NVIC_ICPR_CLRPEND_5                 ((uint32_t)0x00000020)        /*!< bit 5 */
+#define  NVIC_ICPR_CLRPEND_6                 ((uint32_t)0x00000040)        /*!< bit 6 */
+#define  NVIC_ICPR_CLRPEND_7                 ((uint32_t)0x00000080)        /*!< bit 7 */
+#define  NVIC_ICPR_CLRPEND_8                 ((uint32_t)0x00000100)        /*!< bit 8 */
+#define  NVIC_ICPR_CLRPEND_9                 ((uint32_t)0x00000200)        /*!< bit 9 */
+#define  NVIC_ICPR_CLRPEND_10                ((uint32_t)0x00000400)        /*!< bit 10 */
+#define  NVIC_ICPR_CLRPEND_11                ((uint32_t)0x00000800)        /*!< bit 11 */
+#define  NVIC_ICPR_CLRPEND_12                ((uint32_t)0x00001000)        /*!< bit 12 */
+#define  NVIC_ICPR_CLRPEND_13                ((uint32_t)0x00002000)        /*!< bit 13 */
+#define  NVIC_ICPR_CLRPEND_14                ((uint32_t)0x00004000)        /*!< bit 14 */
+#define  NVIC_ICPR_CLRPEND_15                ((uint32_t)0x00008000)        /*!< bit 15 */
+#define  NVIC_ICPR_CLRPEND_16                ((uint32_t)0x00010000)        /*!< bit 16 */
+#define  NVIC_ICPR_CLRPEND_17                ((uint32_t)0x00020000)        /*!< bit 17 */
+#define  NVIC_ICPR_CLRPEND_18                ((uint32_t)0x00040000)        /*!< bit 18 */
+#define  NVIC_ICPR_CLRPEND_19                ((uint32_t)0x00080000)        /*!< bit 19 */
+#define  NVIC_ICPR_CLRPEND_20                ((uint32_t)0x00100000)        /*!< bit 20 */
+#define  NVIC_ICPR_CLRPEND_21                ((uint32_t)0x00200000)        /*!< bit 21 */
+#define  NVIC_ICPR_CLRPEND_22                ((uint32_t)0x00400000)        /*!< bit 22 */
+#define  NVIC_ICPR_CLRPEND_23                ((uint32_t)0x00800000)        /*!< bit 23 */
+#define  NVIC_ICPR_CLRPEND_24                ((uint32_t)0x01000000)        /*!< bit 24 */
+#define  NVIC_ICPR_CLRPEND_25                ((uint32_t)0x02000000)        /*!< bit 25 */
+#define  NVIC_ICPR_CLRPEND_26                ((uint32_t)0x04000000)        /*!< bit 26 */
+#define  NVIC_ICPR_CLRPEND_27                ((uint32_t)0x08000000)        /*!< bit 27 */
+#define  NVIC_ICPR_CLRPEND_28                ((uint32_t)0x10000000)        /*!< bit 28 */
+#define  NVIC_ICPR_CLRPEND_29                ((uint32_t)0x20000000)        /*!< bit 29 */
+#define  NVIC_ICPR_CLRPEND_30                ((uint32_t)0x40000000)        /*!< bit 30 */
+#define  NVIC_ICPR_CLRPEND_31                ((uint32_t)0x80000000)        /*!< bit 31 */
+
+/******************  Bit definition for NVIC_IABR register  *******************/
+#define  NVIC_IABR_ACTIVE                    ((uint32_t)0xFFFFFFFF)        /*!< Interrupt active flags */
+#define  NVIC_IABR_ACTIVE_0                  ((uint32_t)0x00000001)        /*!< bit 0 */
+#define  NVIC_IABR_ACTIVE_1                  ((uint32_t)0x00000002)        /*!< bit 1 */
+#define  NVIC_IABR_ACTIVE_2                  ((uint32_t)0x00000004)        /*!< bit 2 */
+#define  NVIC_IABR_ACTIVE_3                  ((uint32_t)0x00000008)        /*!< bit 3 */
+#define  NVIC_IABR_ACTIVE_4                  ((uint32_t)0x00000010)        /*!< bit 4 */
+#define  NVIC_IABR_ACTIVE_5                  ((uint32_t)0x00000020)        /*!< bit 5 */
+#define  NVIC_IABR_ACTIVE_6                  ((uint32_t)0x00000040)        /*!< bit 6 */
+#define  NVIC_IABR_ACTIVE_7                  ((uint32_t)0x00000080)        /*!< bit 7 */
+#define  NVIC_IABR_ACTIVE_8                  ((uint32_t)0x00000100)        /*!< bit 8 */
+#define  NVIC_IABR_ACTIVE_9                  ((uint32_t)0x00000200)        /*!< bit 9 */
+#define  NVIC_IABR_ACTIVE_10                 ((uint32_t)0x00000400)        /*!< bit 10 */
+#define  NVIC_IABR_ACTIVE_11                 ((uint32_t)0x00000800)        /*!< bit 11 */
+#define  NVIC_IABR_ACTIVE_12                 ((uint32_t)0x00001000)        /*!< bit 12 */
+#define  NVIC_IABR_ACTIVE_13                 ((uint32_t)0x00002000)        /*!< bit 13 */
+#define  NVIC_IABR_ACTIVE_14                 ((uint32_t)0x00004000)        /*!< bit 14 */
+#define  NVIC_IABR_ACTIVE_15                 ((uint32_t)0x00008000)        /*!< bit 15 */
+#define  NVIC_IABR_ACTIVE_16                 ((uint32_t)0x00010000)        /*!< bit 16 */
+#define  NVIC_IABR_ACTIVE_17                 ((uint32_t)0x00020000)        /*!< bit 17 */
+#define  NVIC_IABR_ACTIVE_18                 ((uint32_t)0x00040000)        /*!< bit 18 */
+#define  NVIC_IABR_ACTIVE_19                 ((uint32_t)0x00080000)        /*!< bit 19 */
+#define  NVIC_IABR_ACTIVE_20                 ((uint32_t)0x00100000)        /*!< bit 20 */
+#define  NVIC_IABR_ACTIVE_21                 ((uint32_t)0x00200000)        /*!< bit 21 */
+#define  NVIC_IABR_ACTIVE_22                 ((uint32_t)0x00400000)        /*!< bit 22 */
+#define  NVIC_IABR_ACTIVE_23                 ((uint32_t)0x00800000)        /*!< bit 23 */
+#define  NVIC_IABR_ACTIVE_24                 ((uint32_t)0x01000000)        /*!< bit 24 */
+#define  NVIC_IABR_ACTIVE_25                 ((uint32_t)0x02000000)        /*!< bit 25 */
+#define  NVIC_IABR_ACTIVE_26                 ((uint32_t)0x04000000)        /*!< bit 26 */
+#define  NVIC_IABR_ACTIVE_27                 ((uint32_t)0x08000000)        /*!< bit 27 */
+#define  NVIC_IABR_ACTIVE_28                 ((uint32_t)0x10000000)        /*!< bit 28 */
+#define  NVIC_IABR_ACTIVE_29                 ((uint32_t)0x20000000)        /*!< bit 29 */
+#define  NVIC_IABR_ACTIVE_30                 ((uint32_t)0x40000000)        /*!< bit 30 */
+#define  NVIC_IABR_ACTIVE_31                 ((uint32_t)0x80000000)        /*!< bit 31 */
+
+/******************  Bit definition for NVIC_PRI0 register  *******************/
+#define  NVIC_IPR0_PRI_0                     ((uint32_t)0x000000FF)        /*!< Priority of interrupt 0 */
+#define  NVIC_IPR0_PRI_1                     ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 1 */
+#define  NVIC_IPR0_PRI_2                     ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 2 */
+#define  NVIC_IPR0_PRI_3                     ((uint32_t)0xFF000000)        /*!< Priority of interrupt 3 */
+
+/******************  Bit definition for NVIC_PRI1 register  *******************/
+#define  NVIC_IPR1_PRI_4                     ((uint32_t)0x000000FF)        /*!< Priority of interrupt 4 */
+#define  NVIC_IPR1_PRI_5                     ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 5 */
+#define  NVIC_IPR1_PRI_6                     ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 6 */
+#define  NVIC_IPR1_PRI_7                     ((uint32_t)0xFF000000)        /*!< Priority of interrupt 7 */
+
+/******************  Bit definition for NVIC_PRI2 register  *******************/
+#define  NVIC_IPR2_PRI_8                     ((uint32_t)0x000000FF)        /*!< Priority of interrupt 8 */
+#define  NVIC_IPR2_PRI_9                     ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 9 */
+#define  NVIC_IPR2_PRI_10                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 10 */
+#define  NVIC_IPR2_PRI_11                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 11 */
+
+/******************  Bit definition for NVIC_PRI3 register  *******************/
+#define  NVIC_IPR3_PRI_12                    ((uint32_t)0x000000FF)        /*!< Priority of interrupt 12 */
+#define  NVIC_IPR3_PRI_13                    ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 13 */
+#define  NVIC_IPR3_PRI_14                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 14 */
+#define  NVIC_IPR3_PRI_15                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 15 */
+
+/******************  Bit definition for NVIC_PRI4 register  *******************/
+#define  NVIC_IPR4_PRI_16                    ((uint32_t)0x000000FF)        /*!< Priority of interrupt 16 */
+#define  NVIC_IPR4_PRI_17                    ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 17 */
+#define  NVIC_IPR4_PRI_18                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 18 */
+#define  NVIC_IPR4_PRI_19                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 19 */
+
+/******************  Bit definition for NVIC_PRI5 register  *******************/
+#define  NVIC_IPR5_PRI_20                    ((uint32_t)0x000000FF)        /*!< Priority of interrupt 20 */
+#define  NVIC_IPR5_PRI_21                    ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 21 */
+#define  NVIC_IPR5_PRI_22                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 22 */
+#define  NVIC_IPR5_PRI_23                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 23 */
+
+/******************  Bit definition for NVIC_PRI6 register  *******************/
+#define  NVIC_IPR6_PRI_24                    ((uint32_t)0x000000FF)        /*!< Priority of interrupt 24 */
+#define  NVIC_IPR6_PRI_25                    ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 25 */
+#define  NVIC_IPR6_PRI_26                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 26 */
+#define  NVIC_IPR6_PRI_27                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 27 */
+
+/******************  Bit definition for NVIC_PRI7 register  *******************/
+#define  NVIC_IPR7_PRI_28                    ((uint32_t)0x000000FF)        /*!< Priority of interrupt 28 */
+#define  NVIC_IPR7_PRI_29                    ((uint32_t)0x0000FF00)        /*!< Priority of interrupt 29 */
+#define  NVIC_IPR7_PRI_30                    ((uint32_t)0x00FF0000)        /*!< Priority of interrupt 30 */
+#define  NVIC_IPR7_PRI_31                    ((uint32_t)0xFF000000)        /*!< Priority of interrupt 31 */
+
+/******************  Bit definition for SCB_CPUID register  *******************/
+#define  SCB_CPUID_REVISION                  ((uint32_t)0x0000000F)        /*!< Implementation defined revision number */
+#define  SCB_CPUID_PARTNO                    ((uint32_t)0x0000FFF0)        /*!< Number of processor within family */
+#define  SCB_CPUID_Constant                  ((uint32_t)0x000F0000)        /*!< Reads as 0x0F */
+#define  SCB_CPUID_VARIANT                   ((uint32_t)0x00F00000)        /*!< Implementation defined variant number */
+#define  SCB_CPUID_IMPLEMENTER               ((uint32_t)0xFF000000)        /*!< Implementer code. ARM is 0x41 */
+
+/*******************  Bit definition for SCB_ICSR register  *******************/
+#define  SCB_ICSR_VECTACTIVE                 ((uint32_t)0x000001FF)        /*!< Active ISR number field */
+#define  SCB_ICSR_RETTOBASE                  ((uint32_t)0x00000800)        /*!< All active exceptions minus the IPSR_current_exception yields the empty set */
+#define  SCB_ICSR_VECTPENDING                ((uint32_t)0x003FF000)        /*!< Pending ISR number field */
+#define  SCB_ICSR_ISRPENDING                 ((uint32_t)0x00400000)        /*!< Interrupt pending flag */
+#define  SCB_ICSR_ISRPREEMPT                 ((uint32_t)0x00800000)        /*!< It indicates that a pending interrupt becomes active in the next running cycle */
+#define  SCB_ICSR_PENDSTCLR                  ((uint32_t)0x02000000)        /*!< Clear pending SysTick bit */
+#define  SCB_ICSR_PENDSTSET                  ((uint32_t)0x04000000)        /*!< Set pending SysTick bit */
+#define  SCB_ICSR_PENDSVCLR                  ((uint32_t)0x08000000)        /*!< Clear pending pendSV bit */
+#define  SCB_ICSR_PENDSVSET                  ((uint32_t)0x10000000)        /*!< Set pending pendSV bit */
+#define  SCB_ICSR_NMIPENDSET                 ((uint32_t)0x80000000)        /*!< Set pending NMI bit */
+
+/*******************  Bit definition for SCB_VTOR register  *******************/
+#define  SCB_VTOR_TBLOFF                     ((uint32_t)0x1FFFFF80)        /*!< Vector table base offset field */
+#define  SCB_VTOR_TBLBASE                    ((uint32_t)0x20000000)        /*!< Table base in code(0) or RAM(1) */
+
+/*!<*****************  Bit definition for SCB_AIRCR register  *******************/
+#define  SCB_AIRCR_VECTRESET                 ((uint32_t)0x00000001)        /*!< System Reset bit */
+#define  SCB_AIRCR_VECTCLRACTIVE             ((uint32_t)0x00000002)        /*!< Clear active vector bit */
+#define  SCB_AIRCR_SYSRESETREQ               ((uint32_t)0x00000004)        /*!< Requests chip control logic to generate a reset */
+
+#define  SCB_AIRCR_PRIGROUP                  ((uint32_t)0x00000700)        /*!< PRIGROUP[2:0] bits (Priority group) */
+#define  SCB_AIRCR_PRIGROUP_0                ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  SCB_AIRCR_PRIGROUP_1                ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  SCB_AIRCR_PRIGROUP_2                ((uint32_t)0x00000400)        /*!< Bit 2  */
+
+/* prority group configuration */
+#define  SCB_AIRCR_PRIGROUP0                 ((uint32_t)0x00000000)        /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */
+#define  SCB_AIRCR_PRIGROUP1                 ((uint32_t)0x00000100)        /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP2                 ((uint32_t)0x00000200)        /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP3                 ((uint32_t)0x00000300)        /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP4                 ((uint32_t)0x00000400)        /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP5                 ((uint32_t)0x00000500)        /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP6                 ((uint32_t)0x00000600)        /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */
+#define  SCB_AIRCR_PRIGROUP7                 ((uint32_t)0x00000700)        /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */
+
+#define  SCB_AIRCR_ENDIANESS                 ((uint32_t)0x00008000)        /*!< Data endianness bit */
+#define  SCB_AIRCR_VECTKEY                   ((uint32_t)0xFFFF0000)        /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */
+
+/*******************  Bit definition for SCB_SCR register  ********************/
+#define  SCB_SCR_SLEEPONEXIT                 ((uint8_t)0x02)               /*!< Sleep on exit bit */
+#define  SCB_SCR_SLEEPDEEP                   ((uint8_t)0x04)               /*!< Sleep deep bit */
+#define  SCB_SCR_SEVONPEND                   ((uint8_t)0x10)               /*!< Wake up from WFE */
+
+/********************  Bit definition for SCB_CCR register  *******************/
+#define  SCB_CCR_NONBASETHRDENA              ((uint16_t)0x0001)            /*!< Thread mode can be entered from any level in Handler mode by controlled return value */
+#define  SCB_CCR_USERSETMPEND                ((uint16_t)0x0002)            /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */
+#define  SCB_CCR_UNALIGN_TRP                 ((uint16_t)0x0008)            /*!< Trap for unaligned access */
+#define  SCB_CCR_DIV_0_TRP                   ((uint16_t)0x0010)            /*!< Trap on Divide by 0 */
+#define  SCB_CCR_BFHFNMIGN                   ((uint16_t)0x0100)            /*!< Handlers running at priority -1 and -2 */
+#define  SCB_CCR_STKALIGN                    ((uint16_t)0x0200)            /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */
+
+/*******************  Bit definition for SCB_SHPR register ********************/
+#define  SCB_SHPR_PRI_N                      ((uint32_t)0x000000FF)        /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */
+#define  SCB_SHPR_PRI_N1                     ((uint32_t)0x0000FF00)        /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */
+#define  SCB_SHPR_PRI_N2                     ((uint32_t)0x00FF0000)        /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */
+#define  SCB_SHPR_PRI_N3                     ((uint32_t)0xFF000000)        /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */
+
+/******************  Bit definition for SCB_SHCSR register  *******************/
+#define  SCB_SHCSR_MEMFAULTACT               ((uint32_t)0x00000001)        /*!< MemManage is active */
+#define  SCB_SHCSR_BUSFAULTACT               ((uint32_t)0x00000002)        /*!< BusFault is active */
+#define  SCB_SHCSR_USGFAULTACT               ((uint32_t)0x00000008)        /*!< UsageFault is active */
+#define  SCB_SHCSR_SVCALLACT                 ((uint32_t)0x00000080)        /*!< SVCall is active */
+#define  SCB_SHCSR_MONITORACT                ((uint32_t)0x00000100)        /*!< Monitor is active */
+#define  SCB_SHCSR_PENDSVACT                 ((uint32_t)0x00000400)        /*!< PendSV is active */
+#define  SCB_SHCSR_SYSTICKACT                ((uint32_t)0x00000800)        /*!< SysTick is active */
+#define  SCB_SHCSR_USGFAULTPENDED            ((uint32_t)0x00001000)        /*!< Usage Fault is pended */
+#define  SCB_SHCSR_MEMFAULTPENDED            ((uint32_t)0x00002000)        /*!< MemManage is pended */
+#define  SCB_SHCSR_BUSFAULTPENDED            ((uint32_t)0x00004000)        /*!< Bus Fault is pended */
+#define  SCB_SHCSR_SVCALLPENDED              ((uint32_t)0x00008000)        /*!< SVCall is pended */
+#define  SCB_SHCSR_MEMFAULTENA               ((uint32_t)0x00010000)        /*!< MemManage enable */
+#define  SCB_SHCSR_BUSFAULTENA               ((uint32_t)0x00020000)        /*!< Bus Fault enable */
+#define  SCB_SHCSR_USGFAULTENA               ((uint32_t)0x00040000)        /*!< UsageFault enable */
+
+/*******************  Bit definition for SCB_CFSR register  *******************/
+/*!< MFSR */
+#define  SCB_CFSR_IACCVIOL                   ((uint32_t)0x00000001)        /*!< Instruction access violation */
+#define  SCB_CFSR_DACCVIOL                   ((uint32_t)0x00000002)        /*!< Data access violation */
+#define  SCB_CFSR_MUNSTKERR                  ((uint32_t)0x00000008)        /*!< Unstacking error */
+#define  SCB_CFSR_MSTKERR                    ((uint32_t)0x00000010)        /*!< Stacking error */
+#define  SCB_CFSR_MMARVALID                  ((uint32_t)0x00000080)        /*!< Memory Manage Address Register address valid flag */
+/*!< BFSR */
+#define  SCB_CFSR_IBUSERR                    ((uint32_t)0x00000100)        /*!< Instruction bus error flag */
+#define  SCB_CFSR_PRECISERR                  ((uint32_t)0x00000200)        /*!< Precise data bus error */
+#define  SCB_CFSR_IMPRECISERR                ((uint32_t)0x00000400)        /*!< Imprecise data bus error */
+#define  SCB_CFSR_UNSTKERR                   ((uint32_t)0x00000800)        /*!< Unstacking error */
+#define  SCB_CFSR_STKERR                     ((uint32_t)0x00001000)        /*!< Stacking error */
+#define  SCB_CFSR_BFARVALID                  ((uint32_t)0x00008000)        /*!< Bus Fault Address Register address valid flag */
+/*!< UFSR */
+#define  SCB_CFSR_UNDEFINSTR                 ((uint32_t)0x00010000)        /*!< The processor attempt to execute an undefined instruction */
+#define  SCB_CFSR_INVSTATE                   ((uint32_t)0x00020000)        /*!< Invalid combination of EPSR and instruction */
+#define  SCB_CFSR_INVPC                      ((uint32_t)0x00040000)        /*!< Attempt to load EXC_RETURN into pc illegally */
+#define  SCB_CFSR_NOCP                       ((uint32_t)0x00080000)        /*!< Attempt to use a coprocessor instruction */
+#define  SCB_CFSR_UNALIGNED                  ((uint32_t)0x01000000)        /*!< Fault occurs when there is an attempt to make an unaligned memory access */
+#define  SCB_CFSR_DIVBYZERO                  ((uint32_t)0x02000000)        /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */
+
+/*******************  Bit definition for SCB_HFSR register  *******************/
+#define  SCB_HFSR_VECTTBL                    ((uint32_t)0x00000002)        /*!< Fault occurs because of vector table read on exception processing */
+#define  SCB_HFSR_FORCED                     ((uint32_t)0x40000000)        /*!< Hard Fault activated when a configurable Fault was received and cannot activate */
+#define  SCB_HFSR_DEBUGEVT                   ((uint32_t)0x80000000)        /*!< Fault related to debug */
+
+/*******************  Bit definition for SCB_DFSR register  *******************/
+#define  SCB_DFSR_HALTED                     ((uint8_t)0x01)               /*!< Halt request flag */
+#define  SCB_DFSR_BKPT                       ((uint8_t)0x02)               /*!< BKPT flag */
+#define  SCB_DFSR_DWTTRAP                    ((uint8_t)0x04)               /*!< Data Watchpoint and Trace (DWT) flag */
+#define  SCB_DFSR_VCATCH                     ((uint8_t)0x08)               /*!< Vector catch flag */
+#define  SCB_DFSR_EXTERNAL                   ((uint8_t)0x10)               /*!< External debug request flag */
+
+/*******************  Bit definition for SCB_MMFAR register  ******************/
+#define  SCB_MMFAR_ADDRESS                   ((uint32_t)0xFFFFFFFF)        /*!< Mem Manage fault address field */
+
+/*******************  Bit definition for SCB_BFAR register  *******************/
+#define  SCB_BFAR_ADDRESS                    ((uint32_t)0xFFFFFFFF)        /*!< Bus fault address field */
+
+/*******************  Bit definition for SCB_afsr register  *******************/
+#define  SCB_AFSR_IMPDEF                     ((uint32_t)0xFFFFFFFF)        /*!< Implementation defined */
+
+/******************************************************************************/
+/*                                                                            */
+/*                    External Interrupt/Event Controller                     */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for EXTI_IMR register  *******************/
+#define  EXTI_IMR_MR0                        ((uint32_t)0x00000001)        /*!< Interrupt Mask on line 0 */
+#define  EXTI_IMR_MR1                        ((uint32_t)0x00000002)        /*!< Interrupt Mask on line 1 */
+#define  EXTI_IMR_MR2                        ((uint32_t)0x00000004)        /*!< Interrupt Mask on line 2 */
+#define  EXTI_IMR_MR3                        ((uint32_t)0x00000008)        /*!< Interrupt Mask on line 3 */
+#define  EXTI_IMR_MR4                        ((uint32_t)0x00000010)        /*!< Interrupt Mask on line 4 */
+#define  EXTI_IMR_MR5                        ((uint32_t)0x00000020)        /*!< Interrupt Mask on line 5 */
+#define  EXTI_IMR_MR6                        ((uint32_t)0x00000040)        /*!< Interrupt Mask on line 6 */
+#define  EXTI_IMR_MR7                        ((uint32_t)0x00000080)        /*!< Interrupt Mask on line 7 */
+#define  EXTI_IMR_MR8                        ((uint32_t)0x00000100)        /*!< Interrupt Mask on line 8 */
+#define  EXTI_IMR_MR9                        ((uint32_t)0x00000200)        /*!< Interrupt Mask on line 9 */
+#define  EXTI_IMR_MR10                       ((uint32_t)0x00000400)        /*!< Interrupt Mask on line 10 */
+#define  EXTI_IMR_MR11                       ((uint32_t)0x00000800)        /*!< Interrupt Mask on line 11 */
+#define  EXTI_IMR_MR12                       ((uint32_t)0x00001000)        /*!< Interrupt Mask on line 12 */
+#define  EXTI_IMR_MR13                       ((uint32_t)0x00002000)        /*!< Interrupt Mask on line 13 */
+#define  EXTI_IMR_MR14                       ((uint32_t)0x00004000)        /*!< Interrupt Mask on line 14 */
+#define  EXTI_IMR_MR15                       ((uint32_t)0x00008000)        /*!< Interrupt Mask on line 15 */
+#define  EXTI_IMR_MR16                       ((uint32_t)0x00010000)        /*!< Interrupt Mask on line 16 */
+#define  EXTI_IMR_MR17                       ((uint32_t)0x00020000)        /*!< Interrupt Mask on line 17 */
+#define  EXTI_IMR_MR18                       ((uint32_t)0x00040000)        /*!< Interrupt Mask on line 18 */
+#define  EXTI_IMR_MR19                       ((uint32_t)0x00080000)        /*!< Interrupt Mask on line 19 */
+
+/*******************  Bit definition for EXTI_EMR register  *******************/
+#define  EXTI_EMR_MR0                        ((uint32_t)0x00000001)        /*!< Event Mask on line 0 */
+#define  EXTI_EMR_MR1                        ((uint32_t)0x00000002)        /*!< Event Mask on line 1 */
+#define  EXTI_EMR_MR2                        ((uint32_t)0x00000004)        /*!< Event Mask on line 2 */
+#define  EXTI_EMR_MR3                        ((uint32_t)0x00000008)        /*!< Event Mask on line 3 */
+#define  EXTI_EMR_MR4                        ((uint32_t)0x00000010)        /*!< Event Mask on line 4 */
+#define  EXTI_EMR_MR5                        ((uint32_t)0x00000020)        /*!< Event Mask on line 5 */
+#define  EXTI_EMR_MR6                        ((uint32_t)0x00000040)        /*!< Event Mask on line 6 */
+#define  EXTI_EMR_MR7                        ((uint32_t)0x00000080)        /*!< Event Mask on line 7 */
+#define  EXTI_EMR_MR8                        ((uint32_t)0x00000100)        /*!< Event Mask on line 8 */
+#define  EXTI_EMR_MR9                        ((uint32_t)0x00000200)        /*!< Event Mask on line 9 */
+#define  EXTI_EMR_MR10                       ((uint32_t)0x00000400)        /*!< Event Mask on line 10 */
+#define  EXTI_EMR_MR11                       ((uint32_t)0x00000800)        /*!< Event Mask on line 11 */
+#define  EXTI_EMR_MR12                       ((uint32_t)0x00001000)        /*!< Event Mask on line 12 */
+#define  EXTI_EMR_MR13                       ((uint32_t)0x00002000)        /*!< Event Mask on line 13 */
+#define  EXTI_EMR_MR14                       ((uint32_t)0x00004000)        /*!< Event Mask on line 14 */
+#define  EXTI_EMR_MR15                       ((uint32_t)0x00008000)        /*!< Event Mask on line 15 */
+#define  EXTI_EMR_MR16                       ((uint32_t)0x00010000)        /*!< Event Mask on line 16 */
+#define  EXTI_EMR_MR17                       ((uint32_t)0x00020000)        /*!< Event Mask on line 17 */
+#define  EXTI_EMR_MR18                       ((uint32_t)0x00040000)        /*!< Event Mask on line 18 */
+#define  EXTI_EMR_MR19                       ((uint32_t)0x00080000)        /*!< Event Mask on line 19 */
+
+/******************  Bit definition for EXTI_RTSR register  *******************/
+#define  EXTI_RTSR_TR0                       ((uint32_t)0x00000001)        /*!< Rising trigger event configuration bit of line 0 */
+#define  EXTI_RTSR_TR1                       ((uint32_t)0x00000002)        /*!< Rising trigger event configuration bit of line 1 */
+#define  EXTI_RTSR_TR2                       ((uint32_t)0x00000004)        /*!< Rising trigger event configuration bit of line 2 */
+#define  EXTI_RTSR_TR3                       ((uint32_t)0x00000008)        /*!< Rising trigger event configuration bit of line 3 */
+#define  EXTI_RTSR_TR4                       ((uint32_t)0x00000010)        /*!< Rising trigger event configuration bit of line 4 */
+#define  EXTI_RTSR_TR5                       ((uint32_t)0x00000020)        /*!< Rising trigger event configuration bit of line 5 */
+#define  EXTI_RTSR_TR6                       ((uint32_t)0x00000040)        /*!< Rising trigger event configuration bit of line 6 */
+#define  EXTI_RTSR_TR7                       ((uint32_t)0x00000080)        /*!< Rising trigger event configuration bit of line 7 */
+#define  EXTI_RTSR_TR8                       ((uint32_t)0x00000100)        /*!< Rising trigger event configuration bit of line 8 */
+#define  EXTI_RTSR_TR9                       ((uint32_t)0x00000200)        /*!< Rising trigger event configuration bit of line 9 */
+#define  EXTI_RTSR_TR10                      ((uint32_t)0x00000400)        /*!< Rising trigger event configuration bit of line 10 */
+#define  EXTI_RTSR_TR11                      ((uint32_t)0x00000800)        /*!< Rising trigger event configuration bit of line 11 */
+#define  EXTI_RTSR_TR12                      ((uint32_t)0x00001000)        /*!< Rising trigger event configuration bit of line 12 */
+#define  EXTI_RTSR_TR13                      ((uint32_t)0x00002000)        /*!< Rising trigger event configuration bit of line 13 */
+#define  EXTI_RTSR_TR14                      ((uint32_t)0x00004000)        /*!< Rising trigger event configuration bit of line 14 */
+#define  EXTI_RTSR_TR15                      ((uint32_t)0x00008000)        /*!< Rising trigger event configuration bit of line 15 */
+#define  EXTI_RTSR_TR16                      ((uint32_t)0x00010000)        /*!< Rising trigger event configuration bit of line 16 */
+#define  EXTI_RTSR_TR17                      ((uint32_t)0x00020000)        /*!< Rising trigger event configuration bit of line 17 */
+#define  EXTI_RTSR_TR18                      ((uint32_t)0x00040000)        /*!< Rising trigger event configuration bit of line 18 */
+#define  EXTI_RTSR_TR19                      ((uint32_t)0x00080000)        /*!< Rising trigger event configuration bit of line 19 */
+
+/******************  Bit definition for EXTI_FTSR register  *******************/
+#define  EXTI_FTSR_TR0                       ((uint32_t)0x00000001)        /*!< Falling trigger event configuration bit of line 0 */
+#define  EXTI_FTSR_TR1                       ((uint32_t)0x00000002)        /*!< Falling trigger event configuration bit of line 1 */
+#define  EXTI_FTSR_TR2                       ((uint32_t)0x00000004)        /*!< Falling trigger event configuration bit of line 2 */
+#define  EXTI_FTSR_TR3                       ((uint32_t)0x00000008)        /*!< Falling trigger event configuration bit of line 3 */
+#define  EXTI_FTSR_TR4                       ((uint32_t)0x00000010)        /*!< Falling trigger event configuration bit of line 4 */
+#define  EXTI_FTSR_TR5                       ((uint32_t)0x00000020)        /*!< Falling trigger event configuration bit of line 5 */
+#define  EXTI_FTSR_TR6                       ((uint32_t)0x00000040)        /*!< Falling trigger event configuration bit of line 6 */
+#define  EXTI_FTSR_TR7                       ((uint32_t)0x00000080)        /*!< Falling trigger event configuration bit of line 7 */
+#define  EXTI_FTSR_TR8                       ((uint32_t)0x00000100)        /*!< Falling trigger event configuration bit of line 8 */
+#define  EXTI_FTSR_TR9                       ((uint32_t)0x00000200)        /*!< Falling trigger event configuration bit of line 9 */
+#define  EXTI_FTSR_TR10                      ((uint32_t)0x00000400)        /*!< Falling trigger event configuration bit of line 10 */
+#define  EXTI_FTSR_TR11                      ((uint32_t)0x00000800)        /*!< Falling trigger event configuration bit of line 11 */
+#define  EXTI_FTSR_TR12                      ((uint32_t)0x00001000)        /*!< Falling trigger event configuration bit of line 12 */
+#define  EXTI_FTSR_TR13                      ((uint32_t)0x00002000)        /*!< Falling trigger event configuration bit of line 13 */
+#define  EXTI_FTSR_TR14                      ((uint32_t)0x00004000)        /*!< Falling trigger event configuration bit of line 14 */
+#define  EXTI_FTSR_TR15                      ((uint32_t)0x00008000)        /*!< Falling trigger event configuration bit of line 15 */
+#define  EXTI_FTSR_TR16                      ((uint32_t)0x00010000)        /*!< Falling trigger event configuration bit of line 16 */
+#define  EXTI_FTSR_TR17                      ((uint32_t)0x00020000)        /*!< Falling trigger event configuration bit of line 17 */
+#define  EXTI_FTSR_TR18                      ((uint32_t)0x00040000)        /*!< Falling trigger event configuration bit of line 18 */
+#define  EXTI_FTSR_TR19                      ((uint32_t)0x00080000)        /*!< Falling trigger event configuration bit of line 19 */
+
+/******************  Bit definition for EXTI_SWIER register  ******************/
+#define  EXTI_SWIER_SWIER0                   ((uint32_t)0x00000001)        /*!< Software Interrupt on line 0 */
+#define  EXTI_SWIER_SWIER1                   ((uint32_t)0x00000002)        /*!< Software Interrupt on line 1 */
+#define  EXTI_SWIER_SWIER2                   ((uint32_t)0x00000004)        /*!< Software Interrupt on line 2 */
+#define  EXTI_SWIER_SWIER3                   ((uint32_t)0x00000008)        /*!< Software Interrupt on line 3 */
+#define  EXTI_SWIER_SWIER4                   ((uint32_t)0x00000010)        /*!< Software Interrupt on line 4 */
+#define  EXTI_SWIER_SWIER5                   ((uint32_t)0x00000020)        /*!< Software Interrupt on line 5 */
+#define  EXTI_SWIER_SWIER6                   ((uint32_t)0x00000040)        /*!< Software Interrupt on line 6 */
+#define  EXTI_SWIER_SWIER7                   ((uint32_t)0x00000080)        /*!< Software Interrupt on line 7 */
+#define  EXTI_SWIER_SWIER8                   ((uint32_t)0x00000100)        /*!< Software Interrupt on line 8 */
+#define  EXTI_SWIER_SWIER9                   ((uint32_t)0x00000200)        /*!< Software Interrupt on line 9 */
+#define  EXTI_SWIER_SWIER10                  ((uint32_t)0x00000400)        /*!< Software Interrupt on line 10 */
+#define  EXTI_SWIER_SWIER11                  ((uint32_t)0x00000800)        /*!< Software Interrupt on line 11 */
+#define  EXTI_SWIER_SWIER12                  ((uint32_t)0x00001000)        /*!< Software Interrupt on line 12 */
+#define  EXTI_SWIER_SWIER13                  ((uint32_t)0x00002000)        /*!< Software Interrupt on line 13 */
+#define  EXTI_SWIER_SWIER14                  ((uint32_t)0x00004000)        /*!< Software Interrupt on line 14 */
+#define  EXTI_SWIER_SWIER15                  ((uint32_t)0x00008000)        /*!< Software Interrupt on line 15 */
+#define  EXTI_SWIER_SWIER16                  ((uint32_t)0x00010000)        /*!< Software Interrupt on line 16 */
+#define  EXTI_SWIER_SWIER17                  ((uint32_t)0x00020000)        /*!< Software Interrupt on line 17 */
+#define  EXTI_SWIER_SWIER18                  ((uint32_t)0x00040000)        /*!< Software Interrupt on line 18 */
+#define  EXTI_SWIER_SWIER19                  ((uint32_t)0x00080000)        /*!< Software Interrupt on line 19 */
+
+/*******************  Bit definition for EXTI_PR register  ********************/
+#define  EXTI_PR_PR0                         ((uint32_t)0x00000001)        /*!< Pending bit for line 0 */
+#define  EXTI_PR_PR1                         ((uint32_t)0x00000002)        /*!< Pending bit for line 1 */
+#define  EXTI_PR_PR2                         ((uint32_t)0x00000004)        /*!< Pending bit for line 2 */
+#define  EXTI_PR_PR3                         ((uint32_t)0x00000008)        /*!< Pending bit for line 3 */
+#define  EXTI_PR_PR4                         ((uint32_t)0x00000010)        /*!< Pending bit for line 4 */
+#define  EXTI_PR_PR5                         ((uint32_t)0x00000020)        /*!< Pending bit for line 5 */
+#define  EXTI_PR_PR6                         ((uint32_t)0x00000040)        /*!< Pending bit for line 6 */
+#define  EXTI_PR_PR7                         ((uint32_t)0x00000080)        /*!< Pending bit for line 7 */
+#define  EXTI_PR_PR8                         ((uint32_t)0x00000100)        /*!< Pending bit for line 8 */
+#define  EXTI_PR_PR9                         ((uint32_t)0x00000200)        /*!< Pending bit for line 9 */
+#define  EXTI_PR_PR10                        ((uint32_t)0x00000400)        /*!< Pending bit for line 10 */
+#define  EXTI_PR_PR11                        ((uint32_t)0x00000800)        /*!< Pending bit for line 11 */
+#define  EXTI_PR_PR12                        ((uint32_t)0x00001000)        /*!< Pending bit for line 12 */
+#define  EXTI_PR_PR13                        ((uint32_t)0x00002000)        /*!< Pending bit for line 13 */
+#define  EXTI_PR_PR14                        ((uint32_t)0x00004000)        /*!< Pending bit for line 14 */
+#define  EXTI_PR_PR15                        ((uint32_t)0x00008000)        /*!< Pending bit for line 15 */
+#define  EXTI_PR_PR16                        ((uint32_t)0x00010000)        /*!< Pending bit for line 16 */
+#define  EXTI_PR_PR17                        ((uint32_t)0x00020000)        /*!< Pending bit for line 17 */
+#define  EXTI_PR_PR18                        ((uint32_t)0x00040000)        /*!< Pending bit for line 18 */
+#define  EXTI_PR_PR19                        ((uint32_t)0x00080000)        /*!< Pending bit for line 19 */
+
+/******************************************************************************/
+/*                                                                            */
+/*                             DMA Controller                                 */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for DMA_ISR register  ********************/
+#define  DMA_ISR_GIF1                        ((uint32_t)0x00000001)        /*!< Channel 1 Global interrupt flag */
+#define  DMA_ISR_TCIF1                       ((uint32_t)0x00000002)        /*!< Channel 1 Transfer Complete flag */
+#define  DMA_ISR_HTIF1                       ((uint32_t)0x00000004)        /*!< Channel 1 Half Transfer flag */
+#define  DMA_ISR_TEIF1                       ((uint32_t)0x00000008)        /*!< Channel 1 Transfer Error flag */
+#define  DMA_ISR_GIF2                        ((uint32_t)0x00000010)        /*!< Channel 2 Global interrupt flag */
+#define  DMA_ISR_TCIF2                       ((uint32_t)0x00000020)        /*!< Channel 2 Transfer Complete flag */
+#define  DMA_ISR_HTIF2                       ((uint32_t)0x00000040)        /*!< Channel 2 Half Transfer flag */
+#define  DMA_ISR_TEIF2                       ((uint32_t)0x00000080)        /*!< Channel 2 Transfer Error flag */
+#define  DMA_ISR_GIF3                        ((uint32_t)0x00000100)        /*!< Channel 3 Global interrupt flag */
+#define  DMA_ISR_TCIF3                       ((uint32_t)0x00000200)        /*!< Channel 3 Transfer Complete flag */
+#define  DMA_ISR_HTIF3                       ((uint32_t)0x00000400)        /*!< Channel 3 Half Transfer flag */
+#define  DMA_ISR_TEIF3                       ((uint32_t)0x00000800)        /*!< Channel 3 Transfer Error flag */
+#define  DMA_ISR_GIF4                        ((uint32_t)0x00001000)        /*!< Channel 4 Global interrupt flag */
+#define  DMA_ISR_TCIF4                       ((uint32_t)0x00002000)        /*!< Channel 4 Transfer Complete flag */
+#define  DMA_ISR_HTIF4                       ((uint32_t)0x00004000)        /*!< Channel 4 Half Transfer flag */
+#define  DMA_ISR_TEIF4                       ((uint32_t)0x00008000)        /*!< Channel 4 Transfer Error flag */
+#define  DMA_ISR_GIF5                        ((uint32_t)0x00010000)        /*!< Channel 5 Global interrupt flag */
+#define  DMA_ISR_TCIF5                       ((uint32_t)0x00020000)        /*!< Channel 5 Transfer Complete flag */
+#define  DMA_ISR_HTIF5                       ((uint32_t)0x00040000)        /*!< Channel 5 Half Transfer flag */
+#define  DMA_ISR_TEIF5                       ((uint32_t)0x00080000)        /*!< Channel 5 Transfer Error flag */
+#define  DMA_ISR_GIF6                        ((uint32_t)0x00100000)        /*!< Channel 6 Global interrupt flag */
+#define  DMA_ISR_TCIF6                       ((uint32_t)0x00200000)        /*!< Channel 6 Transfer Complete flag */
+#define  DMA_ISR_HTIF6                       ((uint32_t)0x00400000)        /*!< Channel 6 Half Transfer flag */
+#define  DMA_ISR_TEIF6                       ((uint32_t)0x00800000)        /*!< Channel 6 Transfer Error flag */
+#define  DMA_ISR_GIF7                        ((uint32_t)0x01000000)        /*!< Channel 7 Global interrupt flag */
+#define  DMA_ISR_TCIF7                       ((uint32_t)0x02000000)        /*!< Channel 7 Transfer Complete flag */
+#define  DMA_ISR_HTIF7                       ((uint32_t)0x04000000)        /*!< Channel 7 Half Transfer flag */
+#define  DMA_ISR_TEIF7                       ((uint32_t)0x08000000)        /*!< Channel 7 Transfer Error flag */
+
+/*******************  Bit definition for DMA_IFCR register  *******************/
+#define  DMA_IFCR_CGIF1                      ((uint32_t)0x00000001)        /*!< Channel 1 Global interrupt clear */
+#define  DMA_IFCR_CTCIF1                     ((uint32_t)0x00000002)        /*!< Channel 1 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF1                     ((uint32_t)0x00000004)        /*!< Channel 1 Half Transfer clear */
+#define  DMA_IFCR_CTEIF1                     ((uint32_t)0x00000008)        /*!< Channel 1 Transfer Error clear */
+#define  DMA_IFCR_CGIF2                      ((uint32_t)0x00000010)        /*!< Channel 2 Global interrupt clear */
+#define  DMA_IFCR_CTCIF2                     ((uint32_t)0x00000020)        /*!< Channel 2 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF2                     ((uint32_t)0x00000040)        /*!< Channel 2 Half Transfer clear */
+#define  DMA_IFCR_CTEIF2                     ((uint32_t)0x00000080)        /*!< Channel 2 Transfer Error clear */
+#define  DMA_IFCR_CGIF3                      ((uint32_t)0x00000100)        /*!< Channel 3 Global interrupt clear */
+#define  DMA_IFCR_CTCIF3                     ((uint32_t)0x00000200)        /*!< Channel 3 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF3                     ((uint32_t)0x00000400)        /*!< Channel 3 Half Transfer clear */
+#define  DMA_IFCR_CTEIF3                     ((uint32_t)0x00000800)        /*!< Channel 3 Transfer Error clear */
+#define  DMA_IFCR_CGIF4                      ((uint32_t)0x00001000)        /*!< Channel 4 Global interrupt clear */
+#define  DMA_IFCR_CTCIF4                     ((uint32_t)0x00002000)        /*!< Channel 4 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF4                     ((uint32_t)0x00004000)        /*!< Channel 4 Half Transfer clear */
+#define  DMA_IFCR_CTEIF4                     ((uint32_t)0x00008000)        /*!< Channel 4 Transfer Error clear */
+#define  DMA_IFCR_CGIF5                      ((uint32_t)0x00010000)        /*!< Channel 5 Global interrupt clear */
+#define  DMA_IFCR_CTCIF5                     ((uint32_t)0x00020000)        /*!< Channel 5 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF5                     ((uint32_t)0x00040000)        /*!< Channel 5 Half Transfer clear */
+#define  DMA_IFCR_CTEIF5                     ((uint32_t)0x00080000)        /*!< Channel 5 Transfer Error clear */
+#define  DMA_IFCR_CGIF6                      ((uint32_t)0x00100000)        /*!< Channel 6 Global interrupt clear */
+#define  DMA_IFCR_CTCIF6                     ((uint32_t)0x00200000)        /*!< Channel 6 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF6                     ((uint32_t)0x00400000)        /*!< Channel 6 Half Transfer clear */
+#define  DMA_IFCR_CTEIF6                     ((uint32_t)0x00800000)        /*!< Channel 6 Transfer Error clear */
+#define  DMA_IFCR_CGIF7                      ((uint32_t)0x01000000)        /*!< Channel 7 Global interrupt clear */
+#define  DMA_IFCR_CTCIF7                     ((uint32_t)0x02000000)        /*!< Channel 7 Transfer Complete clear */
+#define  DMA_IFCR_CHTIF7                     ((uint32_t)0x04000000)        /*!< Channel 7 Half Transfer clear */
+#define  DMA_IFCR_CTEIF7                     ((uint32_t)0x08000000)        /*!< Channel 7 Transfer Error clear */
+
+/*******************  Bit definition for DMA_CCR1 register  *******************/
+#define  DMA_CCR1_EN                         ((uint16_t)0x0001)            /*!< Channel enable*/
+#define  DMA_CCR1_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR1_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR1_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR1_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR1_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR1_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR1_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR1_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR1_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR1_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR1_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR1_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR1_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR1_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits(Channel Priority level) */
+#define  DMA_CCR1_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR1_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR1_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode */
+
+/*******************  Bit definition for DMA_CCR2 register  *******************/
+#define  DMA_CCR2_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR2_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR2_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR2_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR2_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR2_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR2_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR2_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR2_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR2_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR2_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR2_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR2_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR2_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR2_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR2_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR2_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR2_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode */
+
+/*******************  Bit definition for DMA_CCR3 register  *******************/
+#define  DMA_CCR3_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR3_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR3_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR3_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR3_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR3_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR3_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR3_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR3_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR3_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR3_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR3_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR3_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR3_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR3_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR3_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR3_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR3_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode */
+
+/*!<******************  Bit definition for DMA_CCR4 register  *******************/
+#define  DMA_CCR4_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR4_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR4_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR4_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR4_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR4_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR4_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR4_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR4_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR4_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR4_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR4_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR4_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR4_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR4_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR4_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR4_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR4_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode */
+
+/******************  Bit definition for DMA_CCR5 register  *******************/
+#define  DMA_CCR5_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR5_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR5_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR5_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR5_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR5_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR5_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR5_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR5_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR5_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR5_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR5_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR5_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR5_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR5_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR5_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR5_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR5_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode enable */
+
+/*******************  Bit definition for DMA_CCR6 register  *******************/
+#define  DMA_CCR6_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR6_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR6_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR6_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR6_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR6_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR6_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR6_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR6_PSIZE                      ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR6_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR6_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR6_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR6_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR6_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR6_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR6_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR6_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR6_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode */
+
+/*******************  Bit definition for DMA_CCR7 register  *******************/
+#define  DMA_CCR7_EN                         ((uint16_t)0x0001)            /*!< Channel enable */
+#define  DMA_CCR7_TCIE                       ((uint16_t)0x0002)            /*!< Transfer complete interrupt enable */
+#define  DMA_CCR7_HTIE                       ((uint16_t)0x0004)            /*!< Half Transfer interrupt enable */
+#define  DMA_CCR7_TEIE                       ((uint16_t)0x0008)            /*!< Transfer error interrupt enable */
+#define  DMA_CCR7_DIR                        ((uint16_t)0x0010)            /*!< Data transfer direction */
+#define  DMA_CCR7_CIRC                       ((uint16_t)0x0020)            /*!< Circular mode */
+#define  DMA_CCR7_PINC                       ((uint16_t)0x0040)            /*!< Peripheral increment mode */
+#define  DMA_CCR7_MINC                       ((uint16_t)0x0080)            /*!< Memory increment mode */
+
+#define  DMA_CCR7_PSIZE            ,         ((uint16_t)0x0300)            /*!< PSIZE[1:0] bits (Peripheral size) */
+#define  DMA_CCR7_PSIZE_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  DMA_CCR7_PSIZE_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  DMA_CCR7_MSIZE                      ((uint16_t)0x0C00)            /*!< MSIZE[1:0] bits (Memory size) */
+#define  DMA_CCR7_MSIZE_0                    ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  DMA_CCR7_MSIZE_1                    ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  DMA_CCR7_PL                         ((uint16_t)0x3000)            /*!< PL[1:0] bits (Channel Priority level) */
+#define  DMA_CCR7_PL_0                       ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  DMA_CCR7_PL_1                       ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  DMA_CCR7_MEM2MEM                    ((uint16_t)0x4000)            /*!< Memory to memory mode enable */
+
+/******************  Bit definition for DMA_CNDTR1 register  ******************/
+#define  DMA_CNDTR1_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR2 register  ******************/
+#define  DMA_CNDTR2_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR3 register  ******************/
+#define  DMA_CNDTR3_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR4 register  ******************/
+#define  DMA_CNDTR4_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR5 register  ******************/
+#define  DMA_CNDTR5_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR6 register  ******************/
+#define  DMA_CNDTR6_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CNDTR7 register  ******************/
+#define  DMA_CNDTR7_NDT                      ((uint16_t)0xFFFF)            /*!< Number of data to Transfer */
+
+/******************  Bit definition for DMA_CPAR1 register  *******************/
+#define  DMA_CPAR1_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+/******************  Bit definition for DMA_CPAR2 register  *******************/
+#define  DMA_CPAR2_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+/******************  Bit definition for DMA_CPAR3 register  *******************/
+#define  DMA_CPAR3_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+
+/******************  Bit definition for DMA_CPAR4 register  *******************/
+#define  DMA_CPAR4_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+/******************  Bit definition for DMA_CPAR5 register  *******************/
+#define  DMA_CPAR5_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+/******************  Bit definition for DMA_CPAR6 register  *******************/
+#define  DMA_CPAR6_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+
+/******************  Bit definition for DMA_CPAR7 register  *******************/
+#define  DMA_CPAR7_PA                        ((uint32_t)0xFFFFFFFF)        /*!< Peripheral Address */
+
+/******************  Bit definition for DMA_CMAR1 register  *******************/
+#define  DMA_CMAR1_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************  Bit definition for DMA_CMAR2 register  *******************/
+#define  DMA_CMAR2_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************  Bit definition for DMA_CMAR3 register  *******************/
+#define  DMA_CMAR3_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+
+/******************  Bit definition for DMA_CMAR4 register  *******************/
+#define  DMA_CMAR4_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************  Bit definition for DMA_CMAR5 register  *******************/
+#define  DMA_CMAR5_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************  Bit definition for DMA_CMAR6 register  *******************/
+#define  DMA_CMAR6_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************  Bit definition for DMA_CMAR7 register  *******************/
+#define  DMA_CMAR7_MA                        ((uint32_t)0xFFFFFFFF)        /*!< Memory Address */
+
+/******************************************************************************/
+/*                                                                            */
+/*                        Analog to Digital Converter                         */
+/*                                                                            */
+/******************************************************************************/
+
+/********************  Bit definition for ADC_SR register  ********************/
+#define  ADC_SR_AWD                          ((uint8_t)0x01)               /*!< Analog watchdog flag */
+#define  ADC_SR_EOC                          ((uint8_t)0x02)               /*!< End of conversion */
+#define  ADC_SR_JEOC                         ((uint8_t)0x04)               /*!< Injected channel end of conversion */
+#define  ADC_SR_JSTRT                        ((uint8_t)0x08)               /*!< Injected channel Start flag */
+#define  ADC_SR_STRT                         ((uint8_t)0x10)               /*!< Regular channel Start flag */
+
+/*******************  Bit definition for ADC_CR1 register  ********************/
+#define  ADC_CR1_AWDCH                       ((uint32_t)0x0000001F)        /*!< AWDCH[4:0] bits (Analog watchdog channel select bits) */
+#define  ADC_CR1_AWDCH_0                     ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_CR1_AWDCH_1                     ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_CR1_AWDCH_2                     ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  ADC_CR1_AWDCH_3                     ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  ADC_CR1_AWDCH_4                     ((uint32_t)0x00000010)        /*!< Bit 4 */
+
+#define  ADC_CR1_EOCIE                       ((uint32_t)0x00000020)        /*!< Interrupt enable for EOC */
+#define  ADC_CR1_AWDIE                       ((uint32_t)0x00000040)        /*!< Analog Watchdog interrupt enable */
+#define  ADC_CR1_JEOCIE                      ((uint32_t)0x00000080)        /*!< Interrupt enable for injected channels */
+#define  ADC_CR1_SCAN                        ((uint32_t)0x00000100)        /*!< Scan mode */
+#define  ADC_CR1_AWDSGL                      ((uint32_t)0x00000200)        /*!< Enable the watchdog on a single channel in scan mode */
+#define  ADC_CR1_JAUTO                       ((uint32_t)0x00000400)        /*!< Automatic injected group conversion */
+#define  ADC_CR1_DISCEN                      ((uint32_t)0x00000800)        /*!< Discontinuous mode on regular channels */
+#define  ADC_CR1_JDISCEN                     ((uint32_t)0x00001000)        /*!< Discontinuous mode on injected channels */
+
+#define  ADC_CR1_DISCNUM                     ((uint32_t)0x0000E000)        /*!< DISCNUM[2:0] bits (Discontinuous mode channel count) */
+#define  ADC_CR1_DISCNUM_0                   ((uint32_t)0x00002000)        /*!< Bit 0 */
+#define  ADC_CR1_DISCNUM_1                   ((uint32_t)0x00004000)        /*!< Bit 1 */
+#define  ADC_CR1_DISCNUM_2                   ((uint32_t)0x00008000)        /*!< Bit 2 */
+
+#define  ADC_CR1_DUALMOD                     ((uint32_t)0x000F0000)        /*!< DUALMOD[3:0] bits (Dual mode selection) */
+#define  ADC_CR1_DUALMOD_0                   ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  ADC_CR1_DUALMOD_1                   ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  ADC_CR1_DUALMOD_2                   ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  ADC_CR1_DUALMOD_3                   ((uint32_t)0x00080000)        /*!< Bit 3 */
+
+#define  ADC_CR1_JAWDEN                      ((uint32_t)0x00400000)        /*!< Analog watchdog enable on injected channels */
+#define  ADC_CR1_AWDEN                       ((uint32_t)0x00800000)        /*!< Analog watchdog enable on regular channels */
+
+  
+/*******************  Bit definition for ADC_CR2 register  ********************/
+#define  ADC_CR2_ADON                        ((uint32_t)0x00000001)        /*!< A/D Converter ON / OFF */
+#define  ADC_CR2_CONT                        ((uint32_t)0x00000002)        /*!< Continuous Conversion */
+#define  ADC_CR2_CAL                         ((uint32_t)0x00000004)        /*!< A/D Calibration */
+#define  ADC_CR2_RSTCAL                      ((uint32_t)0x00000008)        /*!< Reset Calibration */
+#define  ADC_CR2_DMA                         ((uint32_t)0x00000100)        /*!< Direct Memory access mode */
+#define  ADC_CR2_ALIGN                       ((uint32_t)0x00000800)        /*!< Data Alignment */
+
+#define  ADC_CR2_JEXTSEL                     ((uint32_t)0x00007000)        /*!< JEXTSEL[2:0] bits (External event select for injected group) */
+#define  ADC_CR2_JEXTSEL_0                   ((uint32_t)0x00001000)        /*!< Bit 0 */
+#define  ADC_CR2_JEXTSEL_1                   ((uint32_t)0x00002000)        /*!< Bit 1 */
+#define  ADC_CR2_JEXTSEL_2                   ((uint32_t)0x00004000)        /*!< Bit 2 */
+
+#define  ADC_CR2_JEXTTRIG                    ((uint32_t)0x00008000)        /*!< External Trigger Conversion mode for injected channels */
+
+#define  ADC_CR2_EXTSEL                      ((uint32_t)0x000E0000)        /*!< EXTSEL[2:0] bits (External Event Select for regular group) */
+#define  ADC_CR2_EXTSEL_0                    ((uint32_t)0x00020000)        /*!< Bit 0 */
+#define  ADC_CR2_EXTSEL_1                    ((uint32_t)0x00040000)        /*!< Bit 1 */
+#define  ADC_CR2_EXTSEL_2                    ((uint32_t)0x00080000)        /*!< Bit 2 */
+
+#define  ADC_CR2_EXTTRIG                     ((uint32_t)0x00100000)        /*!< External Trigger Conversion mode for regular channels */
+#define  ADC_CR2_JSWSTART                    ((uint32_t)0x00200000)        /*!< Start Conversion of injected channels */
+#define  ADC_CR2_SWSTART                     ((uint32_t)0x00400000)        /*!< Start Conversion of regular channels */
+#define  ADC_CR2_TSVREFE                     ((uint32_t)0x00800000)        /*!< Temperature Sensor and VREFINT Enable */
+
+/******************  Bit definition for ADC_SMPR1 register  *******************/
+#define  ADC_SMPR1_SMP10                     ((uint32_t)0x00000007)        /*!< SMP10[2:0] bits (Channel 10 Sample time selection) */
+#define  ADC_SMPR1_SMP10_0                   ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP10_1                   ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP10_2                   ((uint32_t)0x00000004)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP11                     ((uint32_t)0x00000038)        /*!< SMP11[2:0] bits (Channel 11 Sample time selection) */
+#define  ADC_SMPR1_SMP11_0                   ((uint32_t)0x00000008)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP11_1                   ((uint32_t)0x00000010)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP11_2                   ((uint32_t)0x00000020)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP12                     ((uint32_t)0x000001C0)        /*!< SMP12[2:0] bits (Channel 12 Sample time selection) */
+#define  ADC_SMPR1_SMP12_0                   ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP12_1                   ((uint32_t)0x00000080)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP12_2                   ((uint32_t)0x00000100)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP13                     ((uint32_t)0x00000E00)        /*!< SMP13[2:0] bits (Channel 13 Sample time selection) */
+#define  ADC_SMPR1_SMP13_0                   ((uint32_t)0x00000200)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP13_1                   ((uint32_t)0x00000400)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP13_2                   ((uint32_t)0x00000800)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP14                     ((uint32_t)0x00007000)        /*!< SMP14[2:0] bits (Channel 14 Sample time selection) */
+#define  ADC_SMPR1_SMP14_0                   ((uint32_t)0x00001000)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP14_1                   ((uint32_t)0x00002000)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP14_2                   ((uint32_t)0x00004000)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP15                     ((uint32_t)0x00038000)        /*!< SMP15[2:0] bits (Channel 15 Sample time selection) */
+#define  ADC_SMPR1_SMP15_0                   ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP15_1                   ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP15_2                   ((uint32_t)0x00020000)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP16                     ((uint32_t)0x001C0000)        /*!< SMP16[2:0] bits (Channel 16 Sample time selection) */
+#define  ADC_SMPR1_SMP16_0                   ((uint32_t)0x00040000)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP16_1                   ((uint32_t)0x00080000)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP16_2                   ((uint32_t)0x00100000)        /*!< Bit 2 */
+
+#define  ADC_SMPR1_SMP17                     ((uint32_t)0x00E00000)        /*!< SMP17[2:0] bits (Channel 17 Sample time selection) */
+#define  ADC_SMPR1_SMP17_0                   ((uint32_t)0x00200000)        /*!< Bit 0 */
+#define  ADC_SMPR1_SMP17_1                   ((uint32_t)0x00400000)        /*!< Bit 1 */
+#define  ADC_SMPR1_SMP17_2                   ((uint32_t)0x00800000)        /*!< Bit 2 */
+
+/******************  Bit definition for ADC_SMPR2 register  *******************/
+#define  ADC_SMPR2_SMP0                      ((uint32_t)0x00000007)        /*!< SMP0[2:0] bits (Channel 0 Sample time selection) */
+#define  ADC_SMPR2_SMP0_0                    ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP0_1                    ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP0_2                    ((uint32_t)0x00000004)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP1                      ((uint32_t)0x00000038)        /*!< SMP1[2:0] bits (Channel 1 Sample time selection) */
+#define  ADC_SMPR2_SMP1_0                    ((uint32_t)0x00000008)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP1_1                    ((uint32_t)0x00000010)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP1_2                    ((uint32_t)0x00000020)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP2                      ((uint32_t)0x000001C0)        /*!< SMP2[2:0] bits (Channel 2 Sample time selection) */
+#define  ADC_SMPR2_SMP2_0                    ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP2_1                    ((uint32_t)0x00000080)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP2_2                    ((uint32_t)0x00000100)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP3                      ((uint32_t)0x00000E00)        /*!< SMP3[2:0] bits (Channel 3 Sample time selection) */
+#define  ADC_SMPR2_SMP3_0                    ((uint32_t)0x00000200)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP3_1                    ((uint32_t)0x00000400)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP3_2                    ((uint32_t)0x00000800)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP4                      ((uint32_t)0x00007000)        /*!< SMP4[2:0] bits (Channel 4 Sample time selection) */
+#define  ADC_SMPR2_SMP4_0                    ((uint32_t)0x00001000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP4_1                    ((uint32_t)0x00002000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP4_2                    ((uint32_t)0x00004000)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP5                      ((uint32_t)0x00038000)        /*!< SMP5[2:0] bits (Channel 5 Sample time selection) */
+#define  ADC_SMPR2_SMP5_0                    ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP5_1                    ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP5_2                    ((uint32_t)0x00020000)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP6                      ((uint32_t)0x001C0000)        /*!< SMP6[2:0] bits (Channel 6 Sample time selection) */
+#define  ADC_SMPR2_SMP6_0                    ((uint32_t)0x00040000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP6_1                    ((uint32_t)0x00080000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP6_2                    ((uint32_t)0x00100000)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP7                      ((uint32_t)0x00E00000)        /*!< SMP7[2:0] bits (Channel 7 Sample time selection) */
+#define  ADC_SMPR2_SMP7_0                    ((uint32_t)0x00200000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP7_1                    ((uint32_t)0x00400000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP7_2                    ((uint32_t)0x00800000)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP8                      ((uint32_t)0x07000000)        /*!< SMP8[2:0] bits (Channel 8 Sample time selection) */
+#define  ADC_SMPR2_SMP8_0                    ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP8_1                    ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP8_2                    ((uint32_t)0x04000000)        /*!< Bit 2 */
+
+#define  ADC_SMPR2_SMP9                      ((uint32_t)0x38000000)        /*!< SMP9[2:0] bits (Channel 9 Sample time selection) */
+#define  ADC_SMPR2_SMP9_0                    ((uint32_t)0x08000000)        /*!< Bit 0 */
+#define  ADC_SMPR2_SMP9_1                    ((uint32_t)0x10000000)        /*!< Bit 1 */
+#define  ADC_SMPR2_SMP9_2                    ((uint32_t)0x20000000)        /*!< Bit 2 */
+
+/******************  Bit definition for ADC_JOFR1 register  *******************/
+#define  ADC_JOFR1_JOFFSET1                  ((uint16_t)0x0FFF)            /*!< Data offset for injected channel 1 */
+
+/******************  Bit definition for ADC_JOFR2 register  *******************/
+#define  ADC_JOFR2_JOFFSET2                  ((uint16_t)0x0FFF)            /*!< Data offset for injected channel 2 */
+
+/******************  Bit definition for ADC_JOFR3 register  *******************/
+#define  ADC_JOFR3_JOFFSET3                  ((uint16_t)0x0FFF)            /*!< Data offset for injected channel 3 */
+
+/******************  Bit definition for ADC_JOFR4 register  *******************/
+#define  ADC_JOFR4_JOFFSET4                  ((uint16_t)0x0FFF)            /*!< Data offset for injected channel 4 */
+
+/*******************  Bit definition for ADC_HTR register  ********************/
+#define  ADC_HTR_HT                          ((uint16_t)0x0FFF)            /*!< Analog watchdog high threshold */
+
+/*******************  Bit definition for ADC_LTR register  ********************/
+#define  ADC_LTR_LT                          ((uint16_t)0x0FFF)            /*!< Analog watchdog low threshold */
+
+/*******************  Bit definition for ADC_SQR1 register  *******************/
+#define  ADC_SQR1_SQ13                       ((uint32_t)0x0000001F)        /*!< SQ13[4:0] bits (13th conversion in regular sequence) */
+#define  ADC_SQR1_SQ13_0                     ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_SQR1_SQ13_1                     ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_SQR1_SQ13_2                     ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  ADC_SQR1_SQ13_3                     ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  ADC_SQR1_SQ13_4                     ((uint32_t)0x00000010)        /*!< Bit 4 */
+
+#define  ADC_SQR1_SQ14                       ((uint32_t)0x000003E0)        /*!< SQ14[4:0] bits (14th conversion in regular sequence) */
+#define  ADC_SQR1_SQ14_0                     ((uint32_t)0x00000020)        /*!< Bit 0 */
+#define  ADC_SQR1_SQ14_1                     ((uint32_t)0x00000040)        /*!< Bit 1 */
+#define  ADC_SQR1_SQ14_2                     ((uint32_t)0x00000080)        /*!< Bit 2 */
+#define  ADC_SQR1_SQ14_3                     ((uint32_t)0x00000100)        /*!< Bit 3 */
+#define  ADC_SQR1_SQ14_4                     ((uint32_t)0x00000200)        /*!< Bit 4 */
+
+#define  ADC_SQR1_SQ15                       ((uint32_t)0x00007C00)        /*!< SQ15[4:0] bits (15th conversion in regular sequence) */
+#define  ADC_SQR1_SQ15_0                     ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  ADC_SQR1_SQ15_1                     ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  ADC_SQR1_SQ15_2                     ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  ADC_SQR1_SQ15_3                     ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  ADC_SQR1_SQ15_4                     ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  ADC_SQR1_SQ16                       ((uint32_t)0x000F8000)        /*!< SQ16[4:0] bits (16th conversion in regular sequence) */
+#define  ADC_SQR1_SQ16_0                     ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_SQR1_SQ16_1                     ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_SQR1_SQ16_2                     ((uint32_t)0x00020000)        /*!< Bit 2 */
+#define  ADC_SQR1_SQ16_3                     ((uint32_t)0x00040000)        /*!< Bit 3 */
+#define  ADC_SQR1_SQ16_4                     ((uint32_t)0x00080000)        /*!< Bit 4 */
+
+#define  ADC_SQR1_L                          ((uint32_t)0x00F00000)        /*!< L[3:0] bits (Regular channel sequence length) */
+#define  ADC_SQR1_L_0                        ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  ADC_SQR1_L_1                        ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  ADC_SQR1_L_2                        ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  ADC_SQR1_L_3                        ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+/*******************  Bit definition for ADC_SQR2 register  *******************/
+#define  ADC_SQR2_SQ7                        ((uint32_t)0x0000001F)        /*!< SQ7[4:0] bits (7th conversion in regular sequence) */
+#define  ADC_SQR2_SQ7_0                      ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ7_1                      ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ7_2                      ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ7_3                      ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ7_4                      ((uint32_t)0x00000010)        /*!< Bit 4 */
+
+#define  ADC_SQR2_SQ8                        ((uint32_t)0x000003E0)        /*!< SQ8[4:0] bits (8th conversion in regular sequence) */
+#define  ADC_SQR2_SQ8_0                      ((uint32_t)0x00000020)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ8_1                      ((uint32_t)0x00000040)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ8_2                      ((uint32_t)0x00000080)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ8_3                      ((uint32_t)0x00000100)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ8_4                      ((uint32_t)0x00000200)        /*!< Bit 4 */
+
+#define  ADC_SQR2_SQ9                        ((uint32_t)0x00007C00)        /*!< SQ9[4:0] bits (9th conversion in regular sequence) */
+#define  ADC_SQR2_SQ9_0                      ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ9_1                      ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ9_2                      ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ9_3                      ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ9_4                      ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  ADC_SQR2_SQ10                       ((uint32_t)0x000F8000)        /*!< SQ10[4:0] bits (10th conversion in regular sequence) */
+#define  ADC_SQR2_SQ10_0                     ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ10_1                     ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ10_2                     ((uint32_t)0x00020000)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ10_3                     ((uint32_t)0x00040000)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ10_4                     ((uint32_t)0x00080000)        /*!< Bit 4 */
+
+#define  ADC_SQR2_SQ11                       ((uint32_t)0x01F00000)        /*!< SQ11[4:0] bits (11th conversion in regular sequence) */
+#define  ADC_SQR2_SQ11_0                     ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ11_1                     ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ11_2                     ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ11_3                     ((uint32_t)0x00800000)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ11_4                     ((uint32_t)0x01000000)        /*!< Bit 4 */
+
+#define  ADC_SQR2_SQ12                       ((uint32_t)0x3E000000)        /*!< SQ12[4:0] bits (12th conversion in regular sequence) */
+#define  ADC_SQR2_SQ12_0                     ((uint32_t)0x02000000)        /*!< Bit 0 */
+#define  ADC_SQR2_SQ12_1                     ((uint32_t)0x04000000)        /*!< Bit 1 */
+#define  ADC_SQR2_SQ12_2                     ((uint32_t)0x08000000)        /*!< Bit 2 */
+#define  ADC_SQR2_SQ12_3                     ((uint32_t)0x10000000)        /*!< Bit 3 */
+#define  ADC_SQR2_SQ12_4                     ((uint32_t)0x20000000)        /*!< Bit 4 */
+
+/*******************  Bit definition for ADC_SQR3 register  *******************/
+#define  ADC_SQR3_SQ1                        ((uint32_t)0x0000001F)        /*!< SQ1[4:0] bits (1st conversion in regular sequence) */
+#define  ADC_SQR3_SQ1_0                      ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ1_1                      ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ1_2                      ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ1_3                      ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ1_4                      ((uint32_t)0x00000010)        /*!< Bit 4 */
+
+#define  ADC_SQR3_SQ2                        ((uint32_t)0x000003E0)        /*!< SQ2[4:0] bits (2nd conversion in regular sequence) */
+#define  ADC_SQR3_SQ2_0                      ((uint32_t)0x00000020)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ2_1                      ((uint32_t)0x00000040)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ2_2                      ((uint32_t)0x00000080)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ2_3                      ((uint32_t)0x00000100)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ2_4                      ((uint32_t)0x00000200)        /*!< Bit 4 */
+
+#define  ADC_SQR3_SQ3                        ((uint32_t)0x00007C00)        /*!< SQ3[4:0] bits (3rd conversion in regular sequence) */
+#define  ADC_SQR3_SQ3_0                      ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ3_1                      ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ3_2                      ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ3_3                      ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ3_4                      ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  ADC_SQR3_SQ4                        ((uint32_t)0x000F8000)        /*!< SQ4[4:0] bits (4th conversion in regular sequence) */
+#define  ADC_SQR3_SQ4_0                      ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ4_1                      ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ4_2                      ((uint32_t)0x00020000)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ4_3                      ((uint32_t)0x00040000)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ4_4                      ((uint32_t)0x00080000)        /*!< Bit 4 */
+
+#define  ADC_SQR3_SQ5                        ((uint32_t)0x01F00000)        /*!< SQ5[4:0] bits (5th conversion in regular sequence) */
+#define  ADC_SQR3_SQ5_0                      ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ5_1                      ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ5_2                      ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ5_3                      ((uint32_t)0x00800000)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ5_4                      ((uint32_t)0x01000000)        /*!< Bit 4 */
+
+#define  ADC_SQR3_SQ6                        ((uint32_t)0x3E000000)        /*!< SQ6[4:0] bits (6th conversion in regular sequence) */
+#define  ADC_SQR3_SQ6_0                      ((uint32_t)0x02000000)        /*!< Bit 0 */
+#define  ADC_SQR3_SQ6_1                      ((uint32_t)0x04000000)        /*!< Bit 1 */
+#define  ADC_SQR3_SQ6_2                      ((uint32_t)0x08000000)        /*!< Bit 2 */
+#define  ADC_SQR3_SQ6_3                      ((uint32_t)0x10000000)        /*!< Bit 3 */
+#define  ADC_SQR3_SQ6_4                      ((uint32_t)0x20000000)        /*!< Bit 4 */
+
+/*******************  Bit definition for ADC_JSQR register  *******************/
+#define  ADC_JSQR_JSQ1                       ((uint32_t)0x0000001F)        /*!< JSQ1[4:0] bits (1st conversion in injected sequence) */  
+#define  ADC_JSQR_JSQ1_0                     ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  ADC_JSQR_JSQ1_1                     ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  ADC_JSQR_JSQ1_2                     ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  ADC_JSQR_JSQ1_3                     ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  ADC_JSQR_JSQ1_4                     ((uint32_t)0x00000010)        /*!< Bit 4 */
+
+#define  ADC_JSQR_JSQ2                       ((uint32_t)0x000003E0)        /*!< JSQ2[4:0] bits (2nd conversion in injected sequence) */
+#define  ADC_JSQR_JSQ2_0                     ((uint32_t)0x00000020)        /*!< Bit 0 */
+#define  ADC_JSQR_JSQ2_1                     ((uint32_t)0x00000040)        /*!< Bit 1 */
+#define  ADC_JSQR_JSQ2_2                     ((uint32_t)0x00000080)        /*!< Bit 2 */
+#define  ADC_JSQR_JSQ2_3                     ((uint32_t)0x00000100)        /*!< Bit 3 */
+#define  ADC_JSQR_JSQ2_4                     ((uint32_t)0x00000200)        /*!< Bit 4 */
+
+#define  ADC_JSQR_JSQ3                       ((uint32_t)0x00007C00)        /*!< JSQ3[4:0] bits (3rd conversion in injected sequence) */
+#define  ADC_JSQR_JSQ3_0                     ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  ADC_JSQR_JSQ3_1                     ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  ADC_JSQR_JSQ3_2                     ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  ADC_JSQR_JSQ3_3                     ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  ADC_JSQR_JSQ3_4                     ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  ADC_JSQR_JSQ4                       ((uint32_t)0x000F8000)        /*!< JSQ4[4:0] bits (4th conversion in injected sequence) */
+#define  ADC_JSQR_JSQ4_0                     ((uint32_t)0x00008000)        /*!< Bit 0 */
+#define  ADC_JSQR_JSQ4_1                     ((uint32_t)0x00010000)        /*!< Bit 1 */
+#define  ADC_JSQR_JSQ4_2                     ((uint32_t)0x00020000)        /*!< Bit 2 */
+#define  ADC_JSQR_JSQ4_3                     ((uint32_t)0x00040000)        /*!< Bit 3 */
+#define  ADC_JSQR_JSQ4_4                     ((uint32_t)0x00080000)        /*!< Bit 4 */
+
+#define  ADC_JSQR_JL                         ((uint32_t)0x00300000)        /*!< JL[1:0] bits (Injected Sequence length) */
+#define  ADC_JSQR_JL_0                       ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  ADC_JSQR_JL_1                       ((uint32_t)0x00200000)        /*!< Bit 1 */
+
+/*******************  Bit definition for ADC_JDR1 register  *******************/
+#define  ADC_JDR1_JDATA                      ((uint16_t)0xFFFF)            /*!< Injected data */
+
+/*******************  Bit definition for ADC_JDR2 register  *******************/
+#define  ADC_JDR2_JDATA                      ((uint16_t)0xFFFF)            /*!< Injected data */
+
+/*******************  Bit definition for ADC_JDR3 register  *******************/
+#define  ADC_JDR3_JDATA                      ((uint16_t)0xFFFF)            /*!< Injected data */
+
+/*******************  Bit definition for ADC_JDR4 register  *******************/
+#define  ADC_JDR4_JDATA                      ((uint16_t)0xFFFF)            /*!< Injected data */
+
+/********************  Bit definition for ADC_DR register  ********************/
+#define  ADC_DR_DATA                         ((uint32_t)0x0000FFFF)        /*!< Regular data */
+#define  ADC_DR_ADC2DATA                     ((uint32_t)0xFFFF0000)        /*!< ADC2 data */
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Digital to Analog Converter                           */
+/*                                                                            */
+/******************************************************************************/
+
+/********************  Bit definition for DAC_CR register  ********************/
+#define  DAC_CR_EN1                          ((uint32_t)0x00000001)        /*!< DAC channel1 enable */
+#define  DAC_CR_BOFF1                        ((uint32_t)0x00000002)        /*!< DAC channel1 output buffer disable */
+#define  DAC_CR_TEN1                         ((uint32_t)0x00000004)        /*!< DAC channel1 Trigger enable */
+
+#define  DAC_CR_TSEL1                        ((uint32_t)0x00000038)        /*!< TSEL1[2:0] (DAC channel1 Trigger selection) */
+#define  DAC_CR_TSEL1_0                      ((uint32_t)0x00000008)        /*!< Bit 0 */
+#define  DAC_CR_TSEL1_1                      ((uint32_t)0x00000010)        /*!< Bit 1 */
+#define  DAC_CR_TSEL1_2                      ((uint32_t)0x00000020)        /*!< Bit 2 */
+
+#define  DAC_CR_WAVE1                        ((uint32_t)0x000000C0)        /*!< WAVE1[1:0] (DAC channel1 noise/triangle wave generation enable) */
+#define  DAC_CR_WAVE1_0                      ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  DAC_CR_WAVE1_1                      ((uint32_t)0x00000080)        /*!< Bit 1 */
+
+#define  DAC_CR_MAMP1                        ((uint32_t)0x00000F00)        /*!< MAMP1[3:0] (DAC channel1 Mask/Amplitude selector) */
+#define  DAC_CR_MAMP1_0                      ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  DAC_CR_MAMP1_1                      ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  DAC_CR_MAMP1_2                      ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  DAC_CR_MAMP1_3                      ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  DAC_CR_DMAEN1                       ((uint32_t)0x00001000)        /*!< DAC channel1 DMA enable */
+#define  DAC_CR_EN2                          ((uint32_t)0x00010000)        /*!< DAC channel2 enable */
+#define  DAC_CR_BOFF2                        ((uint32_t)0x00020000)        /*!< DAC channel2 output buffer disable */
+#define  DAC_CR_TEN2                         ((uint32_t)0x00040000)        /*!< DAC channel2 Trigger enable */
+
+#define  DAC_CR_TSEL2                        ((uint32_t)0x00380000)        /*!< TSEL2[2:0] (DAC channel2 Trigger selection) */
+#define  DAC_CR_TSEL2_0                      ((uint32_t)0x00080000)        /*!< Bit 0 */
+#define  DAC_CR_TSEL2_1                      ((uint32_t)0x00100000)        /*!< Bit 1 */
+#define  DAC_CR_TSEL2_2                      ((uint32_t)0x00200000)        /*!< Bit 2 */
+
+#define  DAC_CR_WAVE2                        ((uint32_t)0x00C00000)        /*!< WAVE2[1:0] (DAC channel2 noise/triangle wave generation enable) */
+#define  DAC_CR_WAVE2_0                      ((uint32_t)0x00400000)        /*!< Bit 0 */
+#define  DAC_CR_WAVE2_1                      ((uint32_t)0x00800000)        /*!< Bit 1 */
+
+#define  DAC_CR_MAMP2                        ((uint32_t)0x0F000000)        /*!< MAMP2[3:0] (DAC channel2 Mask/Amplitude selector) */
+#define  DAC_CR_MAMP2_0                      ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  DAC_CR_MAMP2_1                      ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  DAC_CR_MAMP2_2                      ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  DAC_CR_MAMP2_3                      ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  DAC_CR_DMAEN2                       ((uint32_t)0x10000000)        /*!< DAC channel2 DMA enabled */
+
+/*****************  Bit definition for DAC_SWTRIGR register  ******************/
+#define  DAC_SWTRIGR_SWTRIG1                 ((uint8_t)0x01)               /*!< DAC channel1 software trigger */
+#define  DAC_SWTRIGR_SWTRIG2                 ((uint8_t)0x02)               /*!< DAC channel2 software trigger */
+
+/*****************  Bit definition for DAC_DHR12R1 register  ******************/
+#define  DAC_DHR12R1_DACC1DHR                ((uint16_t)0x0FFF)            /*!< DAC channel1 12-bit Right aligned data */
+
+/*****************  Bit definition for DAC_DHR12L1 register  ******************/
+#define  DAC_DHR12L1_DACC1DHR                ((uint16_t)0xFFF0)            /*!< DAC channel1 12-bit Left aligned data */
+
+/******************  Bit definition for DAC_DHR8R1 register  ******************/
+#define  DAC_DHR8R1_DACC1DHR                 ((uint8_t)0xFF)               /*!< DAC channel1 8-bit Right aligned data */
+
+/*****************  Bit definition for DAC_DHR12R2 register  ******************/
+#define  DAC_DHR12R2_DACC2DHR                ((uint16_t)0x0FFF)            /*!< DAC channel2 12-bit Right aligned data */
+
+/*****************  Bit definition for DAC_DHR12L2 register  ******************/
+#define  DAC_DHR12L2_DACC2DHR                ((uint16_t)0xFFF0)            /*!< DAC channel2 12-bit Left aligned data */
+
+/******************  Bit definition for DAC_DHR8R2 register  ******************/
+#define  DAC_DHR8R2_DACC2DHR                 ((uint8_t)0xFF)               /*!< DAC channel2 8-bit Right aligned data */
+
+/*****************  Bit definition for DAC_DHR12RD register  ******************/
+#define  DAC_DHR12RD_DACC1DHR                ((uint32_t)0x00000FFF)        /*!< DAC channel1 12-bit Right aligned data */
+#define  DAC_DHR12RD_DACC2DHR                ((uint32_t)0x0FFF0000)        /*!< DAC channel2 12-bit Right aligned data */
+
+/*****************  Bit definition for DAC_DHR12LD register  ******************/
+#define  DAC_DHR12LD_DACC1DHR                ((uint32_t)0x0000FFF0)        /*!< DAC channel1 12-bit Left aligned data */
+#define  DAC_DHR12LD_DACC2DHR                ((uint32_t)0xFFF00000)        /*!< DAC channel2 12-bit Left aligned data */
+
+/******************  Bit definition for DAC_DHR8RD register  ******************/
+#define  DAC_DHR8RD_DACC1DHR                 ((uint16_t)0x00FF)            /*!< DAC channel1 8-bit Right aligned data */
+#define  DAC_DHR8RD_DACC2DHR                 ((uint16_t)0xFF00)            /*!< DAC channel2 8-bit Right aligned data */
+
+/*******************  Bit definition for DAC_DOR1 register  *******************/
+#define  DAC_DOR1_DACC1DOR                   ((uint16_t)0x0FFF)            /*!< DAC channel1 data output */
+
+/*******************  Bit definition for DAC_DOR2 register  *******************/
+#define  DAC_DOR2_DACC2DOR                   ((uint16_t)0x0FFF)            /*!< DAC channel2 data output */
+
+/********************  Bit definition for DAC_SR register  ********************/
+#define  DAC_SR_DMAUDR1                      ((uint32_t)0x00002000)        /*!< DAC channel1 DMA underrun flag */
+#define  DAC_SR_DMAUDR2                      ((uint32_t)0x20000000)        /*!< DAC channel2 DMA underrun flag */
+
+/******************************************************************************/
+/*                                                                            */
+/*                                    CEC                                     */
+/*                                                                            */
+/******************************************************************************/
+/********************  Bit definition for CEC_CFGR register  ******************/
+#define  CEC_CFGR_PE              ((uint16_t)0x0001)     /*!<  Peripheral Enable */
+#define  CEC_CFGR_IE              ((uint16_t)0x0002)     /*!<  Interrupt Enable */
+#define  CEC_CFGR_BTEM            ((uint16_t)0x0004)     /*!<  Bit Timing Error Mode */
+#define  CEC_CFGR_BPEM            ((uint16_t)0x0008)     /*!<  Bit Period Error Mode */
+
+/********************  Bit definition for CEC_OAR register  ******************/
+#define  CEC_OAR_OA               ((uint16_t)0x000F)     /*!<  OA[3:0]: Own Address */
+#define  CEC_OAR_OA_0             ((uint16_t)0x0001)     /*!<  Bit 0 */
+#define  CEC_OAR_OA_1             ((uint16_t)0x0002)     /*!<  Bit 1 */
+#define  CEC_OAR_OA_2             ((uint16_t)0x0004)     /*!<  Bit 2 */
+#define  CEC_OAR_OA_3             ((uint16_t)0x0008)     /*!<  Bit 3 */
+
+/********************  Bit definition for CEC_PRES register  ******************/
+#define  CEC_PRES_PRES            ((uint16_t)0x3FFF)   /*!<  Prescaler Counter Value */
+
+/********************  Bit definition for CEC_ESR register  ******************/
+#define  CEC_ESR_BTE              ((uint16_t)0x0001)     /*!<  Bit Timing Error */
+#define  CEC_ESR_BPE              ((uint16_t)0x0002)     /*!<  Bit Period Error */
+#define  CEC_ESR_RBTFE            ((uint16_t)0x0004)     /*!<  Rx Block Transfer Finished Error */
+#define  CEC_ESR_SBE              ((uint16_t)0x0008)     /*!<  Start Bit Error */
+#define  CEC_ESR_ACKE             ((uint16_t)0x0010)     /*!<  Block Acknowledge Error */
+#define  CEC_ESR_LINE             ((uint16_t)0x0020)     /*!<  Line Error */
+#define  CEC_ESR_TBTFE            ((uint16_t)0x0040)     /*!<  Tx Block Transfer Finished Error */
+
+/********************  Bit definition for CEC_CSR register  ******************/
+#define  CEC_CSR_TSOM             ((uint16_t)0x0001)     /*!<  Tx Start Of Message */
+#define  CEC_CSR_TEOM             ((uint16_t)0x0002)     /*!<  Tx End Of Message */
+#define  CEC_CSR_TERR             ((uint16_t)0x0004)     /*!<  Tx Error */
+#define  CEC_CSR_TBTRF            ((uint16_t)0x0008)     /*!<  Tx Byte Transfer Request or Block Transfer Finished */
+#define  CEC_CSR_RSOM             ((uint16_t)0x0010)     /*!<  Rx Start Of Message */
+#define  CEC_CSR_REOM             ((uint16_t)0x0020)     /*!<  Rx End Of Message */
+#define  CEC_CSR_RERR             ((uint16_t)0x0040)     /*!<  Rx Error */
+#define  CEC_CSR_RBTF             ((uint16_t)0x0080)     /*!<  Rx Block Transfer Finished */
+
+/********************  Bit definition for CEC_TXD register  ******************/
+#define  CEC_TXD_TXD              ((uint16_t)0x00FF)     /*!<  Tx Data register */
+
+/********************  Bit definition for CEC_RXD register  ******************/
+#define  CEC_RXD_RXD              ((uint16_t)0x00FF)     /*!<  Rx Data register */
+
+/******************************************************************************/
+/*                                                                            */
+/*                                    TIM                                     */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for TIM_CR1 register  ********************/
+#define  TIM_CR1_CEN                         ((uint16_t)0x0001)            /*!< Counter enable */
+#define  TIM_CR1_UDIS                        ((uint16_t)0x0002)            /*!< Update disable */
+#define  TIM_CR1_URS                         ((uint16_t)0x0004)            /*!< Update request source */
+#define  TIM_CR1_OPM                         ((uint16_t)0x0008)            /*!< One pulse mode */
+#define  TIM_CR1_DIR                         ((uint16_t)0x0010)            /*!< Direction */
+
+#define  TIM_CR1_CMS                         ((uint16_t)0x0060)            /*!< CMS[1:0] bits (Center-aligned mode selection) */
+#define  TIM_CR1_CMS_0                       ((uint16_t)0x0020)            /*!< Bit 0 */
+#define  TIM_CR1_CMS_1                       ((uint16_t)0x0040)            /*!< Bit 1 */
+
+#define  TIM_CR1_ARPE                        ((uint16_t)0x0080)            /*!< Auto-reload preload enable */
+
+#define  TIM_CR1_CKD                         ((uint16_t)0x0300)            /*!< CKD[1:0] bits (clock division) */
+#define  TIM_CR1_CKD_0                       ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_CR1_CKD_1                       ((uint16_t)0x0200)            /*!< Bit 1 */
+
+/*******************  Bit definition for TIM_CR2 register  ********************/
+#define  TIM_CR2_CCPC                        ((uint16_t)0x0001)            /*!< Capture/Compare Preloaded Control */
+#define  TIM_CR2_CCUS                        ((uint16_t)0x0004)            /*!< Capture/Compare Control Update Selection */
+#define  TIM_CR2_CCDS                        ((uint16_t)0x0008)            /*!< Capture/Compare DMA Selection */
+
+#define  TIM_CR2_MMS                         ((uint16_t)0x0070)            /*!< MMS[2:0] bits (Master Mode Selection) */
+#define  TIM_CR2_MMS_0                       ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_CR2_MMS_1                       ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_CR2_MMS_2                       ((uint16_t)0x0040)            /*!< Bit 2 */
+
+#define  TIM_CR2_TI1S                        ((uint16_t)0x0080)            /*!< TI1 Selection */
+#define  TIM_CR2_OIS1                        ((uint16_t)0x0100)            /*!< Output Idle state 1 (OC1 output) */
+#define  TIM_CR2_OIS1N                       ((uint16_t)0x0200)            /*!< Output Idle state 1 (OC1N output) */
+#define  TIM_CR2_OIS2                        ((uint16_t)0x0400)            /*!< Output Idle state 2 (OC2 output) */
+#define  TIM_CR2_OIS2N                       ((uint16_t)0x0800)            /*!< Output Idle state 2 (OC2N output) */
+#define  TIM_CR2_OIS3                        ((uint16_t)0x1000)            /*!< Output Idle state 3 (OC3 output) */
+#define  TIM_CR2_OIS3N                       ((uint16_t)0x2000)            /*!< Output Idle state 3 (OC3N output) */
+#define  TIM_CR2_OIS4                        ((uint16_t)0x4000)            /*!< Output Idle state 4 (OC4 output) */
+
+/*******************  Bit definition for TIM_SMCR register  *******************/
+#define  TIM_SMCR_SMS                        ((uint16_t)0x0007)            /*!< SMS[2:0] bits (Slave mode selection) */
+#define  TIM_SMCR_SMS_0                      ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  TIM_SMCR_SMS_1                      ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  TIM_SMCR_SMS_2                      ((uint16_t)0x0004)            /*!< Bit 2 */
+
+#define  TIM_SMCR_TS                         ((uint16_t)0x0070)            /*!< TS[2:0] bits (Trigger selection) */
+#define  TIM_SMCR_TS_0                       ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_SMCR_TS_1                       ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_SMCR_TS_2                       ((uint16_t)0x0040)            /*!< Bit 2 */
+
+#define  TIM_SMCR_MSM                        ((uint16_t)0x0080)            /*!< Master/slave mode */
+
+#define  TIM_SMCR_ETF                        ((uint16_t)0x0F00)            /*!< ETF[3:0] bits (External trigger filter) */
+#define  TIM_SMCR_ETF_0                      ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_SMCR_ETF_1                      ((uint16_t)0x0200)            /*!< Bit 1 */
+#define  TIM_SMCR_ETF_2                      ((uint16_t)0x0400)            /*!< Bit 2 */
+#define  TIM_SMCR_ETF_3                      ((uint16_t)0x0800)            /*!< Bit 3 */
+
+#define  TIM_SMCR_ETPS                       ((uint16_t)0x3000)            /*!< ETPS[1:0] bits (External trigger prescaler) */
+#define  TIM_SMCR_ETPS_0                     ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  TIM_SMCR_ETPS_1                     ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  TIM_SMCR_ECE                        ((uint16_t)0x4000)            /*!< External clock enable */
+#define  TIM_SMCR_ETP                        ((uint16_t)0x8000)            /*!< External trigger polarity */
+
+/*******************  Bit definition for TIM_DIER register  *******************/
+#define  TIM_DIER_UIE                        ((uint16_t)0x0001)            /*!< Update interrupt enable */
+#define  TIM_DIER_CC1IE                      ((uint16_t)0x0002)            /*!< Capture/Compare 1 interrupt enable */
+#define  TIM_DIER_CC2IE                      ((uint16_t)0x0004)            /*!< Capture/Compare 2 interrupt enable */
+#define  TIM_DIER_CC3IE                      ((uint16_t)0x0008)            /*!< Capture/Compare 3 interrupt enable */
+#define  TIM_DIER_CC4IE                      ((uint16_t)0x0010)            /*!< Capture/Compare 4 interrupt enable */
+#define  TIM_DIER_COMIE                      ((uint16_t)0x0020)            /*!< COM interrupt enable */
+#define  TIM_DIER_TIE                        ((uint16_t)0x0040)            /*!< Trigger interrupt enable */
+#define  TIM_DIER_BIE                        ((uint16_t)0x0080)            /*!< Break interrupt enable */
+#define  TIM_DIER_UDE                        ((uint16_t)0x0100)            /*!< Update DMA request enable */
+#define  TIM_DIER_CC1DE                      ((uint16_t)0x0200)            /*!< Capture/Compare 1 DMA request enable */
+#define  TIM_DIER_CC2DE                      ((uint16_t)0x0400)            /*!< Capture/Compare 2 DMA request enable */
+#define  TIM_DIER_CC3DE                      ((uint16_t)0x0800)            /*!< Capture/Compare 3 DMA request enable */
+#define  TIM_DIER_CC4DE                      ((uint16_t)0x1000)            /*!< Capture/Compare 4 DMA request enable */
+#define  TIM_DIER_COMDE                      ((uint16_t)0x2000)            /*!< COM DMA request enable */
+#define  TIM_DIER_TDE                        ((uint16_t)0x4000)            /*!< Trigger DMA request enable */
+
+/********************  Bit definition for TIM_SR register  ********************/
+#define  TIM_SR_UIF                          ((uint16_t)0x0001)            /*!< Update interrupt Flag */
+#define  TIM_SR_CC1IF                        ((uint16_t)0x0002)            /*!< Capture/Compare 1 interrupt Flag */
+#define  TIM_SR_CC2IF                        ((uint16_t)0x0004)            /*!< Capture/Compare 2 interrupt Flag */
+#define  TIM_SR_CC3IF                        ((uint16_t)0x0008)            /*!< Capture/Compare 3 interrupt Flag */
+#define  TIM_SR_CC4IF                        ((uint16_t)0x0010)            /*!< Capture/Compare 4 interrupt Flag */
+#define  TIM_SR_COMIF                        ((uint16_t)0x0020)            /*!< COM interrupt Flag */
+#define  TIM_SR_TIF                          ((uint16_t)0x0040)            /*!< Trigger interrupt Flag */
+#define  TIM_SR_BIF                          ((uint16_t)0x0080)            /*!< Break interrupt Flag */
+#define  TIM_SR_CC1OF                        ((uint16_t)0x0200)            /*!< Capture/Compare 1 Overcapture Flag */
+#define  TIM_SR_CC2OF                        ((uint16_t)0x0400)            /*!< Capture/Compare 2 Overcapture Flag */
+#define  TIM_SR_CC3OF                        ((uint16_t)0x0800)            /*!< Capture/Compare 3 Overcapture Flag */
+#define  TIM_SR_CC4OF                        ((uint16_t)0x1000)            /*!< Capture/Compare 4 Overcapture Flag */
+
+/*******************  Bit definition for TIM_EGR register  ********************/
+#define  TIM_EGR_UG                          ((uint8_t)0x01)               /*!< Update Generation */
+#define  TIM_EGR_CC1G                        ((uint8_t)0x02)               /*!< Capture/Compare 1 Generation */
+#define  TIM_EGR_CC2G                        ((uint8_t)0x04)               /*!< Capture/Compare 2 Generation */
+#define  TIM_EGR_CC3G                        ((uint8_t)0x08)               /*!< Capture/Compare 3 Generation */
+#define  TIM_EGR_CC4G                        ((uint8_t)0x10)               /*!< Capture/Compare 4 Generation */
+#define  TIM_EGR_COMG                        ((uint8_t)0x20)               /*!< Capture/Compare Control Update Generation */
+#define  TIM_EGR_TG                          ((uint8_t)0x40)               /*!< Trigger Generation */
+#define  TIM_EGR_BG                          ((uint8_t)0x80)               /*!< Break Generation */
+
+/******************  Bit definition for TIM_CCMR1 register  *******************/
+#define  TIM_CCMR1_CC1S                      ((uint16_t)0x0003)            /*!< CC1S[1:0] bits (Capture/Compare 1 Selection) */
+#define  TIM_CCMR1_CC1S_0                    ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  TIM_CCMR1_CC1S_1                    ((uint16_t)0x0002)            /*!< Bit 1 */
+
+#define  TIM_CCMR1_OC1FE                     ((uint16_t)0x0004)            /*!< Output Compare 1 Fast enable */
+#define  TIM_CCMR1_OC1PE                     ((uint16_t)0x0008)            /*!< Output Compare 1 Preload enable */
+
+#define  TIM_CCMR1_OC1M                      ((uint16_t)0x0070)            /*!< OC1M[2:0] bits (Output Compare 1 Mode) */
+#define  TIM_CCMR1_OC1M_0                    ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_CCMR1_OC1M_1                    ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_CCMR1_OC1M_2                    ((uint16_t)0x0040)            /*!< Bit 2 */
+
+#define  TIM_CCMR1_OC1CE                     ((uint16_t)0x0080)            /*!< Output Compare 1Clear Enable */
+
+#define  TIM_CCMR1_CC2S                      ((uint16_t)0x0300)            /*!< CC2S[1:0] bits (Capture/Compare 2 Selection) */
+#define  TIM_CCMR1_CC2S_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_CCMR1_CC2S_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  TIM_CCMR1_OC2FE                     ((uint16_t)0x0400)            /*!< Output Compare 2 Fast enable */
+#define  TIM_CCMR1_OC2PE                     ((uint16_t)0x0800)            /*!< Output Compare 2 Preload enable */
+
+#define  TIM_CCMR1_OC2M                      ((uint16_t)0x7000)            /*!< OC2M[2:0] bits (Output Compare 2 Mode) */
+#define  TIM_CCMR1_OC2M_0                    ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  TIM_CCMR1_OC2M_1                    ((uint16_t)0x2000)            /*!< Bit 1 */
+#define  TIM_CCMR1_OC2M_2                    ((uint16_t)0x4000)            /*!< Bit 2 */
+
+#define  TIM_CCMR1_OC2CE                     ((uint16_t)0x8000)            /*!< Output Compare 2 Clear Enable */
+
+/*----------------------------------------------------------------------------*/
+
+#define  TIM_CCMR1_IC1PSC                    ((uint16_t)0x000C)            /*!< IC1PSC[1:0] bits (Input Capture 1 Prescaler) */
+#define  TIM_CCMR1_IC1PSC_0                  ((uint16_t)0x0004)            /*!< Bit 0 */
+#define  TIM_CCMR1_IC1PSC_1                  ((uint16_t)0x0008)            /*!< Bit 1 */
+
+#define  TIM_CCMR1_IC1F                      ((uint16_t)0x00F0)            /*!< IC1F[3:0] bits (Input Capture 1 Filter) */
+#define  TIM_CCMR1_IC1F_0                    ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_CCMR1_IC1F_1                    ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_CCMR1_IC1F_2                    ((uint16_t)0x0040)            /*!< Bit 2 */
+#define  TIM_CCMR1_IC1F_3                    ((uint16_t)0x0080)            /*!< Bit 3 */
+
+#define  TIM_CCMR1_IC2PSC                    ((uint16_t)0x0C00)            /*!< IC2PSC[1:0] bits (Input Capture 2 Prescaler) */
+#define  TIM_CCMR1_IC2PSC_0                  ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  TIM_CCMR1_IC2PSC_1                  ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  TIM_CCMR1_IC2F                      ((uint16_t)0xF000)            /*!< IC2F[3:0] bits (Input Capture 2 Filter) */
+#define  TIM_CCMR1_IC2F_0                    ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  TIM_CCMR1_IC2F_1                    ((uint16_t)0x2000)            /*!< Bit 1 */
+#define  TIM_CCMR1_IC2F_2                    ((uint16_t)0x4000)            /*!< Bit 2 */
+#define  TIM_CCMR1_IC2F_3                    ((uint16_t)0x8000)            /*!< Bit 3 */
+
+/******************  Bit definition for TIM_CCMR2 register  *******************/
+#define  TIM_CCMR2_CC3S                      ((uint16_t)0x0003)            /*!< CC3S[1:0] bits (Capture/Compare 3 Selection) */
+#define  TIM_CCMR2_CC3S_0                    ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  TIM_CCMR2_CC3S_1                    ((uint16_t)0x0002)            /*!< Bit 1 */
+
+#define  TIM_CCMR2_OC3FE                     ((uint16_t)0x0004)            /*!< Output Compare 3 Fast enable */
+#define  TIM_CCMR2_OC3PE                     ((uint16_t)0x0008)            /*!< Output Compare 3 Preload enable */
+
+#define  TIM_CCMR2_OC3M                      ((uint16_t)0x0070)            /*!< OC3M[2:0] bits (Output Compare 3 Mode) */
+#define  TIM_CCMR2_OC3M_0                    ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_CCMR2_OC3M_1                    ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_CCMR2_OC3M_2                    ((uint16_t)0x0040)            /*!< Bit 2 */
+
+#define  TIM_CCMR2_OC3CE                     ((uint16_t)0x0080)            /*!< Output Compare 3 Clear Enable */
+
+#define  TIM_CCMR2_CC4S                      ((uint16_t)0x0300)            /*!< CC4S[1:0] bits (Capture/Compare 4 Selection) */
+#define  TIM_CCMR2_CC4S_0                    ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_CCMR2_CC4S_1                    ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  TIM_CCMR2_OC4FE                     ((uint16_t)0x0400)            /*!< Output Compare 4 Fast enable */
+#define  TIM_CCMR2_OC4PE                     ((uint16_t)0x0800)            /*!< Output Compare 4 Preload enable */
+
+#define  TIM_CCMR2_OC4M                      ((uint16_t)0x7000)            /*!< OC4M[2:0] bits (Output Compare 4 Mode) */
+#define  TIM_CCMR2_OC4M_0                    ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  TIM_CCMR2_OC4M_1                    ((uint16_t)0x2000)            /*!< Bit 1 */
+#define  TIM_CCMR2_OC4M_2                    ((uint16_t)0x4000)            /*!< Bit 2 */
+
+#define  TIM_CCMR2_OC4CE                     ((uint16_t)0x8000)            /*!< Output Compare 4 Clear Enable */
+
+/*----------------------------------------------------------------------------*/
+
+#define  TIM_CCMR2_IC3PSC                    ((uint16_t)0x000C)            /*!< IC3PSC[1:0] bits (Input Capture 3 Prescaler) */
+#define  TIM_CCMR2_IC3PSC_0                  ((uint16_t)0x0004)            /*!< Bit 0 */
+#define  TIM_CCMR2_IC3PSC_1                  ((uint16_t)0x0008)            /*!< Bit 1 */
+
+#define  TIM_CCMR2_IC3F                      ((uint16_t)0x00F0)            /*!< IC3F[3:0] bits (Input Capture 3 Filter) */
+#define  TIM_CCMR2_IC3F_0                    ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  TIM_CCMR2_IC3F_1                    ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  TIM_CCMR2_IC3F_2                    ((uint16_t)0x0040)            /*!< Bit 2 */
+#define  TIM_CCMR2_IC3F_3                    ((uint16_t)0x0080)            /*!< Bit 3 */
+
+#define  TIM_CCMR2_IC4PSC                    ((uint16_t)0x0C00)            /*!< IC4PSC[1:0] bits (Input Capture 4 Prescaler) */
+#define  TIM_CCMR2_IC4PSC_0                  ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  TIM_CCMR2_IC4PSC_1                  ((uint16_t)0x0800)            /*!< Bit 1 */
+
+#define  TIM_CCMR2_IC4F                      ((uint16_t)0xF000)            /*!< IC4F[3:0] bits (Input Capture 4 Filter) */
+#define  TIM_CCMR2_IC4F_0                    ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  TIM_CCMR2_IC4F_1                    ((uint16_t)0x2000)            /*!< Bit 1 */
+#define  TIM_CCMR2_IC4F_2                    ((uint16_t)0x4000)            /*!< Bit 2 */
+#define  TIM_CCMR2_IC4F_3                    ((uint16_t)0x8000)            /*!< Bit 3 */
+
+/*******************  Bit definition for TIM_CCER register  *******************/
+#define  TIM_CCER_CC1E                       ((uint16_t)0x0001)            /*!< Capture/Compare 1 output enable */
+#define  TIM_CCER_CC1P                       ((uint16_t)0x0002)            /*!< Capture/Compare 1 output Polarity */
+#define  TIM_CCER_CC1NE                      ((uint16_t)0x0004)            /*!< Capture/Compare 1 Complementary output enable */
+#define  TIM_CCER_CC1NP                      ((uint16_t)0x0008)            /*!< Capture/Compare 1 Complementary output Polarity */
+#define  TIM_CCER_CC2E                       ((uint16_t)0x0010)            /*!< Capture/Compare 2 output enable */
+#define  TIM_CCER_CC2P                       ((uint16_t)0x0020)            /*!< Capture/Compare 2 output Polarity */
+#define  TIM_CCER_CC2NE                      ((uint16_t)0x0040)            /*!< Capture/Compare 2 Complementary output enable */
+#define  TIM_CCER_CC2NP                      ((uint16_t)0x0080)            /*!< Capture/Compare 2 Complementary output Polarity */
+#define  TIM_CCER_CC3E                       ((uint16_t)0x0100)            /*!< Capture/Compare 3 output enable */
+#define  TIM_CCER_CC3P                       ((uint16_t)0x0200)            /*!< Capture/Compare 3 output Polarity */
+#define  TIM_CCER_CC3NE                      ((uint16_t)0x0400)            /*!< Capture/Compare 3 Complementary output enable */
+#define  TIM_CCER_CC3NP                      ((uint16_t)0x0800)            /*!< Capture/Compare 3 Complementary output Polarity */
+#define  TIM_CCER_CC4E                       ((uint16_t)0x1000)            /*!< Capture/Compare 4 output enable */
+#define  TIM_CCER_CC4P                       ((uint16_t)0x2000)            /*!< Capture/Compare 4 output Polarity */
+#define  TIM_CCER_CC4NP                      ((uint16_t)0x8000)            /*!< Capture/Compare 4 Complementary output Polarity */
+
+/*******************  Bit definition for TIM_CNT register  ********************/
+#define  TIM_CNT_CNT                         ((uint16_t)0xFFFF)            /*!< Counter Value */
+
+/*******************  Bit definition for TIM_PSC register  ********************/
+#define  TIM_PSC_PSC                         ((uint16_t)0xFFFF)            /*!< Prescaler Value */
+
+/*******************  Bit definition for TIM_ARR register  ********************/
+#define  TIM_ARR_ARR                         ((uint16_t)0xFFFF)            /*!< actual auto-reload Value */
+
+/*******************  Bit definition for TIM_RCR register  ********************/
+#define  TIM_RCR_REP                         ((uint8_t)0xFF)               /*!< Repetition Counter Value */
+
+/*******************  Bit definition for TIM_CCR1 register  *******************/
+#define  TIM_CCR1_CCR1                       ((uint16_t)0xFFFF)            /*!< Capture/Compare 1 Value */
+
+/*******************  Bit definition for TIM_CCR2 register  *******************/
+#define  TIM_CCR2_CCR2                       ((uint16_t)0xFFFF)            /*!< Capture/Compare 2 Value */
+
+/*******************  Bit definition for TIM_CCR3 register  *******************/
+#define  TIM_CCR3_CCR3                       ((uint16_t)0xFFFF)            /*!< Capture/Compare 3 Value */
+
+/*******************  Bit definition for TIM_CCR4 register  *******************/
+#define  TIM_CCR4_CCR4                       ((uint16_t)0xFFFF)            /*!< Capture/Compare 4 Value */
+
+/*******************  Bit definition for TIM_BDTR register  *******************/
+#define  TIM_BDTR_DTG                        ((uint16_t)0x00FF)            /*!< DTG[0:7] bits (Dead-Time Generator set-up) */
+#define  TIM_BDTR_DTG_0                      ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  TIM_BDTR_DTG_1                      ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  TIM_BDTR_DTG_2                      ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  TIM_BDTR_DTG_3                      ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  TIM_BDTR_DTG_4                      ((uint16_t)0x0010)            /*!< Bit 4 */
+#define  TIM_BDTR_DTG_5                      ((uint16_t)0x0020)            /*!< Bit 5 */
+#define  TIM_BDTR_DTG_6                      ((uint16_t)0x0040)            /*!< Bit 6 */
+#define  TIM_BDTR_DTG_7                      ((uint16_t)0x0080)            /*!< Bit 7 */
+
+#define  TIM_BDTR_LOCK                       ((uint16_t)0x0300)            /*!< LOCK[1:0] bits (Lock Configuration) */
+#define  TIM_BDTR_LOCK_0                     ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_BDTR_LOCK_1                     ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  TIM_BDTR_OSSI                       ((uint16_t)0x0400)            /*!< Off-State Selection for Idle mode */
+#define  TIM_BDTR_OSSR                       ((uint16_t)0x0800)            /*!< Off-State Selection for Run mode */
+#define  TIM_BDTR_BKE                        ((uint16_t)0x1000)            /*!< Break enable */
+#define  TIM_BDTR_BKP                        ((uint16_t)0x2000)            /*!< Break Polarity */
+#define  TIM_BDTR_AOE                        ((uint16_t)0x4000)            /*!< Automatic Output enable */
+#define  TIM_BDTR_MOE                        ((uint16_t)0x8000)            /*!< Main Output enable */
+
+/*******************  Bit definition for TIM_DCR register  ********************/
+#define  TIM_DCR_DBA                         ((uint16_t)0x001F)            /*!< DBA[4:0] bits (DMA Base Address) */
+#define  TIM_DCR_DBA_0                       ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  TIM_DCR_DBA_1                       ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  TIM_DCR_DBA_2                       ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  TIM_DCR_DBA_3                       ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  TIM_DCR_DBA_4                       ((uint16_t)0x0010)            /*!< Bit 4 */
+
+#define  TIM_DCR_DBL                         ((uint16_t)0x1F00)            /*!< DBL[4:0] bits (DMA Burst Length) */
+#define  TIM_DCR_DBL_0                       ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  TIM_DCR_DBL_1                       ((uint16_t)0x0200)            /*!< Bit 1 */
+#define  TIM_DCR_DBL_2                       ((uint16_t)0x0400)            /*!< Bit 2 */
+#define  TIM_DCR_DBL_3                       ((uint16_t)0x0800)            /*!< Bit 3 */
+#define  TIM_DCR_DBL_4                       ((uint16_t)0x1000)            /*!< Bit 4 */
+
+/*******************  Bit definition for TIM_DMAR register  *******************/
+#define  TIM_DMAR_DMAB                       ((uint16_t)0xFFFF)            /*!< DMA register for burst accesses */
+
+/******************************************************************************/
+/*                                                                            */
+/*                             Real-Time Clock                                */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for RTC_CRH register  ********************/
+#define  RTC_CRH_SECIE                       ((uint8_t)0x01)               /*!< Second Interrupt Enable */
+#define  RTC_CRH_ALRIE                       ((uint8_t)0x02)               /*!< Alarm Interrupt Enable */
+#define  RTC_CRH_OWIE                        ((uint8_t)0x04)               /*!< OverfloW Interrupt Enable */
+
+/*******************  Bit definition for RTC_CRL register  ********************/
+#define  RTC_CRL_SECF                        ((uint8_t)0x01)               /*!< Second Flag */
+#define  RTC_CRL_ALRF                        ((uint8_t)0x02)               /*!< Alarm Flag */
+#define  RTC_CRL_OWF                         ((uint8_t)0x04)               /*!< OverfloW Flag */
+#define  RTC_CRL_RSF                         ((uint8_t)0x08)               /*!< Registers Synchronized Flag */
+#define  RTC_CRL_CNF                         ((uint8_t)0x10)               /*!< Configuration Flag */
+#define  RTC_CRL_RTOFF                       ((uint8_t)0x20)               /*!< RTC operation OFF */
+
+/*******************  Bit definition for RTC_PRLH register  *******************/
+#define  RTC_PRLH_PRL                        ((uint16_t)0x000F)            /*!< RTC Prescaler Reload Value High */
+
+/*******************  Bit definition for RTC_PRLL register  *******************/
+#define  RTC_PRLL_PRL                        ((uint16_t)0xFFFF)            /*!< RTC Prescaler Reload Value Low */
+
+/*******************  Bit definition for RTC_DIVH register  *******************/
+#define  RTC_DIVH_RTC_DIV                    ((uint16_t)0x000F)            /*!< RTC Clock Divider High */
+
+/*******************  Bit definition for RTC_DIVL register  *******************/
+#define  RTC_DIVL_RTC_DIV                    ((uint16_t)0xFFFF)            /*!< RTC Clock Divider Low */
+
+/*******************  Bit definition for RTC_CNTH register  *******************/
+#define  RTC_CNTH_RTC_CNT                    ((uint16_t)0xFFFF)            /*!< RTC Counter High */
+
+/*******************  Bit definition for RTC_CNTL register  *******************/
+#define  RTC_CNTL_RTC_CNT                    ((uint16_t)0xFFFF)            /*!< RTC Counter Low */
+
+/*******************  Bit definition for RTC_ALRH register  *******************/
+#define  RTC_ALRH_RTC_ALR                    ((uint16_t)0xFFFF)            /*!< RTC Alarm High */
+
+/*******************  Bit definition for RTC_ALRL register  *******************/
+#define  RTC_ALRL_RTC_ALR                    ((uint16_t)0xFFFF)            /*!< RTC Alarm Low */
+
+/******************************************************************************/
+/*                                                                            */
+/*                           Independent WATCHDOG                             */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for IWDG_KR register  ********************/
+#define  IWDG_KR_KEY                         ((uint16_t)0xFFFF)            /*!< Key value (write only, read 0000h) */
+
+/*******************  Bit definition for IWDG_PR register  ********************/
+#define  IWDG_PR_PR                          ((uint8_t)0x07)               /*!< PR[2:0] (Prescaler divider) */
+#define  IWDG_PR_PR_0                        ((uint8_t)0x01)               /*!< Bit 0 */
+#define  IWDG_PR_PR_1                        ((uint8_t)0x02)               /*!< Bit 1 */
+#define  IWDG_PR_PR_2                        ((uint8_t)0x04)               /*!< Bit 2 */
+
+/*******************  Bit definition for IWDG_RLR register  *******************/
+#define  IWDG_RLR_RL                         ((uint16_t)0x0FFF)            /*!< Watchdog counter reload value */
+
+/*******************  Bit definition for IWDG_SR register  ********************/
+#define  IWDG_SR_PVU                         ((uint8_t)0x01)               /*!< Watchdog prescaler value update */
+#define  IWDG_SR_RVU                         ((uint8_t)0x02)               /*!< Watchdog counter reload value update */
+
+/******************************************************************************/
+/*                                                                            */
+/*                            Window WATCHDOG                                 */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for WWDG_CR register  ********************/
+#define  WWDG_CR_T                           ((uint8_t)0x7F)               /*!< T[6:0] bits (7-Bit counter (MSB to LSB)) */
+#define  WWDG_CR_T0                          ((uint8_t)0x01)               /*!< Bit 0 */
+#define  WWDG_CR_T1                          ((uint8_t)0x02)               /*!< Bit 1 */
+#define  WWDG_CR_T2                          ((uint8_t)0x04)               /*!< Bit 2 */
+#define  WWDG_CR_T3                          ((uint8_t)0x08)               /*!< Bit 3 */
+#define  WWDG_CR_T4                          ((uint8_t)0x10)               /*!< Bit 4 */
+#define  WWDG_CR_T5                          ((uint8_t)0x20)               /*!< Bit 5 */
+#define  WWDG_CR_T6                          ((uint8_t)0x40)               /*!< Bit 6 */
+
+#define  WWDG_CR_WDGA                        ((uint8_t)0x80)               /*!< Activation bit */
+
+/*******************  Bit definition for WWDG_CFR register  *******************/
+#define  WWDG_CFR_W                          ((uint16_t)0x007F)            /*!< W[6:0] bits (7-bit window value) */
+#define  WWDG_CFR_W0                         ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  WWDG_CFR_W1                         ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  WWDG_CFR_W2                         ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  WWDG_CFR_W3                         ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  WWDG_CFR_W4                         ((uint16_t)0x0010)            /*!< Bit 4 */
+#define  WWDG_CFR_W5                         ((uint16_t)0x0020)            /*!< Bit 5 */
+#define  WWDG_CFR_W6                         ((uint16_t)0x0040)            /*!< Bit 6 */
+
+#define  WWDG_CFR_WDGTB                      ((uint16_t)0x0180)            /*!< WDGTB[1:0] bits (Timer Base) */
+#define  WWDG_CFR_WDGTB0                     ((uint16_t)0x0080)            /*!< Bit 0 */
+#define  WWDG_CFR_WDGTB1                     ((uint16_t)0x0100)            /*!< Bit 1 */
+
+#define  WWDG_CFR_EWI                        ((uint16_t)0x0200)            /*!< Early Wakeup Interrupt */
+
+/*******************  Bit definition for WWDG_SR register  ********************/
+#define  WWDG_SR_EWIF                        ((uint8_t)0x01)               /*!< Early Wakeup Interrupt Flag */
+
+/******************************************************************************/
+/*                                                                            */
+/*                       Flexible Static Memory Controller                    */
+/*                                                                            */
+/******************************************************************************/
+
+/******************  Bit definition for FSMC_BCR1 register  *******************/
+#define  FSMC_BCR1_MBKEN                     ((uint32_t)0x00000001)        /*!< Memory bank enable bit */
+#define  FSMC_BCR1_MUXEN                     ((uint32_t)0x00000002)        /*!< Address/data multiplexing enable bit */
+
+#define  FSMC_BCR1_MTYP                      ((uint32_t)0x0000000C)        /*!< MTYP[1:0] bits (Memory type) */
+#define  FSMC_BCR1_MTYP_0                    ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  FSMC_BCR1_MTYP_1                    ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  FSMC_BCR1_MWID                      ((uint32_t)0x00000030)        /*!< MWID[1:0] bits (Memory data bus width) */
+#define  FSMC_BCR1_MWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BCR1_MWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_BCR1_FACCEN                    ((uint32_t)0x00000040)        /*!< Flash access enable */
+#define  FSMC_BCR1_BURSTEN                   ((uint32_t)0x00000100)        /*!< Burst enable bit */
+#define  FSMC_BCR1_WAITPOL                   ((uint32_t)0x00000200)        /*!< Wait signal polarity bit */
+#define  FSMC_BCR1_WRAPMOD                   ((uint32_t)0x00000400)        /*!< Wrapped burst mode support */
+#define  FSMC_BCR1_WAITCFG                   ((uint32_t)0x00000800)        /*!< Wait timing configuration */
+#define  FSMC_BCR1_WREN                      ((uint32_t)0x00001000)        /*!< Write enable bit */
+#define  FSMC_BCR1_WAITEN                    ((uint32_t)0x00002000)        /*!< Wait enable bit */
+#define  FSMC_BCR1_EXTMOD                    ((uint32_t)0x00004000)        /*!< Extended mode enable */
+#define  FSMC_BCR1_ASYNCWAIT                 ((uint32_t)0x00008000)       /*!< Asynchronous wait */
+#define  FSMC_BCR1_CBURSTRW                  ((uint32_t)0x00080000)        /*!< Write burst enable */
+
+/******************  Bit definition for FSMC_BCR2 register  *******************/
+#define  FSMC_BCR2_MBKEN                     ((uint32_t)0x00000001)        /*!< Memory bank enable bit */
+#define  FSMC_BCR2_MUXEN                     ((uint32_t)0x00000002)        /*!< Address/data multiplexing enable bit */
+
+#define  FSMC_BCR2_MTYP                      ((uint32_t)0x0000000C)        /*!< MTYP[1:0] bits (Memory type) */
+#define  FSMC_BCR2_MTYP_0                    ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  FSMC_BCR2_MTYP_1                    ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  FSMC_BCR2_MWID                      ((uint32_t)0x00000030)        /*!< MWID[1:0] bits (Memory data bus width) */
+#define  FSMC_BCR2_MWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BCR2_MWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_BCR2_FACCEN                    ((uint32_t)0x00000040)        /*!< Flash access enable */
+#define  FSMC_BCR2_BURSTEN                   ((uint32_t)0x00000100)        /*!< Burst enable bit */
+#define  FSMC_BCR2_WAITPOL                   ((uint32_t)0x00000200)        /*!< Wait signal polarity bit */
+#define  FSMC_BCR2_WRAPMOD                   ((uint32_t)0x00000400)        /*!< Wrapped burst mode support */
+#define  FSMC_BCR2_WAITCFG                   ((uint32_t)0x00000800)        /*!< Wait timing configuration */
+#define  FSMC_BCR2_WREN                      ((uint32_t)0x00001000)        /*!< Write enable bit */
+#define  FSMC_BCR2_WAITEN                    ((uint32_t)0x00002000)        /*!< Wait enable bit */
+#define  FSMC_BCR2_EXTMOD                    ((uint32_t)0x00004000)        /*!< Extended mode enable */
+#define  FSMC_BCR2_ASYNCWAIT                 ((uint32_t)0x00008000)       /*!< Asynchronous wait */
+#define  FSMC_BCR2_CBURSTRW                  ((uint32_t)0x00080000)        /*!< Write burst enable */
+
+/******************  Bit definition for FSMC_BCR3 register  *******************/
+#define  FSMC_BCR3_MBKEN                     ((uint32_t)0x00000001)        /*!< Memory bank enable bit */
+#define  FSMC_BCR3_MUXEN                     ((uint32_t)0x00000002)        /*!< Address/data multiplexing enable bit */
+
+#define  FSMC_BCR3_MTYP                      ((uint32_t)0x0000000C)        /*!< MTYP[1:0] bits (Memory type) */
+#define  FSMC_BCR3_MTYP_0                    ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  FSMC_BCR3_MTYP_1                    ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  FSMC_BCR3_MWID                      ((uint32_t)0x00000030)        /*!< MWID[1:0] bits (Memory data bus width) */
+#define  FSMC_BCR3_MWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BCR3_MWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_BCR3_FACCEN                    ((uint32_t)0x00000040)        /*!< Flash access enable */
+#define  FSMC_BCR3_BURSTEN                   ((uint32_t)0x00000100)        /*!< Burst enable bit */
+#define  FSMC_BCR3_WAITPOL                   ((uint32_t)0x00000200)        /*!< Wait signal polarity bit. */
+#define  FSMC_BCR3_WRAPMOD                   ((uint32_t)0x00000400)        /*!< Wrapped burst mode support */
+#define  FSMC_BCR3_WAITCFG                   ((uint32_t)0x00000800)        /*!< Wait timing configuration */
+#define  FSMC_BCR3_WREN                      ((uint32_t)0x00001000)        /*!< Write enable bit */
+#define  FSMC_BCR3_WAITEN                    ((uint32_t)0x00002000)        /*!< Wait enable bit */
+#define  FSMC_BCR3_EXTMOD                    ((uint32_t)0x00004000)        /*!< Extended mode enable */
+#define  FSMC_BCR3_ASYNCWAIT                 ((uint32_t)0x00008000)       /*!< Asynchronous wait */
+#define  FSMC_BCR3_CBURSTRW                  ((uint32_t)0x00080000)        /*!< Write burst enable */
+
+/******************  Bit definition for FSMC_BCR4 register  *******************/
+#define  FSMC_BCR4_MBKEN                     ((uint32_t)0x00000001)        /*!< Memory bank enable bit */
+#define  FSMC_BCR4_MUXEN                     ((uint32_t)0x00000002)        /*!< Address/data multiplexing enable bit */
+
+#define  FSMC_BCR4_MTYP                      ((uint32_t)0x0000000C)        /*!< MTYP[1:0] bits (Memory type) */
+#define  FSMC_BCR4_MTYP_0                    ((uint32_t)0x00000004)        /*!< Bit 0 */
+#define  FSMC_BCR4_MTYP_1                    ((uint32_t)0x00000008)        /*!< Bit 1 */
+
+#define  FSMC_BCR4_MWID                      ((uint32_t)0x00000030)        /*!< MWID[1:0] bits (Memory data bus width) */
+#define  FSMC_BCR4_MWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BCR4_MWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_BCR4_FACCEN                    ((uint32_t)0x00000040)        /*!< Flash access enable */
+#define  FSMC_BCR4_BURSTEN                   ((uint32_t)0x00000100)        /*!< Burst enable bit */
+#define  FSMC_BCR4_WAITPOL                   ((uint32_t)0x00000200)        /*!< Wait signal polarity bit */
+#define  FSMC_BCR4_WRAPMOD                   ((uint32_t)0x00000400)        /*!< Wrapped burst mode support */
+#define  FSMC_BCR4_WAITCFG                   ((uint32_t)0x00000800)        /*!< Wait timing configuration */
+#define  FSMC_BCR4_WREN                      ((uint32_t)0x00001000)        /*!< Write enable bit */
+#define  FSMC_BCR4_WAITEN                    ((uint32_t)0x00002000)        /*!< Wait enable bit */
+#define  FSMC_BCR4_EXTMOD                    ((uint32_t)0x00004000)        /*!< Extended mode enable */
+#define  FSMC_BCR4_ASYNCWAIT                 ((uint32_t)0x00008000)       /*!< Asynchronous wait */
+#define  FSMC_BCR4_CBURSTRW                  ((uint32_t)0x00080000)        /*!< Write burst enable */
+
+/******************  Bit definition for FSMC_BTR1 register  ******************/
+#define  FSMC_BTR1_ADDSET                    ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BTR1_ADDSET_0                  ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BTR1_ADDSET_1                  ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BTR1_ADDSET_2                  ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BTR1_ADDSET_3                  ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_ADDHLD                    ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BTR1_ADDHLD_0                  ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BTR1_ADDHLD_1                  ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BTR1_ADDHLD_2                  ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BTR1_ADDHLD_3                  ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_DATAST                    ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BTR1_DATAST_0                  ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BTR1_DATAST_1                  ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BTR1_DATAST_2                  ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BTR1_DATAST_3                  ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_BUSTURN                   ((uint32_t)0x000F0000)        /*!< BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define  FSMC_BTR1_BUSTURN_0                 ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_BTR1_BUSTURN_1                 ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_BTR1_BUSTURN_2                 ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_BTR1_BUSTURN_3                 ((uint32_t)0x00080000)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_CLKDIV                    ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BTR1_CLKDIV_0                  ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BTR1_CLKDIV_1                  ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BTR1_CLKDIV_2                  ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BTR1_CLKDIV_3                  ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_DATLAT                    ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BTR1_DATLAT_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BTR1_DATLAT_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BTR1_DATLAT_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BTR1_DATLAT_3                  ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BTR1_ACCMOD                    ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BTR1_ACCMOD_0                  ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BTR1_ACCMOD_1                  ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BTR2 register  *******************/
+#define  FSMC_BTR2_ADDSET                    ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BTR2_ADDSET_0                  ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BTR2_ADDSET_1                  ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BTR2_ADDSET_2                  ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BTR2_ADDSET_3                  ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_ADDHLD                    ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BTR2_ADDHLD_0                  ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BTR2_ADDHLD_1                  ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BTR2_ADDHLD_2                  ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BTR2_ADDHLD_3                  ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_DATAST                    ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BTR2_DATAST_0                  ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BTR2_DATAST_1                  ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BTR2_DATAST_2                  ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BTR2_DATAST_3                  ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_BUSTURN                   ((uint32_t)0x000F0000)        /*!< BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define  FSMC_BTR2_BUSTURN_0                 ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_BTR2_BUSTURN_1                 ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_BTR2_BUSTURN_2                 ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_BTR2_BUSTURN_3                 ((uint32_t)0x00080000)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_CLKDIV                    ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BTR2_CLKDIV_0                  ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BTR2_CLKDIV_1                  ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BTR2_CLKDIV_2                  ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BTR2_CLKDIV_3                  ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_DATLAT                    ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BTR2_DATLAT_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BTR2_DATLAT_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BTR2_DATLAT_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BTR2_DATLAT_3                  ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BTR2_ACCMOD                    ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BTR2_ACCMOD_0                  ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BTR2_ACCMOD_1                  ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/*******************  Bit definition for FSMC_BTR3 register  *******************/
+#define  FSMC_BTR3_ADDSET                    ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BTR3_ADDSET_0                  ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BTR3_ADDSET_1                  ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BTR3_ADDSET_2                  ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BTR3_ADDSET_3                  ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_ADDHLD                    ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BTR3_ADDHLD_0                  ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BTR3_ADDHLD_1                  ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BTR3_ADDHLD_2                  ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BTR3_ADDHLD_3                  ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_DATAST                    ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BTR3_DATAST_0                  ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BTR3_DATAST_1                  ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BTR3_DATAST_2                  ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BTR3_DATAST_3                  ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_BUSTURN                   ((uint32_t)0x000F0000)        /*!< BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define  FSMC_BTR3_BUSTURN_0                 ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_BTR3_BUSTURN_1                 ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_BTR3_BUSTURN_2                 ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_BTR3_BUSTURN_3                 ((uint32_t)0x00080000)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_CLKDIV                    ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BTR3_CLKDIV_0                  ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BTR3_CLKDIV_1                  ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BTR3_CLKDIV_2                  ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BTR3_CLKDIV_3                  ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_DATLAT                    ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BTR3_DATLAT_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BTR3_DATLAT_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BTR3_DATLAT_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BTR3_DATLAT_3                  ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BTR3_ACCMOD                    ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BTR3_ACCMOD_0                  ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BTR3_ACCMOD_1                  ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BTR4 register  *******************/
+#define  FSMC_BTR4_ADDSET                    ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BTR4_ADDSET_0                  ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BTR4_ADDSET_1                  ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BTR4_ADDSET_2                  ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BTR4_ADDSET_3                  ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_ADDHLD                    ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BTR4_ADDHLD_0                  ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BTR4_ADDHLD_1                  ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BTR4_ADDHLD_2                  ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BTR4_ADDHLD_3                  ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_DATAST                    ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BTR4_DATAST_0                  ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BTR4_DATAST_1                  ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BTR4_DATAST_2                  ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BTR4_DATAST_3                  ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_BUSTURN                   ((uint32_t)0x000F0000)        /*!< BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define  FSMC_BTR4_BUSTURN_0                 ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_BTR4_BUSTURN_1                 ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_BTR4_BUSTURN_2                 ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_BTR4_BUSTURN_3                 ((uint32_t)0x00080000)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_CLKDIV                    ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BTR4_CLKDIV_0                  ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BTR4_CLKDIV_1                  ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BTR4_CLKDIV_2                  ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BTR4_CLKDIV_3                  ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_DATLAT                    ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BTR4_DATLAT_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BTR4_DATLAT_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BTR4_DATLAT_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BTR4_DATLAT_3                  ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BTR4_ACCMOD                    ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BTR4_ACCMOD_0                  ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BTR4_ACCMOD_1                  ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BWTR1 register  ******************/
+#define  FSMC_BWTR1_ADDSET                   ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BWTR1_ADDSET_0                 ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BWTR1_ADDSET_1                 ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BWTR1_ADDSET_2                 ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BWTR1_ADDSET_3                 ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BWTR1_ADDHLD                   ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BWTR1_ADDHLD_0                 ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BWTR1_ADDHLD_1                 ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BWTR1_ADDHLD_2                 ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BWTR1_ADDHLD_3                 ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BWTR1_DATAST                   ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BWTR1_DATAST_0                 ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BWTR1_DATAST_1                 ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BWTR1_DATAST_2                 ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BWTR1_DATAST_3                 ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BWTR1_CLKDIV                   ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BWTR1_CLKDIV_0                 ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BWTR1_CLKDIV_1                 ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BWTR1_CLKDIV_2                 ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BWTR1_CLKDIV_3                 ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR1_DATLAT                   ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BWTR1_DATLAT_0                 ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BWTR1_DATLAT_1                 ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BWTR1_DATLAT_2                 ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BWTR1_DATLAT_3                 ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR1_ACCMOD                   ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BWTR1_ACCMOD_0                 ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BWTR1_ACCMOD_1                 ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BWTR2 register  ******************/
+#define  FSMC_BWTR2_ADDSET                   ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BWTR2_ADDSET_0                 ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BWTR2_ADDSET_1                 ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BWTR2_ADDSET_2                 ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BWTR2_ADDSET_3                 ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BWTR2_ADDHLD                   ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BWTR2_ADDHLD_0                 ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BWTR2_ADDHLD_1                 ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BWTR2_ADDHLD_2                 ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BWTR2_ADDHLD_3                 ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BWTR2_DATAST                   ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BWTR2_DATAST_0                 ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BWTR2_DATAST_1                 ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BWTR2_DATAST_2                 ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BWTR2_DATAST_3                 ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BWTR2_CLKDIV                   ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BWTR2_CLKDIV_0                 ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BWTR2_CLKDIV_1                 ((uint32_t)0x00200000)        /*!< Bit 1*/
+#define  FSMC_BWTR2_CLKDIV_2                 ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BWTR2_CLKDIV_3                 ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR2_DATLAT                   ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BWTR2_DATLAT_0                 ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BWTR2_DATLAT_1                 ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BWTR2_DATLAT_2                 ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BWTR2_DATLAT_3                 ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR2_ACCMOD                   ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BWTR2_ACCMOD_0                 ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BWTR2_ACCMOD_1                 ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BWTR3 register  ******************/
+#define  FSMC_BWTR3_ADDSET                   ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BWTR3_ADDSET_0                 ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BWTR3_ADDSET_1                 ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BWTR3_ADDSET_2                 ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BWTR3_ADDSET_3                 ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BWTR3_ADDHLD                   ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BWTR3_ADDHLD_0                 ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BWTR3_ADDHLD_1                 ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BWTR3_ADDHLD_2                 ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BWTR3_ADDHLD_3                 ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BWTR3_DATAST                   ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BWTR3_DATAST_0                 ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BWTR3_DATAST_1                 ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BWTR3_DATAST_2                 ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BWTR3_DATAST_3                 ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BWTR3_CLKDIV                   ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BWTR3_CLKDIV_0                 ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BWTR3_CLKDIV_1                 ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BWTR3_CLKDIV_2                 ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BWTR3_CLKDIV_3                 ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR3_DATLAT                   ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BWTR3_DATLAT_0                 ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BWTR3_DATLAT_1                 ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BWTR3_DATLAT_2                 ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BWTR3_DATLAT_3                 ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR3_ACCMOD                   ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BWTR3_ACCMOD_0                 ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BWTR3_ACCMOD_1                 ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_BWTR4 register  ******************/
+#define  FSMC_BWTR4_ADDSET                   ((uint32_t)0x0000000F)        /*!< ADDSET[3:0] bits (Address setup phase duration) */
+#define  FSMC_BWTR4_ADDSET_0                 ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_BWTR4_ADDSET_1                 ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_BWTR4_ADDSET_2                 ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_BWTR4_ADDSET_3                 ((uint32_t)0x00000008)        /*!< Bit 3 */
+
+#define  FSMC_BWTR4_ADDHLD                   ((uint32_t)0x000000F0)        /*!< ADDHLD[3:0] bits (Address-hold phase duration) */
+#define  FSMC_BWTR4_ADDHLD_0                 ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_BWTR4_ADDHLD_1                 ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  FSMC_BWTR4_ADDHLD_2                 ((uint32_t)0x00000040)        /*!< Bit 2 */
+#define  FSMC_BWTR4_ADDHLD_3                 ((uint32_t)0x00000080)        /*!< Bit 3 */
+
+#define  FSMC_BWTR4_DATAST                   ((uint32_t)0x0000FF00)        /*!< DATAST [3:0] bits (Data-phase duration) */
+#define  FSMC_BWTR4_DATAST_0                 ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_BWTR4_DATAST_1                 ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_BWTR4_DATAST_2                 ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_BWTR4_DATAST_3                 ((uint32_t)0x00000800)        /*!< Bit 3 */
+
+#define  FSMC_BWTR4_CLKDIV                   ((uint32_t)0x00F00000)        /*!< CLKDIV[3:0] bits (Clock divide ratio) */
+#define  FSMC_BWTR4_CLKDIV_0                 ((uint32_t)0x00100000)        /*!< Bit 0 */
+#define  FSMC_BWTR4_CLKDIV_1                 ((uint32_t)0x00200000)        /*!< Bit 1 */
+#define  FSMC_BWTR4_CLKDIV_2                 ((uint32_t)0x00400000)        /*!< Bit 2 */
+#define  FSMC_BWTR4_CLKDIV_3                 ((uint32_t)0x00800000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR4_DATLAT                   ((uint32_t)0x0F000000)        /*!< DATLA[3:0] bits (Data latency) */
+#define  FSMC_BWTR4_DATLAT_0                 ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_BWTR4_DATLAT_1                 ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_BWTR4_DATLAT_2                 ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_BWTR4_DATLAT_3                 ((uint32_t)0x08000000)        /*!< Bit 3 */
+
+#define  FSMC_BWTR4_ACCMOD                   ((uint32_t)0x30000000)        /*!< ACCMOD[1:0] bits (Access mode) */
+#define  FSMC_BWTR4_ACCMOD_0                 ((uint32_t)0x10000000)        /*!< Bit 0 */
+#define  FSMC_BWTR4_ACCMOD_1                 ((uint32_t)0x20000000)        /*!< Bit 1 */
+
+/******************  Bit definition for FSMC_PCR2 register  *******************/
+#define  FSMC_PCR2_PWAITEN                   ((uint32_t)0x00000002)        /*!< Wait feature enable bit */
+#define  FSMC_PCR2_PBKEN                     ((uint32_t)0x00000004)        /*!< PC Card/NAND Flash memory bank enable bit */
+#define  FSMC_PCR2_PTYP                      ((uint32_t)0x00000008)        /*!< Memory type */
+
+#define  FSMC_PCR2_PWID                      ((uint32_t)0x00000030)        /*!< PWID[1:0] bits (NAND Flash databus width) */
+#define  FSMC_PCR2_PWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_PCR2_PWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_PCR2_ECCEN                     ((uint32_t)0x00000040)        /*!< ECC computation logic enable bit */
+
+#define  FSMC_PCR2_TCLR                      ((uint32_t)0x00001E00)        /*!< TCLR[3:0] bits (CLE to RE delay) */
+#define  FSMC_PCR2_TCLR_0                    ((uint32_t)0x00000200)        /*!< Bit 0 */
+#define  FSMC_PCR2_TCLR_1                    ((uint32_t)0x00000400)        /*!< Bit 1 */
+#define  FSMC_PCR2_TCLR_2                    ((uint32_t)0x00000800)        /*!< Bit 2 */
+#define  FSMC_PCR2_TCLR_3                    ((uint32_t)0x00001000)        /*!< Bit 3 */
+
+#define  FSMC_PCR2_TAR                       ((uint32_t)0x0001E000)        /*!< TAR[3:0] bits (ALE to RE delay) */
+#define  FSMC_PCR2_TAR_0                     ((uint32_t)0x00002000)        /*!< Bit 0 */
+#define  FSMC_PCR2_TAR_1                     ((uint32_t)0x00004000)        /*!< Bit 1 */
+#define  FSMC_PCR2_TAR_2                     ((uint32_t)0x00008000)        /*!< Bit 2 */
+#define  FSMC_PCR2_TAR_3                     ((uint32_t)0x00010000)        /*!< Bit 3 */
+
+#define  FSMC_PCR2_ECCPS                     ((uint32_t)0x000E0000)        /*!< ECCPS[1:0] bits (ECC page size) */
+#define  FSMC_PCR2_ECCPS_0                   ((uint32_t)0x00020000)        /*!< Bit 0 */
+#define  FSMC_PCR2_ECCPS_1                   ((uint32_t)0x00040000)        /*!< Bit 1 */
+#define  FSMC_PCR2_ECCPS_2                   ((uint32_t)0x00080000)        /*!< Bit 2 */
+
+/******************  Bit definition for FSMC_PCR3 register  *******************/
+#define  FSMC_PCR3_PWAITEN                   ((uint32_t)0x00000002)        /*!< Wait feature enable bit */
+#define  FSMC_PCR3_PBKEN                     ((uint32_t)0x00000004)        /*!< PC Card/NAND Flash memory bank enable bit */
+#define  FSMC_PCR3_PTYP                      ((uint32_t)0x00000008)        /*!< Memory type */
+
+#define  FSMC_PCR3_PWID                      ((uint32_t)0x00000030)        /*!< PWID[1:0] bits (NAND Flash databus width) */
+#define  FSMC_PCR3_PWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_PCR3_PWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_PCR3_ECCEN                     ((uint32_t)0x00000040)        /*!< ECC computation logic enable bit */
+
+#define  FSMC_PCR3_TCLR                      ((uint32_t)0x00001E00)        /*!< TCLR[3:0] bits (CLE to RE delay) */
+#define  FSMC_PCR3_TCLR_0                    ((uint32_t)0x00000200)        /*!< Bit 0 */
+#define  FSMC_PCR3_TCLR_1                    ((uint32_t)0x00000400)        /*!< Bit 1 */
+#define  FSMC_PCR3_TCLR_2                    ((uint32_t)0x00000800)        /*!< Bit 2 */
+#define  FSMC_PCR3_TCLR_3                    ((uint32_t)0x00001000)        /*!< Bit 3 */
+
+#define  FSMC_PCR3_TAR                       ((uint32_t)0x0001E000)        /*!< TAR[3:0] bits (ALE to RE delay) */
+#define  FSMC_PCR3_TAR_0                     ((uint32_t)0x00002000)        /*!< Bit 0 */
+#define  FSMC_PCR3_TAR_1                     ((uint32_t)0x00004000)        /*!< Bit 1 */
+#define  FSMC_PCR3_TAR_2                     ((uint32_t)0x00008000)        /*!< Bit 2 */
+#define  FSMC_PCR3_TAR_3                     ((uint32_t)0x00010000)        /*!< Bit 3 */
+
+#define  FSMC_PCR3_ECCPS                     ((uint32_t)0x000E0000)        /*!< ECCPS[2:0] bits (ECC page size) */
+#define  FSMC_PCR3_ECCPS_0                   ((uint32_t)0x00020000)        /*!< Bit 0 */
+#define  FSMC_PCR3_ECCPS_1                   ((uint32_t)0x00040000)        /*!< Bit 1 */
+#define  FSMC_PCR3_ECCPS_2                   ((uint32_t)0x00080000)        /*!< Bit 2 */
+
+/******************  Bit definition for FSMC_PCR4 register  *******************/
+#define  FSMC_PCR4_PWAITEN                   ((uint32_t)0x00000002)        /*!< Wait feature enable bit */
+#define  FSMC_PCR4_PBKEN                     ((uint32_t)0x00000004)        /*!< PC Card/NAND Flash memory bank enable bit */
+#define  FSMC_PCR4_PTYP                      ((uint32_t)0x00000008)        /*!< Memory type */
+
+#define  FSMC_PCR4_PWID                      ((uint32_t)0x00000030)        /*!< PWID[1:0] bits (NAND Flash databus width) */
+#define  FSMC_PCR4_PWID_0                    ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  FSMC_PCR4_PWID_1                    ((uint32_t)0x00000020)        /*!< Bit 1 */
+
+#define  FSMC_PCR4_ECCEN                     ((uint32_t)0x00000040)        /*!< ECC computation logic enable bit */
+
+#define  FSMC_PCR4_TCLR                      ((uint32_t)0x00001E00)        /*!< TCLR[3:0] bits (CLE to RE delay) */
+#define  FSMC_PCR4_TCLR_0                    ((uint32_t)0x00000200)        /*!< Bit 0 */
+#define  FSMC_PCR4_TCLR_1                    ((uint32_t)0x00000400)        /*!< Bit 1 */
+#define  FSMC_PCR4_TCLR_2                    ((uint32_t)0x00000800)        /*!< Bit 2 */
+#define  FSMC_PCR4_TCLR_3                    ((uint32_t)0x00001000)        /*!< Bit 3 */
+
+#define  FSMC_PCR4_TAR                       ((uint32_t)0x0001E000)        /*!< TAR[3:0] bits (ALE to RE delay) */
+#define  FSMC_PCR4_TAR_0                     ((uint32_t)0x00002000)        /*!< Bit 0 */
+#define  FSMC_PCR4_TAR_1                     ((uint32_t)0x00004000)        /*!< Bit 1 */
+#define  FSMC_PCR4_TAR_2                     ((uint32_t)0x00008000)        /*!< Bit 2 */
+#define  FSMC_PCR4_TAR_3                     ((uint32_t)0x00010000)        /*!< Bit 3 */
+
+#define  FSMC_PCR4_ECCPS                     ((uint32_t)0x000E0000)        /*!< ECCPS[2:0] bits (ECC page size) */
+#define  FSMC_PCR4_ECCPS_0                   ((uint32_t)0x00020000)        /*!< Bit 0 */
+#define  FSMC_PCR4_ECCPS_1                   ((uint32_t)0x00040000)        /*!< Bit 1 */
+#define  FSMC_PCR4_ECCPS_2                   ((uint32_t)0x00080000)        /*!< Bit 2 */
+
+/*******************  Bit definition for FSMC_SR2 register  *******************/
+#define  FSMC_SR2_IRS                        ((uint8_t)0x01)               /*!< Interrupt Rising Edge status */
+#define  FSMC_SR2_ILS                        ((uint8_t)0x02)               /*!< Interrupt Level status */
+#define  FSMC_SR2_IFS                        ((uint8_t)0x04)               /*!< Interrupt Falling Edge status */
+#define  FSMC_SR2_IREN                       ((uint8_t)0x08)               /*!< Interrupt Rising Edge detection Enable bit */
+#define  FSMC_SR2_ILEN                       ((uint8_t)0x10)               /*!< Interrupt Level detection Enable bit */
+#define  FSMC_SR2_IFEN                       ((uint8_t)0x20)               /*!< Interrupt Falling Edge detection Enable bit */
+#define  FSMC_SR2_FEMPT                      ((uint8_t)0x40)               /*!< FIFO empty */
+
+/*******************  Bit definition for FSMC_SR3 register  *******************/
+#define  FSMC_SR3_IRS                        ((uint8_t)0x01)               /*!< Interrupt Rising Edge status */
+#define  FSMC_SR3_ILS                        ((uint8_t)0x02)               /*!< Interrupt Level status */
+#define  FSMC_SR3_IFS                        ((uint8_t)0x04)               /*!< Interrupt Falling Edge status */
+#define  FSMC_SR3_IREN                       ((uint8_t)0x08)               /*!< Interrupt Rising Edge detection Enable bit */
+#define  FSMC_SR3_ILEN                       ((uint8_t)0x10)               /*!< Interrupt Level detection Enable bit */
+#define  FSMC_SR3_IFEN                       ((uint8_t)0x20)               /*!< Interrupt Falling Edge detection Enable bit */
+#define  FSMC_SR3_FEMPT                      ((uint8_t)0x40)               /*!< FIFO empty */
+
+/*******************  Bit definition for FSMC_SR4 register  *******************/
+#define  FSMC_SR4_IRS                        ((uint8_t)0x01)               /*!< Interrupt Rising Edge status */
+#define  FSMC_SR4_ILS                        ((uint8_t)0x02)               /*!< Interrupt Level status */
+#define  FSMC_SR4_IFS                        ((uint8_t)0x04)               /*!< Interrupt Falling Edge status */
+#define  FSMC_SR4_IREN                       ((uint8_t)0x08)               /*!< Interrupt Rising Edge detection Enable bit */
+#define  FSMC_SR4_ILEN                       ((uint8_t)0x10)               /*!< Interrupt Level detection Enable bit */
+#define  FSMC_SR4_IFEN                       ((uint8_t)0x20)               /*!< Interrupt Falling Edge detection Enable bit */
+#define  FSMC_SR4_FEMPT                      ((uint8_t)0x40)               /*!< FIFO empty */
+
+/******************  Bit definition for FSMC_PMEM2 register  ******************/
+#define  FSMC_PMEM2_MEMSET2                  ((uint32_t)0x000000FF)        /*!< MEMSET2[7:0] bits (Common memory 2 setup time) */
+#define  FSMC_PMEM2_MEMSET2_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PMEM2_MEMSET2_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PMEM2_MEMSET2_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PMEM2_MEMSET2_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PMEM2_MEMSET2_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PMEM2_MEMSET2_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PMEM2_MEMSET2_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PMEM2_MEMSET2_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PMEM2_MEMWAIT2                 ((uint32_t)0x0000FF00)        /*!< MEMWAIT2[7:0] bits (Common memory 2 wait time) */
+#define  FSMC_PMEM2_MEMWAIT2_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PMEM2_MEMWAIT2_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PMEM2_MEMWAIT2_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PMEM2_MEMWAIT2_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PMEM2_MEMWAIT2_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PMEM2_MEMWAIT2_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PMEM2_MEMWAIT2_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PMEM2_MEMWAIT2_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM2_MEMHOLD2                 ((uint32_t)0x00FF0000)        /*!< MEMHOLD2[7:0] bits (Common memory 2 hold time) */
+#define  FSMC_PMEM2_MEMHOLD2_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PMEM2_MEMHOLD2_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PMEM2_MEMHOLD2_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PMEM2_MEMHOLD2_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PMEM2_MEMHOLD2_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PMEM2_MEMHOLD2_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PMEM2_MEMHOLD2_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PMEM2_MEMHOLD2_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM2_MEMHIZ2                  ((uint32_t)0xFF000000)        /*!< MEMHIZ2[7:0] bits (Common memory 2 databus HiZ time) */
+#define  FSMC_PMEM2_MEMHIZ2_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PMEM2_MEMHIZ2_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PMEM2_MEMHIZ2_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PMEM2_MEMHIZ2_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PMEM2_MEMHIZ2_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PMEM2_MEMHIZ2_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PMEM2_MEMHIZ2_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PMEM2_MEMHIZ2_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PMEM3 register  ******************/
+#define  FSMC_PMEM3_MEMSET3                  ((uint32_t)0x000000FF)        /*!< MEMSET3[7:0] bits (Common memory 3 setup time) */
+#define  FSMC_PMEM3_MEMSET3_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PMEM3_MEMSET3_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PMEM3_MEMSET3_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PMEM3_MEMSET3_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PMEM3_MEMSET3_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PMEM3_MEMSET3_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PMEM3_MEMSET3_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PMEM3_MEMSET3_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PMEM3_MEMWAIT3                 ((uint32_t)0x0000FF00)        /*!< MEMWAIT3[7:0] bits (Common memory 3 wait time) */
+#define  FSMC_PMEM3_MEMWAIT3_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PMEM3_MEMWAIT3_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PMEM3_MEMWAIT3_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PMEM3_MEMWAIT3_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PMEM3_MEMWAIT3_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PMEM3_MEMWAIT3_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PMEM3_MEMWAIT3_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PMEM3_MEMWAIT3_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM3_MEMHOLD3                 ((uint32_t)0x00FF0000)        /*!< MEMHOLD3[7:0] bits (Common memory 3 hold time) */
+#define  FSMC_PMEM3_MEMHOLD3_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PMEM3_MEMHOLD3_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PMEM3_MEMHOLD3_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PMEM3_MEMHOLD3_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PMEM3_MEMHOLD3_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PMEM3_MEMHOLD3_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PMEM3_MEMHOLD3_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PMEM3_MEMHOLD3_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM3_MEMHIZ3                  ((uint32_t)0xFF000000)        /*!< MEMHIZ3[7:0] bits (Common memory 3 databus HiZ time) */
+#define  FSMC_PMEM3_MEMHIZ3_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PMEM3_MEMHIZ3_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PMEM3_MEMHIZ3_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PMEM3_MEMHIZ3_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PMEM3_MEMHIZ3_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PMEM3_MEMHIZ3_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PMEM3_MEMHIZ3_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PMEM3_MEMHIZ3_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PMEM4 register  ******************/
+#define  FSMC_PMEM4_MEMSET4                  ((uint32_t)0x000000FF)        /*!< MEMSET4[7:0] bits (Common memory 4 setup time) */
+#define  FSMC_PMEM4_MEMSET4_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PMEM4_MEMSET4_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PMEM4_MEMSET4_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PMEM4_MEMSET4_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PMEM4_MEMSET4_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PMEM4_MEMSET4_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PMEM4_MEMSET4_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PMEM4_MEMSET4_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PMEM4_MEMWAIT4                 ((uint32_t)0x0000FF00)        /*!< MEMWAIT4[7:0] bits (Common memory 4 wait time) */
+#define  FSMC_PMEM4_MEMWAIT4_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PMEM4_MEMWAIT4_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PMEM4_MEMWAIT4_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PMEM4_MEMWAIT4_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PMEM4_MEMWAIT4_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PMEM4_MEMWAIT4_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PMEM4_MEMWAIT4_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PMEM4_MEMWAIT4_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM4_MEMHOLD4                 ((uint32_t)0x00FF0000)        /*!< MEMHOLD4[7:0] bits (Common memory 4 hold time) */
+#define  FSMC_PMEM4_MEMHOLD4_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PMEM4_MEMHOLD4_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PMEM4_MEMHOLD4_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PMEM4_MEMHOLD4_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PMEM4_MEMHOLD4_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PMEM4_MEMHOLD4_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PMEM4_MEMHOLD4_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PMEM4_MEMHOLD4_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PMEM4_MEMHIZ4                  ((uint32_t)0xFF000000)        /*!< MEMHIZ4[7:0] bits (Common memory 4 databus HiZ time) */
+#define  FSMC_PMEM4_MEMHIZ4_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PMEM4_MEMHIZ4_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PMEM4_MEMHIZ4_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PMEM4_MEMHIZ4_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PMEM4_MEMHIZ4_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PMEM4_MEMHIZ4_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PMEM4_MEMHIZ4_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PMEM4_MEMHIZ4_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PATT2 register  ******************/
+#define  FSMC_PATT2_ATTSET2                  ((uint32_t)0x000000FF)        /*!< ATTSET2[7:0] bits (Attribute memory 2 setup time) */
+#define  FSMC_PATT2_ATTSET2_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PATT2_ATTSET2_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PATT2_ATTSET2_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PATT2_ATTSET2_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PATT2_ATTSET2_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PATT2_ATTSET2_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PATT2_ATTSET2_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PATT2_ATTSET2_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PATT2_ATTWAIT2                 ((uint32_t)0x0000FF00)        /*!< ATTWAIT2[7:0] bits (Attribute memory 2 wait time) */
+#define  FSMC_PATT2_ATTWAIT2_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PATT2_ATTWAIT2_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PATT2_ATTWAIT2_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PATT2_ATTWAIT2_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PATT2_ATTWAIT2_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PATT2_ATTWAIT2_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PATT2_ATTWAIT2_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PATT2_ATTWAIT2_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PATT2_ATTHOLD2                 ((uint32_t)0x00FF0000)        /*!< ATTHOLD2[7:0] bits (Attribute memory 2 hold time) */
+#define  FSMC_PATT2_ATTHOLD2_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PATT2_ATTHOLD2_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PATT2_ATTHOLD2_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PATT2_ATTHOLD2_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PATT2_ATTHOLD2_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PATT2_ATTHOLD2_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PATT2_ATTHOLD2_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PATT2_ATTHOLD2_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PATT2_ATTHIZ2                  ((uint32_t)0xFF000000)        /*!< ATTHIZ2[7:0] bits (Attribute memory 2 databus HiZ time) */
+#define  FSMC_PATT2_ATTHIZ2_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PATT2_ATTHIZ2_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PATT2_ATTHIZ2_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PATT2_ATTHIZ2_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PATT2_ATTHIZ2_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PATT2_ATTHIZ2_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PATT2_ATTHIZ2_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PATT2_ATTHIZ2_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PATT3 register  ******************/
+#define  FSMC_PATT3_ATTSET3                  ((uint32_t)0x000000FF)        /*!< ATTSET3[7:0] bits (Attribute memory 3 setup time) */
+#define  FSMC_PATT3_ATTSET3_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PATT3_ATTSET3_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PATT3_ATTSET3_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PATT3_ATTSET3_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PATT3_ATTSET3_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PATT3_ATTSET3_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PATT3_ATTSET3_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PATT3_ATTSET3_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PATT3_ATTWAIT3                 ((uint32_t)0x0000FF00)        /*!< ATTWAIT3[7:0] bits (Attribute memory 3 wait time) */
+#define  FSMC_PATT3_ATTWAIT3_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PATT3_ATTWAIT3_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PATT3_ATTWAIT3_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PATT3_ATTWAIT3_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PATT3_ATTWAIT3_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PATT3_ATTWAIT3_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PATT3_ATTWAIT3_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PATT3_ATTWAIT3_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PATT3_ATTHOLD3                 ((uint32_t)0x00FF0000)        /*!< ATTHOLD3[7:0] bits (Attribute memory 3 hold time) */
+#define  FSMC_PATT3_ATTHOLD3_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PATT3_ATTHOLD3_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PATT3_ATTHOLD3_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PATT3_ATTHOLD3_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PATT3_ATTHOLD3_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PATT3_ATTHOLD3_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PATT3_ATTHOLD3_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PATT3_ATTHOLD3_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PATT3_ATTHIZ3                  ((uint32_t)0xFF000000)        /*!< ATTHIZ3[7:0] bits (Attribute memory 3 databus HiZ time) */
+#define  FSMC_PATT3_ATTHIZ3_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PATT3_ATTHIZ3_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PATT3_ATTHIZ3_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PATT3_ATTHIZ3_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PATT3_ATTHIZ3_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PATT3_ATTHIZ3_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PATT3_ATTHIZ3_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PATT3_ATTHIZ3_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PATT4 register  ******************/
+#define  FSMC_PATT4_ATTSET4                  ((uint32_t)0x000000FF)        /*!< ATTSET4[7:0] bits (Attribute memory 4 setup time) */
+#define  FSMC_PATT4_ATTSET4_0                ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PATT4_ATTSET4_1                ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PATT4_ATTSET4_2                ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PATT4_ATTSET4_3                ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PATT4_ATTSET4_4                ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PATT4_ATTSET4_5                ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PATT4_ATTSET4_6                ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PATT4_ATTSET4_7                ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PATT4_ATTWAIT4                 ((uint32_t)0x0000FF00)        /*!< ATTWAIT4[7:0] bits (Attribute memory 4 wait time) */
+#define  FSMC_PATT4_ATTWAIT4_0               ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PATT4_ATTWAIT4_1               ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PATT4_ATTWAIT4_2               ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PATT4_ATTWAIT4_3               ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PATT4_ATTWAIT4_4               ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PATT4_ATTWAIT4_5               ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PATT4_ATTWAIT4_6               ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PATT4_ATTWAIT4_7               ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PATT4_ATTHOLD4                 ((uint32_t)0x00FF0000)        /*!< ATTHOLD4[7:0] bits (Attribute memory 4 hold time) */
+#define  FSMC_PATT4_ATTHOLD4_0               ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PATT4_ATTHOLD4_1               ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PATT4_ATTHOLD4_2               ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PATT4_ATTHOLD4_3               ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PATT4_ATTHOLD4_4               ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PATT4_ATTHOLD4_5               ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PATT4_ATTHOLD4_6               ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PATT4_ATTHOLD4_7               ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PATT4_ATTHIZ4                  ((uint32_t)0xFF000000)        /*!< ATTHIZ4[7:0] bits (Attribute memory 4 databus HiZ time) */
+#define  FSMC_PATT4_ATTHIZ4_0                ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PATT4_ATTHIZ4_1                ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PATT4_ATTHIZ4_2                ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PATT4_ATTHIZ4_3                ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PATT4_ATTHIZ4_4                ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PATT4_ATTHIZ4_5                ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PATT4_ATTHIZ4_6                ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PATT4_ATTHIZ4_7                ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_PIO4 register  *******************/
+#define  FSMC_PIO4_IOSET4                    ((uint32_t)0x000000FF)        /*!< IOSET4[7:0] bits (I/O 4 setup time) */
+#define  FSMC_PIO4_IOSET4_0                  ((uint32_t)0x00000001)        /*!< Bit 0 */
+#define  FSMC_PIO4_IOSET4_1                  ((uint32_t)0x00000002)        /*!< Bit 1 */
+#define  FSMC_PIO4_IOSET4_2                  ((uint32_t)0x00000004)        /*!< Bit 2 */
+#define  FSMC_PIO4_IOSET4_3                  ((uint32_t)0x00000008)        /*!< Bit 3 */
+#define  FSMC_PIO4_IOSET4_4                  ((uint32_t)0x00000010)        /*!< Bit 4 */
+#define  FSMC_PIO4_IOSET4_5                  ((uint32_t)0x00000020)        /*!< Bit 5 */
+#define  FSMC_PIO4_IOSET4_6                  ((uint32_t)0x00000040)        /*!< Bit 6 */
+#define  FSMC_PIO4_IOSET4_7                  ((uint32_t)0x00000080)        /*!< Bit 7 */
+
+#define  FSMC_PIO4_IOWAIT4                   ((uint32_t)0x0000FF00)        /*!< IOWAIT4[7:0] bits (I/O 4 wait time) */
+#define  FSMC_PIO4_IOWAIT4_0                 ((uint32_t)0x00000100)        /*!< Bit 0 */
+#define  FSMC_PIO4_IOWAIT4_1                 ((uint32_t)0x00000200)        /*!< Bit 1 */
+#define  FSMC_PIO4_IOWAIT4_2                 ((uint32_t)0x00000400)        /*!< Bit 2 */
+#define  FSMC_PIO4_IOWAIT4_3                 ((uint32_t)0x00000800)        /*!< Bit 3 */
+#define  FSMC_PIO4_IOWAIT4_4                 ((uint32_t)0x00001000)        /*!< Bit 4 */
+#define  FSMC_PIO4_IOWAIT4_5                 ((uint32_t)0x00002000)        /*!< Bit 5 */
+#define  FSMC_PIO4_IOWAIT4_6                 ((uint32_t)0x00004000)        /*!< Bit 6 */
+#define  FSMC_PIO4_IOWAIT4_7                 ((uint32_t)0x00008000)        /*!< Bit 7 */
+
+#define  FSMC_PIO4_IOHOLD4                   ((uint32_t)0x00FF0000)        /*!< IOHOLD4[7:0] bits (I/O 4 hold time) */
+#define  FSMC_PIO4_IOHOLD4_0                 ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  FSMC_PIO4_IOHOLD4_1                 ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  FSMC_PIO4_IOHOLD4_2                 ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  FSMC_PIO4_IOHOLD4_3                 ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  FSMC_PIO4_IOHOLD4_4                 ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  FSMC_PIO4_IOHOLD4_5                 ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  FSMC_PIO4_IOHOLD4_6                 ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  FSMC_PIO4_IOHOLD4_7                 ((uint32_t)0x00800000)        /*!< Bit 7 */
+
+#define  FSMC_PIO4_IOHIZ4                    ((uint32_t)0xFF000000)        /*!< IOHIZ4[7:0] bits (I/O 4 databus HiZ time) */
+#define  FSMC_PIO4_IOHIZ4_0                  ((uint32_t)0x01000000)        /*!< Bit 0 */
+#define  FSMC_PIO4_IOHIZ4_1                  ((uint32_t)0x02000000)        /*!< Bit 1 */
+#define  FSMC_PIO4_IOHIZ4_2                  ((uint32_t)0x04000000)        /*!< Bit 2 */
+#define  FSMC_PIO4_IOHIZ4_3                  ((uint32_t)0x08000000)        /*!< Bit 3 */
+#define  FSMC_PIO4_IOHIZ4_4                  ((uint32_t)0x10000000)        /*!< Bit 4 */
+#define  FSMC_PIO4_IOHIZ4_5                  ((uint32_t)0x20000000)        /*!< Bit 5 */
+#define  FSMC_PIO4_IOHIZ4_6                  ((uint32_t)0x40000000)        /*!< Bit 6 */
+#define  FSMC_PIO4_IOHIZ4_7                  ((uint32_t)0x80000000)        /*!< Bit 7 */
+
+/******************  Bit definition for FSMC_ECCR2 register  ******************/
+#define  FSMC_ECCR2_ECC2                     ((uint32_t)0xFFFFFFFF)        /*!< ECC result */
+
+/******************  Bit definition for FSMC_ECCR3 register  ******************/
+#define  FSMC_ECCR3_ECC3                     ((uint32_t)0xFFFFFFFF)        /*!< ECC result */
+
+/******************************************************************************/
+/*                                                                            */
+/*                          SD host Interface                                 */
+/*                                                                            */
+/******************************************************************************/
+
+/******************  Bit definition for SDIO_POWER register  ******************/
+#define  SDIO_POWER_PWRCTRL                  ((uint8_t)0x03)               /*!< PWRCTRL[1:0] bits (Power supply control bits) */
+#define  SDIO_POWER_PWRCTRL_0                ((uint8_t)0x01)               /*!< Bit 0 */
+#define  SDIO_POWER_PWRCTRL_1                ((uint8_t)0x02)               /*!< Bit 1 */
+
+/******************  Bit definition for SDIO_CLKCR register  ******************/
+#define  SDIO_CLKCR_CLKDIV                   ((uint16_t)0x00FF)            /*!< Clock divide factor */
+#define  SDIO_CLKCR_CLKEN                    ((uint16_t)0x0100)            /*!< Clock enable bit */
+#define  SDIO_CLKCR_PWRSAV                   ((uint16_t)0x0200)            /*!< Power saving configuration bit */
+#define  SDIO_CLKCR_BYPASS                   ((uint16_t)0x0400)            /*!< Clock divider bypass enable bit */
+
+#define  SDIO_CLKCR_WIDBUS                   ((uint16_t)0x1800)            /*!< WIDBUS[1:0] bits (Wide bus mode enable bit) */
+#define  SDIO_CLKCR_WIDBUS_0                 ((uint16_t)0x0800)            /*!< Bit 0 */
+#define  SDIO_CLKCR_WIDBUS_1                 ((uint16_t)0x1000)            /*!< Bit 1 */
+
+#define  SDIO_CLKCR_NEGEDGE                  ((uint16_t)0x2000)            /*!< SDIO_CK dephasing selection bit */
+#define  SDIO_CLKCR_HWFC_EN                  ((uint16_t)0x4000)            /*!< HW Flow Control enable */
+
+/*******************  Bit definition for SDIO_ARG register  *******************/
+#define  SDIO_ARG_CMDARG                     ((uint32_t)0xFFFFFFFF)            /*!< Command argument */
+
+/*******************  Bit definition for SDIO_CMD register  *******************/
+#define  SDIO_CMD_CMDINDEX                   ((uint16_t)0x003F)            /*!< Command Index */
+
+#define  SDIO_CMD_WAITRESP                   ((uint16_t)0x00C0)            /*!< WAITRESP[1:0] bits (Wait for response bits) */
+#define  SDIO_CMD_WAITRESP_0                 ((uint16_t)0x0040)            /*!<  Bit 0 */
+#define  SDIO_CMD_WAITRESP_1                 ((uint16_t)0x0080)            /*!<  Bit 1 */
+
+#define  SDIO_CMD_WAITINT                    ((uint16_t)0x0100)            /*!< CPSM Waits for Interrupt Request */
+#define  SDIO_CMD_WAITPEND                   ((uint16_t)0x0200)            /*!< CPSM Waits for ends of data transfer (CmdPend internal signal) */
+#define  SDIO_CMD_CPSMEN                     ((uint16_t)0x0400)            /*!< Command path state machine (CPSM) Enable bit */
+#define  SDIO_CMD_SDIOSUSPEND                ((uint16_t)0x0800)            /*!< SD I/O suspend command */
+#define  SDIO_CMD_ENCMDCOMPL                 ((uint16_t)0x1000)            /*!< Enable CMD completion */
+#define  SDIO_CMD_NIEN                       ((uint16_t)0x2000)            /*!< Not Interrupt Enable */
+#define  SDIO_CMD_CEATACMD                   ((uint16_t)0x4000)            /*!< CE-ATA command */
+
+/*****************  Bit definition for SDIO_RESPCMD register  *****************/
+#define  SDIO_RESPCMD_RESPCMD                ((uint8_t)0x3F)               /*!< Response command index */
+
+/******************  Bit definition for SDIO_RESP0 register  ******************/
+#define  SDIO_RESP0_CARDSTATUS0              ((uint32_t)0xFFFFFFFF)        /*!< Card Status */
+
+/******************  Bit definition for SDIO_RESP1 register  ******************/
+#define  SDIO_RESP1_CARDSTATUS1              ((uint32_t)0xFFFFFFFF)        /*!< Card Status */
+
+/******************  Bit definition for SDIO_RESP2 register  ******************/
+#define  SDIO_RESP2_CARDSTATUS2              ((uint32_t)0xFFFFFFFF)        /*!< Card Status */
+
+/******************  Bit definition for SDIO_RESP3 register  ******************/
+#define  SDIO_RESP3_CARDSTATUS3              ((uint32_t)0xFFFFFFFF)        /*!< Card Status */
+
+/******************  Bit definition for SDIO_RESP4 register  ******************/
+#define  SDIO_RESP4_CARDSTATUS4              ((uint32_t)0xFFFFFFFF)        /*!< Card Status */
+
+/******************  Bit definition for SDIO_DTIMER register  *****************/
+#define  SDIO_DTIMER_DATATIME                ((uint32_t)0xFFFFFFFF)        /*!< Data timeout period. */
+
+/******************  Bit definition for SDIO_DLEN register  *******************/
+#define  SDIO_DLEN_DATALENGTH                ((uint32_t)0x01FFFFFF)        /*!< Data length value */
+
+/******************  Bit definition for SDIO_DCTRL register  ******************/
+#define  SDIO_DCTRL_DTEN                     ((uint16_t)0x0001)            /*!< Data transfer enabled bit */
+#define  SDIO_DCTRL_DTDIR                    ((uint16_t)0x0002)            /*!< Data transfer direction selection */
+#define  SDIO_DCTRL_DTMODE                   ((uint16_t)0x0004)            /*!< Data transfer mode selection */
+#define  SDIO_DCTRL_DMAEN                    ((uint16_t)0x0008)            /*!< DMA enabled bit */
+
+#define  SDIO_DCTRL_DBLOCKSIZE               ((uint16_t)0x00F0)            /*!< DBLOCKSIZE[3:0] bits (Data block size) */
+#define  SDIO_DCTRL_DBLOCKSIZE_0             ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  SDIO_DCTRL_DBLOCKSIZE_1             ((uint16_t)0x0020)            /*!< Bit 1 */
+#define  SDIO_DCTRL_DBLOCKSIZE_2             ((uint16_t)0x0040)            /*!< Bit 2 */
+#define  SDIO_DCTRL_DBLOCKSIZE_3             ((uint16_t)0x0080)            /*!< Bit 3 */
+
+#define  SDIO_DCTRL_RWSTART                  ((uint16_t)0x0100)            /*!< Read wait start */
+#define  SDIO_DCTRL_RWSTOP                   ((uint16_t)0x0200)            /*!< Read wait stop */
+#define  SDIO_DCTRL_RWMOD                    ((uint16_t)0x0400)            /*!< Read wait mode */
+#define  SDIO_DCTRL_SDIOEN                   ((uint16_t)0x0800)            /*!< SD I/O enable functions */
+
+/******************  Bit definition for SDIO_DCOUNT register  *****************/
+#define  SDIO_DCOUNT_DATACOUNT               ((uint32_t)0x01FFFFFF)        /*!< Data count value */
+
+/******************  Bit definition for SDIO_STA register  ********************/
+#define  SDIO_STA_CCRCFAIL                   ((uint32_t)0x00000001)        /*!< Command response received (CRC check failed) */
+#define  SDIO_STA_DCRCFAIL                   ((uint32_t)0x00000002)        /*!< Data block sent/received (CRC check failed) */
+#define  SDIO_STA_CTIMEOUT                   ((uint32_t)0x00000004)        /*!< Command response timeout */
+#define  SDIO_STA_DTIMEOUT                   ((uint32_t)0x00000008)        /*!< Data timeout */
+#define  SDIO_STA_TXUNDERR                   ((uint32_t)0x00000010)        /*!< Transmit FIFO underrun error */
+#define  SDIO_STA_RXOVERR                    ((uint32_t)0x00000020)        /*!< Received FIFO overrun error */
+#define  SDIO_STA_CMDREND                    ((uint32_t)0x00000040)        /*!< Command response received (CRC check passed) */
+#define  SDIO_STA_CMDSENT                    ((uint32_t)0x00000080)        /*!< Command sent (no response required) */
+#define  SDIO_STA_DATAEND                    ((uint32_t)0x00000100)        /*!< Data end (data counter, SDIDCOUNT, is zero) */
+#define  SDIO_STA_STBITERR                   ((uint32_t)0x00000200)        /*!< Start bit not detected on all data signals in wide bus mode */
+#define  SDIO_STA_DBCKEND                    ((uint32_t)0x00000400)        /*!< Data block sent/received (CRC check passed) */
+#define  SDIO_STA_CMDACT                     ((uint32_t)0x00000800)        /*!< Command transfer in progress */
+#define  SDIO_STA_TXACT                      ((uint32_t)0x00001000)        /*!< Data transmit in progress */
+#define  SDIO_STA_RXACT                      ((uint32_t)0x00002000)        /*!< Data receive in progress */
+#define  SDIO_STA_TXFIFOHE                   ((uint32_t)0x00004000)        /*!< Transmit FIFO Half Empty: at least 8 words can be written into the FIFO */
+#define  SDIO_STA_RXFIFOHF                   ((uint32_t)0x00008000)        /*!< Receive FIFO Half Full: there are at least 8 words in the FIFO */
+#define  SDIO_STA_TXFIFOF                    ((uint32_t)0x00010000)        /*!< Transmit FIFO full */
+#define  SDIO_STA_RXFIFOF                    ((uint32_t)0x00020000)        /*!< Receive FIFO full */
+#define  SDIO_STA_TXFIFOE                    ((uint32_t)0x00040000)        /*!< Transmit FIFO empty */
+#define  SDIO_STA_RXFIFOE                    ((uint32_t)0x00080000)        /*!< Receive FIFO empty */
+#define  SDIO_STA_TXDAVL                     ((uint32_t)0x00100000)        /*!< Data available in transmit FIFO */
+#define  SDIO_STA_RXDAVL                     ((uint32_t)0x00200000)        /*!< Data available in receive FIFO */
+#define  SDIO_STA_SDIOIT                     ((uint32_t)0x00400000)        /*!< SDIO interrupt received */
+#define  SDIO_STA_CEATAEND                   ((uint32_t)0x00800000)        /*!< CE-ATA command completion signal received for CMD61 */
+
+/*******************  Bit definition for SDIO_ICR register  *******************/
+#define  SDIO_ICR_CCRCFAILC                  ((uint32_t)0x00000001)        /*!< CCRCFAIL flag clear bit */
+#define  SDIO_ICR_DCRCFAILC                  ((uint32_t)0x00000002)        /*!< DCRCFAIL flag clear bit */
+#define  SDIO_ICR_CTIMEOUTC                  ((uint32_t)0x00000004)        /*!< CTIMEOUT flag clear bit */
+#define  SDIO_ICR_DTIMEOUTC                  ((uint32_t)0x00000008)        /*!< DTIMEOUT flag clear bit */
+#define  SDIO_ICR_TXUNDERRC                  ((uint32_t)0x00000010)        /*!< TXUNDERR flag clear bit */
+#define  SDIO_ICR_RXOVERRC                   ((uint32_t)0x00000020)        /*!< RXOVERR flag clear bit */
+#define  SDIO_ICR_CMDRENDC                   ((uint32_t)0x00000040)        /*!< CMDREND flag clear bit */
+#define  SDIO_ICR_CMDSENTC                   ((uint32_t)0x00000080)        /*!< CMDSENT flag clear bit */
+#define  SDIO_ICR_DATAENDC                   ((uint32_t)0x00000100)        /*!< DATAEND flag clear bit */
+#define  SDIO_ICR_STBITERRC                  ((uint32_t)0x00000200)        /*!< STBITERR flag clear bit */
+#define  SDIO_ICR_DBCKENDC                   ((uint32_t)0x00000400)        /*!< DBCKEND flag clear bit */
+#define  SDIO_ICR_SDIOITC                    ((uint32_t)0x00400000)        /*!< SDIOIT flag clear bit */
+#define  SDIO_ICR_CEATAENDC                  ((uint32_t)0x00800000)        /*!< CEATAEND flag clear bit */
+
+/******************  Bit definition for SDIO_MASK register  *******************/
+#define  SDIO_MASK_CCRCFAILIE                ((uint32_t)0x00000001)        /*!< Command CRC Fail Interrupt Enable */
+#define  SDIO_MASK_DCRCFAILIE                ((uint32_t)0x00000002)        /*!< Data CRC Fail Interrupt Enable */
+#define  SDIO_MASK_CTIMEOUTIE                ((uint32_t)0x00000004)        /*!< Command TimeOut Interrupt Enable */
+#define  SDIO_MASK_DTIMEOUTIE                ((uint32_t)0x00000008)        /*!< Data TimeOut Interrupt Enable */
+#define  SDIO_MASK_TXUNDERRIE                ((uint32_t)0x00000010)        /*!< Tx FIFO UnderRun Error Interrupt Enable */
+#define  SDIO_MASK_RXOVERRIE                 ((uint32_t)0x00000020)        /*!< Rx FIFO OverRun Error Interrupt Enable */
+#define  SDIO_MASK_CMDRENDIE                 ((uint32_t)0x00000040)        /*!< Command Response Received Interrupt Enable */
+#define  SDIO_MASK_CMDSENTIE                 ((uint32_t)0x00000080)        /*!< Command Sent Interrupt Enable */
+#define  SDIO_MASK_DATAENDIE                 ((uint32_t)0x00000100)        /*!< Data End Interrupt Enable */
+#define  SDIO_MASK_STBITERRIE                ((uint32_t)0x00000200)        /*!< Start Bit Error Interrupt Enable */
+#define  SDIO_MASK_DBCKENDIE                 ((uint32_t)0x00000400)        /*!< Data Block End Interrupt Enable */
+#define  SDIO_MASK_CMDACTIE                  ((uint32_t)0x00000800)        /*!< Command Acting Interrupt Enable */
+#define  SDIO_MASK_TXACTIE                   ((uint32_t)0x00001000)        /*!< Data Transmit Acting Interrupt Enable */
+#define  SDIO_MASK_RXACTIE                   ((uint32_t)0x00002000)        /*!< Data receive acting interrupt enabled */
+#define  SDIO_MASK_TXFIFOHEIE                ((uint32_t)0x00004000)        /*!< Tx FIFO Half Empty interrupt Enable */
+#define  SDIO_MASK_RXFIFOHFIE                ((uint32_t)0x00008000)        /*!< Rx FIFO Half Full interrupt Enable */
+#define  SDIO_MASK_TXFIFOFIE                 ((uint32_t)0x00010000)        /*!< Tx FIFO Full interrupt Enable */
+#define  SDIO_MASK_RXFIFOFIE                 ((uint32_t)0x00020000)        /*!< Rx FIFO Full interrupt Enable */
+#define  SDIO_MASK_TXFIFOEIE                 ((uint32_t)0x00040000)        /*!< Tx FIFO Empty interrupt Enable */
+#define  SDIO_MASK_RXFIFOEIE                 ((uint32_t)0x00080000)        /*!< Rx FIFO Empty interrupt Enable */
+#define  SDIO_MASK_TXDAVLIE                  ((uint32_t)0x00100000)        /*!< Data available in Tx FIFO interrupt Enable */
+#define  SDIO_MASK_RXDAVLIE                  ((uint32_t)0x00200000)        /*!< Data available in Rx FIFO interrupt Enable */
+#define  SDIO_MASK_SDIOITIE                  ((uint32_t)0x00400000)        /*!< SDIO Mode Interrupt Received interrupt Enable */
+#define  SDIO_MASK_CEATAENDIE                ((uint32_t)0x00800000)        /*!< CE-ATA command completion signal received Interrupt Enable */
+
+/*****************  Bit definition for SDIO_FIFOCNT register  *****************/
+#define  SDIO_FIFOCNT_FIFOCOUNT              ((uint32_t)0x00FFFFFF)        /*!< Remaining number of words to be written to or read from the FIFO */
+
+/******************  Bit definition for SDIO_FIFO register  *******************/
+#define  SDIO_FIFO_FIFODATA                  ((uint32_t)0xFFFFFFFF)        /*!< Receive and transmit FIFO data */
+
+/******************************************************************************/
+/*                                                                            */
+/*                                   USB Device FS                            */
+/*                                                                            */
+/******************************************************************************/
+
+/*!< Endpoint-specific registers */
+/*******************  Bit definition for USB_EP0R register  *******************/
+#define  USB_EP0R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP0R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP0R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP0R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP0R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP0R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP0R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP0R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP0R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP0R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP0R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP0R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP0R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP0R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP0R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP0R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP1R register  *******************/
+#define  USB_EP1R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP1R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP1R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP1R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP1R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP1R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP1R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP1R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP1R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP1R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP1R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP1R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP1R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP1R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP1R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP1R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP2R register  *******************/
+#define  USB_EP2R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP2R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP2R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP2R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP2R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP2R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP2R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP2R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP2R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP2R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP2R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP2R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP2R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP2R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP2R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP2R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP3R register  *******************/
+#define  USB_EP3R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP3R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP3R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP3R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP3R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP3R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP3R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP3R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP3R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP3R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP3R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP3R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP3R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP3R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP3R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP3R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP4R register  *******************/
+#define  USB_EP4R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP4R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP4R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP4R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP4R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP4R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP4R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP4R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP4R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP4R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP4R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP4R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP4R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP4R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP4R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP4R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP5R register  *******************/
+#define  USB_EP5R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP5R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP5R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP5R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP5R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP5R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP5R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP5R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP5R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP5R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP5R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP5R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP5R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP5R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP5R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP5R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP6R register  *******************/
+#define  USB_EP6R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP6R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP6R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP6R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP6R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP6R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP6R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP6R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP6R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP6R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP6R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP6R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP6R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP6R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP6R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP6R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*******************  Bit definition for USB_EP7R register  *******************/
+#define  USB_EP7R_EA                         ((uint16_t)0x000F)            /*!< Endpoint Address */
+
+#define  USB_EP7R_STAT_TX                    ((uint16_t)0x0030)            /*!< STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define  USB_EP7R_STAT_TX_0                  ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  USB_EP7R_STAT_TX_1                  ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  USB_EP7R_DTOG_TX                    ((uint16_t)0x0040)            /*!< Data Toggle, for transmission transfers */
+#define  USB_EP7R_CTR_TX                     ((uint16_t)0x0080)            /*!< Correct Transfer for transmission */
+#define  USB_EP7R_EP_KIND                    ((uint16_t)0x0100)            /*!< Endpoint Kind */
+
+#define  USB_EP7R_EP_TYPE                    ((uint16_t)0x0600)            /*!< EP_TYPE[1:0] bits (Endpoint type) */
+#define  USB_EP7R_EP_TYPE_0                  ((uint16_t)0x0200)            /*!< Bit 0 */
+#define  USB_EP7R_EP_TYPE_1                  ((uint16_t)0x0400)            /*!< Bit 1 */
+
+#define  USB_EP7R_SETUP                      ((uint16_t)0x0800)            /*!< Setup transaction completed */
+
+#define  USB_EP7R_STAT_RX                    ((uint16_t)0x3000)            /*!< STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define  USB_EP7R_STAT_RX_0                  ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USB_EP7R_STAT_RX_1                  ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USB_EP7R_DTOG_RX                    ((uint16_t)0x4000)            /*!< Data Toggle, for reception transfers */
+#define  USB_EP7R_CTR_RX                     ((uint16_t)0x8000)            /*!< Correct Transfer for reception */
+
+/*!< Common registers */
+/*******************  Bit definition for USB_CNTR register  *******************/
+#define  USB_CNTR_FRES                       ((uint16_t)0x0001)            /*!< Force USB Reset */
+#define  USB_CNTR_PDWN                       ((uint16_t)0x0002)            /*!< Power down */
+#define  USB_CNTR_LP_MODE                    ((uint16_t)0x0004)            /*!< Low-power mode */
+#define  USB_CNTR_FSUSP                      ((uint16_t)0x0008)            /*!< Force suspend */
+#define  USB_CNTR_RESUME                     ((uint16_t)0x0010)            /*!< Resume request */
+#define  USB_CNTR_ESOFM                      ((uint16_t)0x0100)            /*!< Expected Start Of Frame Interrupt Mask */
+#define  USB_CNTR_SOFM                       ((uint16_t)0x0200)            /*!< Start Of Frame Interrupt Mask */
+#define  USB_CNTR_RESETM                     ((uint16_t)0x0400)            /*!< RESET Interrupt Mask */
+#define  USB_CNTR_SUSPM                      ((uint16_t)0x0800)            /*!< Suspend mode Interrupt Mask */
+#define  USB_CNTR_WKUPM                      ((uint16_t)0x1000)            /*!< Wakeup Interrupt Mask */
+#define  USB_CNTR_ERRM                       ((uint16_t)0x2000)            /*!< Error Interrupt Mask */
+#define  USB_CNTR_PMAOVRM                    ((uint16_t)0x4000)            /*!< Packet Memory Area Over / Underrun Interrupt Mask */
+#define  USB_CNTR_CTRM                       ((uint16_t)0x8000)            /*!< Correct Transfer Interrupt Mask */
+
+/*******************  Bit definition for USB_ISTR register  *******************/
+#define  USB_ISTR_EP_ID                      ((uint16_t)0x000F)            /*!< Endpoint Identifier */
+#define  USB_ISTR_DIR                        ((uint16_t)0x0010)            /*!< Direction of transaction */
+#define  USB_ISTR_ESOF                       ((uint16_t)0x0100)            /*!< Expected Start Of Frame */
+#define  USB_ISTR_SOF                        ((uint16_t)0x0200)            /*!< Start Of Frame */
+#define  USB_ISTR_RESET                      ((uint16_t)0x0400)            /*!< USB RESET request */
+#define  USB_ISTR_SUSP                       ((uint16_t)0x0800)            /*!< Suspend mode request */
+#define  USB_ISTR_WKUP                       ((uint16_t)0x1000)            /*!< Wake up */
+#define  USB_ISTR_ERR                        ((uint16_t)0x2000)            /*!< Error */
+#define  USB_ISTR_PMAOVR                     ((uint16_t)0x4000)            /*!< Packet Memory Area Over / Underrun */
+#define  USB_ISTR_CTR                        ((uint16_t)0x8000)            /*!< Correct Transfer */
+
+/*******************  Bit definition for USB_FNR register  ********************/
+#define  USB_FNR_FN                          ((uint16_t)0x07FF)            /*!< Frame Number */
+#define  USB_FNR_LSOF                        ((uint16_t)0x1800)            /*!< Lost SOF */
+#define  USB_FNR_LCK                         ((uint16_t)0x2000)            /*!< Locked */
+#define  USB_FNR_RXDM                        ((uint16_t)0x4000)            /*!< Receive Data - Line Status */
+#define  USB_FNR_RXDP                        ((uint16_t)0x8000)            /*!< Receive Data + Line Status */
+
+/******************  Bit definition for USB_DADDR register  *******************/
+#define  USB_DADDR_ADD                       ((uint8_t)0x7F)               /*!< ADD[6:0] bits (Device Address) */
+#define  USB_DADDR_ADD0                      ((uint8_t)0x01)               /*!< Bit 0 */
+#define  USB_DADDR_ADD1                      ((uint8_t)0x02)               /*!< Bit 1 */
+#define  USB_DADDR_ADD2                      ((uint8_t)0x04)               /*!< Bit 2 */
+#define  USB_DADDR_ADD3                      ((uint8_t)0x08)               /*!< Bit 3 */
+#define  USB_DADDR_ADD4                      ((uint8_t)0x10)               /*!< Bit 4 */
+#define  USB_DADDR_ADD5                      ((uint8_t)0x20)               /*!< Bit 5 */
+#define  USB_DADDR_ADD6                      ((uint8_t)0x40)               /*!< Bit 6 */
+
+#define  USB_DADDR_EF                        ((uint8_t)0x80)               /*!< Enable Function */
+
+/******************  Bit definition for USB_BTABLE register  ******************/    
+#define  USB_BTABLE_BTABLE                   ((uint16_t)0xFFF8)            /*!< Buffer Table */
+
+/*!< Buffer descriptor table */
+/*****************  Bit definition for USB_ADDR0_TX register  *****************/
+#define  USB_ADDR0_TX_ADDR0_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 0 */
+
+/*****************  Bit definition for USB_ADDR1_TX register  *****************/
+#define  USB_ADDR1_TX_ADDR1_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 1 */
+
+/*****************  Bit definition for USB_ADDR2_TX register  *****************/
+#define  USB_ADDR2_TX_ADDR2_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 2 */
+
+/*****************  Bit definition for USB_ADDR3_TX register  *****************/
+#define  USB_ADDR3_TX_ADDR3_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 3 */
+
+/*****************  Bit definition for USB_ADDR4_TX register  *****************/
+#define  USB_ADDR4_TX_ADDR4_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 4 */
+
+/*****************  Bit definition for USB_ADDR5_TX register  *****************/
+#define  USB_ADDR5_TX_ADDR5_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 5 */
+
+/*****************  Bit definition for USB_ADDR6_TX register  *****************/
+#define  USB_ADDR6_TX_ADDR6_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 6 */
+
+/*****************  Bit definition for USB_ADDR7_TX register  *****************/
+#define  USB_ADDR7_TX_ADDR7_TX               ((uint16_t)0xFFFE)            /*!< Transmission Buffer Address 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/*****************  Bit definition for USB_COUNT0_TX register  ****************/
+#define  USB_COUNT0_TX_COUNT0_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 0 */
+
+/*****************  Bit definition for USB_COUNT1_TX register  ****************/
+#define  USB_COUNT1_TX_COUNT1_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 1 */
+
+/*****************  Bit definition for USB_COUNT2_TX register  ****************/
+#define  USB_COUNT2_TX_COUNT2_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 2 */
+
+/*****************  Bit definition for USB_COUNT3_TX register  ****************/
+#define  USB_COUNT3_TX_COUNT3_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 3 */
+
+/*****************  Bit definition for USB_COUNT4_TX register  ****************/
+#define  USB_COUNT4_TX_COUNT4_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 4 */
+
+/*****************  Bit definition for USB_COUNT5_TX register  ****************/
+#define  USB_COUNT5_TX_COUNT5_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 5 */
+
+/*****************  Bit definition for USB_COUNT6_TX register  ****************/
+#define  USB_COUNT6_TX_COUNT6_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 6 */
+
+/*****************  Bit definition for USB_COUNT7_TX register  ****************/
+#define  USB_COUNT7_TX_COUNT7_TX             ((uint16_t)0x03FF)            /*!< Transmission Byte Count 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/****************  Bit definition for USB_COUNT0_TX_0 register  ***************/
+#define  USB_COUNT0_TX_0_COUNT0_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 0 (low) */
+
+/****************  Bit definition for USB_COUNT0_TX_1 register  ***************/
+#define  USB_COUNT0_TX_1_COUNT0_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 0 (high) */
+
+/****************  Bit definition for USB_COUNT1_TX_0 register  ***************/
+#define  USB_COUNT1_TX_0_COUNT1_TX_0          ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 1 (low) */
+
+/****************  Bit definition for USB_COUNT1_TX_1 register  ***************/
+#define  USB_COUNT1_TX_1_COUNT1_TX_1          ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 1 (high) */
+
+/****************  Bit definition for USB_COUNT2_TX_0 register  ***************/
+#define  USB_COUNT2_TX_0_COUNT2_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 2 (low) */
+
+/****************  Bit definition for USB_COUNT2_TX_1 register  ***************/
+#define  USB_COUNT2_TX_1_COUNT2_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 2 (high) */
+
+/****************  Bit definition for USB_COUNT3_TX_0 register  ***************/
+#define  USB_COUNT3_TX_0_COUNT3_TX_0         ((uint16_t)0x000003FF)        /*!< Transmission Byte Count 3 (low) */
+
+/****************  Bit definition for USB_COUNT3_TX_1 register  ***************/
+#define  USB_COUNT3_TX_1_COUNT3_TX_1         ((uint16_t)0x03FF0000)        /*!< Transmission Byte Count 3 (high) */
+
+/****************  Bit definition for USB_COUNT4_TX_0 register  ***************/
+#define  USB_COUNT4_TX_0_COUNT4_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 4 (low) */
+
+/****************  Bit definition for USB_COUNT4_TX_1 register  ***************/
+#define  USB_COUNT4_TX_1_COUNT4_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 4 (high) */
+
+/****************  Bit definition for USB_COUNT5_TX_0 register  ***************/
+#define  USB_COUNT5_TX_0_COUNT5_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 5 (low) */
+
+/****************  Bit definition for USB_COUNT5_TX_1 register  ***************/
+#define  USB_COUNT5_TX_1_COUNT5_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 5 (high) */
+
+/****************  Bit definition for USB_COUNT6_TX_0 register  ***************/
+#define  USB_COUNT6_TX_0_COUNT6_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 6 (low) */
+
+/****************  Bit definition for USB_COUNT6_TX_1 register  ***************/
+#define  USB_COUNT6_TX_1_COUNT6_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 6 (high) */
+
+/****************  Bit definition for USB_COUNT7_TX_0 register  ***************/
+#define  USB_COUNT7_TX_0_COUNT7_TX_0         ((uint32_t)0x000003FF)        /*!< Transmission Byte Count 7 (low) */
+
+/****************  Bit definition for USB_COUNT7_TX_1 register  ***************/
+#define  USB_COUNT7_TX_1_COUNT7_TX_1         ((uint32_t)0x03FF0000)        /*!< Transmission Byte Count 7 (high) */
+
+/*----------------------------------------------------------------------------*/
+
+/*****************  Bit definition for USB_ADDR0_RX register  *****************/
+#define  USB_ADDR0_RX_ADDR0_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 0 */
+
+/*****************  Bit definition for USB_ADDR1_RX register  *****************/
+#define  USB_ADDR1_RX_ADDR1_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 1 */
+
+/*****************  Bit definition for USB_ADDR2_RX register  *****************/
+#define  USB_ADDR2_RX_ADDR2_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 2 */
+
+/*****************  Bit definition for USB_ADDR3_RX register  *****************/
+#define  USB_ADDR3_RX_ADDR3_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 3 */
+
+/*****************  Bit definition for USB_ADDR4_RX register  *****************/
+#define  USB_ADDR4_RX_ADDR4_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 4 */
+
+/*****************  Bit definition for USB_ADDR5_RX register  *****************/
+#define  USB_ADDR5_RX_ADDR5_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 5 */
+
+/*****************  Bit definition for USB_ADDR6_RX register  *****************/
+#define  USB_ADDR6_RX_ADDR6_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 6 */
+
+/*****************  Bit definition for USB_ADDR7_RX register  *****************/
+#define  USB_ADDR7_RX_ADDR7_RX               ((uint16_t)0xFFFE)            /*!< Reception Buffer Address 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/*****************  Bit definition for USB_COUNT0_RX register  ****************/
+#define  USB_COUNT0_RX_COUNT0_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT0_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT0_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT0_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT0_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT0_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT0_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT0_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT1_RX register  ****************/
+#define  USB_COUNT1_RX_COUNT1_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT1_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT1_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT1_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT1_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT1_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT1_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT1_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT2_RX register  ****************/
+#define  USB_COUNT2_RX_COUNT2_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT2_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT2_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT2_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT2_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT2_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT2_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT2_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT3_RX register  ****************/
+#define  USB_COUNT3_RX_COUNT3_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT3_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT3_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT3_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT3_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT3_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT3_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT3_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT4_RX register  ****************/
+#define  USB_COUNT4_RX_COUNT4_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT4_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT4_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT4_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT4_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT4_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT4_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT4_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT5_RX register  ****************/
+#define  USB_COUNT5_RX_COUNT5_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT5_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT5_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT5_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT5_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT5_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT5_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT5_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT6_RX register  ****************/
+#define  USB_COUNT6_RX_COUNT6_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT6_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT6_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT6_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT6_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT6_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT6_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT6_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*****************  Bit definition for USB_COUNT7_RX register  ****************/
+#define  USB_COUNT7_RX_COUNT7_RX             ((uint16_t)0x03FF)            /*!< Reception Byte Count */
+
+#define  USB_COUNT7_RX_NUM_BLOCK             ((uint16_t)0x7C00)            /*!< NUM_BLOCK[4:0] bits (Number of blocks) */
+#define  USB_COUNT7_RX_NUM_BLOCK_0           ((uint16_t)0x0400)            /*!< Bit 0 */
+#define  USB_COUNT7_RX_NUM_BLOCK_1           ((uint16_t)0x0800)            /*!< Bit 1 */
+#define  USB_COUNT7_RX_NUM_BLOCK_2           ((uint16_t)0x1000)            /*!< Bit 2 */
+#define  USB_COUNT7_RX_NUM_BLOCK_3           ((uint16_t)0x2000)            /*!< Bit 3 */
+#define  USB_COUNT7_RX_NUM_BLOCK_4           ((uint16_t)0x4000)            /*!< Bit 4 */
+
+#define  USB_COUNT7_RX_BLSIZE                ((uint16_t)0x8000)            /*!< BLock SIZE */
+
+/*----------------------------------------------------------------------------*/
+
+/****************  Bit definition for USB_COUNT0_RX_0 register  ***************/
+#define  USB_COUNT0_RX_0_COUNT0_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT0_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT0_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT0_RX_1 register  ***************/
+#define  USB_COUNT0_RX_1_COUNT0_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 1 */
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT0_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT0_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/****************  Bit definition for USB_COUNT1_RX_0 register  ***************/
+#define  USB_COUNT1_RX_0_COUNT1_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT1_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT1_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT1_RX_1 register  ***************/
+#define  USB_COUNT1_RX_1_COUNT1_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT1_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT1_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/****************  Bit definition for USB_COUNT2_RX_0 register  ***************/
+#define  USB_COUNT2_RX_0_COUNT2_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT2_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT2_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT2_RX_1 register  ***************/
+#define  USB_COUNT2_RX_1_COUNT2_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT2_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT2_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/****************  Bit definition for USB_COUNT3_RX_0 register  ***************/
+#define  USB_COUNT3_RX_0_COUNT3_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT3_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT3_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT3_RX_1 register  ***************/
+#define  USB_COUNT3_RX_1_COUNT3_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT3_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT3_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/****************  Bit definition for USB_COUNT4_RX_0 register  ***************/
+#define  USB_COUNT4_RX_0_COUNT4_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0_0      ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0_1      ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0_2      ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0_3      ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT4_RX_0_NUM_BLOCK_0_4      ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT4_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT4_RX_1 register  ***************/
+#define  USB_COUNT4_RX_1_COUNT4_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT4_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT4_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/****************  Bit definition for USB_COUNT5_RX_0 register  ***************/
+#define  USB_COUNT5_RX_0_COUNT5_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT5_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT5_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT5_RX_1 register  ***************/
+#define  USB_COUNT5_RX_1_COUNT5_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT5_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT5_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/***************  Bit definition for USB_COUNT6_RX_0  register  ***************/
+#define  USB_COUNT6_RX_0_COUNT6_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT6_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT6_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/****************  Bit definition for USB_COUNT6_RX_1 register  ***************/
+#define  USB_COUNT6_RX_1_COUNT6_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT6_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT6_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/***************  Bit definition for USB_COUNT7_RX_0 register  ****************/
+#define  USB_COUNT7_RX_0_COUNT7_RX_0         ((uint32_t)0x000003FF)        /*!< Reception Byte Count (low) */
+
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0         ((uint32_t)0x00007C00)        /*!< NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0_0       ((uint32_t)0x00000400)        /*!< Bit 0 */
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0_1       ((uint32_t)0x00000800)        /*!< Bit 1 */
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0_2       ((uint32_t)0x00001000)        /*!< Bit 2 */
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0_3       ((uint32_t)0x00002000)        /*!< Bit 3 */
+#define  USB_COUNT7_RX_0_NUM_BLOCK_0_4       ((uint32_t)0x00004000)        /*!< Bit 4 */
+
+#define  USB_COUNT7_RX_0_BLSIZE_0            ((uint32_t)0x00008000)        /*!< BLock SIZE (low) */
+
+/***************  Bit definition for USB_COUNT7_RX_1 register  ****************/
+#define  USB_COUNT7_RX_1_COUNT7_RX_1         ((uint32_t)0x03FF0000)        /*!< Reception Byte Count (high) */
+
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1         ((uint32_t)0x7C000000)        /*!< NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1_0       ((uint32_t)0x04000000)        /*!< Bit 0 */
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1_1       ((uint32_t)0x08000000)        /*!< Bit 1 */
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1_2       ((uint32_t)0x10000000)        /*!< Bit 2 */
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1_3       ((uint32_t)0x20000000)        /*!< Bit 3 */
+#define  USB_COUNT7_RX_1_NUM_BLOCK_1_4       ((uint32_t)0x40000000)        /*!< Bit 4 */
+
+#define  USB_COUNT7_RX_1_BLSIZE_1            ((uint32_t)0x80000000)        /*!< BLock SIZE (high) */
+
+/******************************************************************************/
+/*                                                                            */
+/*                         Controller Area Network                            */
+/*                                                                            */
+/******************************************************************************/
+
+/*!< CAN control and status registers */
+/*******************  Bit definition for CAN_MCR register  ********************/
+#define  CAN_MCR_INRQ                        ((uint16_t)0x0001)            /*!< Initialization Request */
+#define  CAN_MCR_SLEEP                       ((uint16_t)0x0002)            /*!< Sleep Mode Request */
+#define  CAN_MCR_TXFP                        ((uint16_t)0x0004)            /*!< Transmit FIFO Priority */
+#define  CAN_MCR_RFLM                        ((uint16_t)0x0008)            /*!< Receive FIFO Locked Mode */
+#define  CAN_MCR_NART                        ((uint16_t)0x0010)            /*!< No Automatic Retransmission */
+#define  CAN_MCR_AWUM                        ((uint16_t)0x0020)            /*!< Automatic Wakeup Mode */
+#define  CAN_MCR_ABOM                        ((uint16_t)0x0040)            /*!< Automatic Bus-Off Management */
+#define  CAN_MCR_TTCM                        ((uint16_t)0x0080)            /*!< Time Triggered Communication Mode */
+#define  CAN_MCR_RESET                       ((uint16_t)0x8000)            /*!< CAN software master reset */
+
+/*******************  Bit definition for CAN_MSR register  ********************/
+#define  CAN_MSR_INAK                        ((uint16_t)0x0001)            /*!< Initialization Acknowledge */
+#define  CAN_MSR_SLAK                        ((uint16_t)0x0002)            /*!< Sleep Acknowledge */
+#define  CAN_MSR_ERRI                        ((uint16_t)0x0004)            /*!< Error Interrupt */
+#define  CAN_MSR_WKUI                        ((uint16_t)0x0008)            /*!< Wakeup Interrupt */
+#define  CAN_MSR_SLAKI                       ((uint16_t)0x0010)            /*!< Sleep Acknowledge Interrupt */
+#define  CAN_MSR_TXM                         ((uint16_t)0x0100)            /*!< Transmit Mode */
+#define  CAN_MSR_RXM                         ((uint16_t)0x0200)            /*!< Receive Mode */
+#define  CAN_MSR_SAMP                        ((uint16_t)0x0400)            /*!< Last Sample Point */
+#define  CAN_MSR_RX                          ((uint16_t)0x0800)            /*!< CAN Rx Signal */
+
+/*******************  Bit definition for CAN_TSR register  ********************/
+#define  CAN_TSR_RQCP0                       ((uint32_t)0x00000001)        /*!< Request Completed Mailbox0 */
+#define  CAN_TSR_TXOK0                       ((uint32_t)0x00000002)        /*!< Transmission OK of Mailbox0 */
+#define  CAN_TSR_ALST0                       ((uint32_t)0x00000004)        /*!< Arbitration Lost for Mailbox0 */
+#define  CAN_TSR_TERR0                       ((uint32_t)0x00000008)        /*!< Transmission Error of Mailbox0 */
+#define  CAN_TSR_ABRQ0                       ((uint32_t)0x00000080)        /*!< Abort Request for Mailbox0 */
+#define  CAN_TSR_RQCP1                       ((uint32_t)0x00000100)        /*!< Request Completed Mailbox1 */
+#define  CAN_TSR_TXOK1                       ((uint32_t)0x00000200)        /*!< Transmission OK of Mailbox1 */
+#define  CAN_TSR_ALST1                       ((uint32_t)0x00000400)        /*!< Arbitration Lost for Mailbox1 */
+#define  CAN_TSR_TERR1                       ((uint32_t)0x00000800)        /*!< Transmission Error of Mailbox1 */
+#define  CAN_TSR_ABRQ1                       ((uint32_t)0x00008000)        /*!< Abort Request for Mailbox 1 */
+#define  CAN_TSR_RQCP2                       ((uint32_t)0x00010000)        /*!< Request Completed Mailbox2 */
+#define  CAN_TSR_TXOK2                       ((uint32_t)0x00020000)        /*!< Transmission OK of Mailbox 2 */
+#define  CAN_TSR_ALST2                       ((uint32_t)0x00040000)        /*!< Arbitration Lost for mailbox 2 */
+#define  CAN_TSR_TERR2                       ((uint32_t)0x00080000)        /*!< Transmission Error of Mailbox 2 */
+#define  CAN_TSR_ABRQ2                       ((uint32_t)0x00800000)        /*!< Abort Request for Mailbox 2 */
+#define  CAN_TSR_CODE                        ((uint32_t)0x03000000)        /*!< Mailbox Code */
+
+#define  CAN_TSR_TME                         ((uint32_t)0x1C000000)        /*!< TME[2:0] bits */
+#define  CAN_TSR_TME0                        ((uint32_t)0x04000000)        /*!< Transmit Mailbox 0 Empty */
+#define  CAN_TSR_TME1                        ((uint32_t)0x08000000)        /*!< Transmit Mailbox 1 Empty */
+#define  CAN_TSR_TME2                        ((uint32_t)0x10000000)        /*!< Transmit Mailbox 2 Empty */
+
+#define  CAN_TSR_LOW                         ((uint32_t)0xE0000000)        /*!< LOW[2:0] bits */
+#define  CAN_TSR_LOW0                        ((uint32_t)0x20000000)        /*!< Lowest Priority Flag for Mailbox 0 */
+#define  CAN_TSR_LOW1                        ((uint32_t)0x40000000)        /*!< Lowest Priority Flag for Mailbox 1 */
+#define  CAN_TSR_LOW2                        ((uint32_t)0x80000000)        /*!< Lowest Priority Flag for Mailbox 2 */
+
+/*******************  Bit definition for CAN_RF0R register  *******************/
+#define  CAN_RF0R_FMP0                       ((uint8_t)0x03)               /*!< FIFO 0 Message Pending */
+#define  CAN_RF0R_FULL0                      ((uint8_t)0x08)               /*!< FIFO 0 Full */
+#define  CAN_RF0R_FOVR0                      ((uint8_t)0x10)               /*!< FIFO 0 Overrun */
+#define  CAN_RF0R_RFOM0                      ((uint8_t)0x20)               /*!< Release FIFO 0 Output Mailbox */
+
+/*******************  Bit definition for CAN_RF1R register  *******************/
+#define  CAN_RF1R_FMP1                       ((uint8_t)0x03)               /*!< FIFO 1 Message Pending */
+#define  CAN_RF1R_FULL1                      ((uint8_t)0x08)               /*!< FIFO 1 Full */
+#define  CAN_RF1R_FOVR1                      ((uint8_t)0x10)               /*!< FIFO 1 Overrun */
+#define  CAN_RF1R_RFOM1                      ((uint8_t)0x20)               /*!< Release FIFO 1 Output Mailbox */
+
+/********************  Bit definition for CAN_IER register  *******************/
+#define  CAN_IER_TMEIE                       ((uint32_t)0x00000001)        /*!< Transmit Mailbox Empty Interrupt Enable */
+#define  CAN_IER_FMPIE0                      ((uint32_t)0x00000002)        /*!< FIFO Message Pending Interrupt Enable */
+#define  CAN_IER_FFIE0                       ((uint32_t)0x00000004)        /*!< FIFO Full Interrupt Enable */
+#define  CAN_IER_FOVIE0                      ((uint32_t)0x00000008)        /*!< FIFO Overrun Interrupt Enable */
+#define  CAN_IER_FMPIE1                      ((uint32_t)0x00000010)        /*!< FIFO Message Pending Interrupt Enable */
+#define  CAN_IER_FFIE1                       ((uint32_t)0x00000020)        /*!< FIFO Full Interrupt Enable */
+#define  CAN_IER_FOVIE1                      ((uint32_t)0x00000040)        /*!< FIFO Overrun Interrupt Enable */
+#define  CAN_IER_EWGIE                       ((uint32_t)0x00000100)        /*!< Error Warning Interrupt Enable */
+#define  CAN_IER_EPVIE                       ((uint32_t)0x00000200)        /*!< Error Passive Interrupt Enable */
+#define  CAN_IER_BOFIE                       ((uint32_t)0x00000400)        /*!< Bus-Off Interrupt Enable */
+#define  CAN_IER_LECIE                       ((uint32_t)0x00000800)        /*!< Last Error Code Interrupt Enable */
+#define  CAN_IER_ERRIE                       ((uint32_t)0x00008000)        /*!< Error Interrupt Enable */
+#define  CAN_IER_WKUIE                       ((uint32_t)0x00010000)        /*!< Wakeup Interrupt Enable */
+#define  CAN_IER_SLKIE                       ((uint32_t)0x00020000)        /*!< Sleep Interrupt Enable */
+
+/********************  Bit definition for CAN_ESR register  *******************/
+#define  CAN_ESR_EWGF                        ((uint32_t)0x00000001)        /*!< Error Warning Flag */
+#define  CAN_ESR_EPVF                        ((uint32_t)0x00000002)        /*!< Error Passive Flag */
+#define  CAN_ESR_BOFF                        ((uint32_t)0x00000004)        /*!< Bus-Off Flag */
+
+#define  CAN_ESR_LEC                         ((uint32_t)0x00000070)        /*!< LEC[2:0] bits (Last Error Code) */
+#define  CAN_ESR_LEC_0                       ((uint32_t)0x00000010)        /*!< Bit 0 */
+#define  CAN_ESR_LEC_1                       ((uint32_t)0x00000020)        /*!< Bit 1 */
+#define  CAN_ESR_LEC_2                       ((uint32_t)0x00000040)        /*!< Bit 2 */
+
+#define  CAN_ESR_TEC                         ((uint32_t)0x00FF0000)        /*!< Least significant byte of the 9-bit Transmit Error Counter */
+#define  CAN_ESR_REC                         ((uint32_t)0xFF000000)        /*!< Receive Error Counter */
+
+/*******************  Bit definition for CAN_BTR register  ********************/
+#define  CAN_BTR_BRP                         ((uint32_t)0x000003FF)        /*!< Baud Rate Prescaler */
+#define  CAN_BTR_TS1                         ((uint32_t)0x000F0000)        /*!< Time Segment 1 */
+#define  CAN_BTR_TS2                         ((uint32_t)0x00700000)        /*!< Time Segment 2 */
+#define  CAN_BTR_SJW                         ((uint32_t)0x03000000)        /*!< Resynchronization Jump Width */
+#define  CAN_BTR_LBKM                        ((uint32_t)0x40000000)        /*!< Loop Back Mode (Debug) */
+#define  CAN_BTR_SILM                        ((uint32_t)0x80000000)        /*!< Silent Mode */
+
+/*!< Mailbox registers */
+/******************  Bit definition for CAN_TI0R register  ********************/
+#define  CAN_TI0R_TXRQ                       ((uint32_t)0x00000001)        /*!< Transmit Mailbox Request */
+#define  CAN_TI0R_RTR                        ((uint32_t)0x00000002)        /*!< Remote Transmission Request */
+#define  CAN_TI0R_IDE                        ((uint32_t)0x00000004)        /*!< Identifier Extension */
+#define  CAN_TI0R_EXID                       ((uint32_t)0x001FFFF8)        /*!< Extended Identifier */
+#define  CAN_TI0R_STID                       ((uint32_t)0xFFE00000)        /*!< Standard Identifier or Extended Identifier */
+
+/******************  Bit definition for CAN_TDT0R register  *******************/
+#define  CAN_TDT0R_DLC                       ((uint32_t)0x0000000F)        /*!< Data Length Code */
+#define  CAN_TDT0R_TGT                       ((uint32_t)0x00000100)        /*!< Transmit Global Time */
+#define  CAN_TDT0R_TIME                      ((uint32_t)0xFFFF0000)        /*!< Message Time Stamp */
+
+/******************  Bit definition for CAN_TDL0R register  *******************/
+#define  CAN_TDL0R_DATA0                     ((uint32_t)0x000000FF)        /*!< Data byte 0 */
+#define  CAN_TDL0R_DATA1                     ((uint32_t)0x0000FF00)        /*!< Data byte 1 */
+#define  CAN_TDL0R_DATA2                     ((uint32_t)0x00FF0000)        /*!< Data byte 2 */
+#define  CAN_TDL0R_DATA3                     ((uint32_t)0xFF000000)        /*!< Data byte 3 */
+
+/******************  Bit definition for CAN_TDH0R register  *******************/
+#define  CAN_TDH0R_DATA4                     ((uint32_t)0x000000FF)        /*!< Data byte 4 */
+#define  CAN_TDH0R_DATA5                     ((uint32_t)0x0000FF00)        /*!< Data byte 5 */
+#define  CAN_TDH0R_DATA6                     ((uint32_t)0x00FF0000)        /*!< Data byte 6 */
+#define  CAN_TDH0R_DATA7                     ((uint32_t)0xFF000000)        /*!< Data byte 7 */
+
+/*******************  Bit definition for CAN_TI1R register  *******************/
+#define  CAN_TI1R_TXRQ                       ((uint32_t)0x00000001)        /*!< Transmit Mailbox Request */
+#define  CAN_TI1R_RTR                        ((uint32_t)0x00000002)        /*!< Remote Transmission Request */
+#define  CAN_TI1R_IDE                        ((uint32_t)0x00000004)        /*!< Identifier Extension */
+#define  CAN_TI1R_EXID                       ((uint32_t)0x001FFFF8)        /*!< Extended Identifier */
+#define  CAN_TI1R_STID                       ((uint32_t)0xFFE00000)        /*!< Standard Identifier or Extended Identifier */
+
+/*******************  Bit definition for CAN_TDT1R register  ******************/
+#define  CAN_TDT1R_DLC                       ((uint32_t)0x0000000F)        /*!< Data Length Code */
+#define  CAN_TDT1R_TGT                       ((uint32_t)0x00000100)        /*!< Transmit Global Time */
+#define  CAN_TDT1R_TIME                      ((uint32_t)0xFFFF0000)        /*!< Message Time Stamp */
+
+/*******************  Bit definition for CAN_TDL1R register  ******************/
+#define  CAN_TDL1R_DATA0                     ((uint32_t)0x000000FF)        /*!< Data byte 0 */
+#define  CAN_TDL1R_DATA1                     ((uint32_t)0x0000FF00)        /*!< Data byte 1 */
+#define  CAN_TDL1R_DATA2                     ((uint32_t)0x00FF0000)        /*!< Data byte 2 */
+#define  CAN_TDL1R_DATA3                     ((uint32_t)0xFF000000)        /*!< Data byte 3 */
+
+/*******************  Bit definition for CAN_TDH1R register  ******************/
+#define  CAN_TDH1R_DATA4                     ((uint32_t)0x000000FF)        /*!< Data byte 4 */
+#define  CAN_TDH1R_DATA5                     ((uint32_t)0x0000FF00)        /*!< Data byte 5 */
+#define  CAN_TDH1R_DATA6                     ((uint32_t)0x00FF0000)        /*!< Data byte 6 */
+#define  CAN_TDH1R_DATA7                     ((uint32_t)0xFF000000)        /*!< Data byte 7 */
+
+/*******************  Bit definition for CAN_TI2R register  *******************/
+#define  CAN_TI2R_TXRQ                       ((uint32_t)0x00000001)        /*!< Transmit Mailbox Request */
+#define  CAN_TI2R_RTR                        ((uint32_t)0x00000002)        /*!< Remote Transmission Request */
+#define  CAN_TI2R_IDE                        ((uint32_t)0x00000004)        /*!< Identifier Extension */
+#define  CAN_TI2R_EXID                       ((uint32_t)0x001FFFF8)        /*!< Extended identifier */
+#define  CAN_TI2R_STID                       ((uint32_t)0xFFE00000)        /*!< Standard Identifier or Extended Identifier */
+
+/*******************  Bit definition for CAN_TDT2R register  ******************/  
+#define  CAN_TDT2R_DLC                       ((uint32_t)0x0000000F)        /*!< Data Length Code */
+#define  CAN_TDT2R_TGT                       ((uint32_t)0x00000100)        /*!< Transmit Global Time */
+#define  CAN_TDT2R_TIME                      ((uint32_t)0xFFFF0000)        /*!< Message Time Stamp */
+
+/*******************  Bit definition for CAN_TDL2R register  ******************/
+#define  CAN_TDL2R_DATA0                     ((uint32_t)0x000000FF)        /*!< Data byte 0 */
+#define  CAN_TDL2R_DATA1                     ((uint32_t)0x0000FF00)        /*!< Data byte 1 */
+#define  CAN_TDL2R_DATA2                     ((uint32_t)0x00FF0000)        /*!< Data byte 2 */
+#define  CAN_TDL2R_DATA3                     ((uint32_t)0xFF000000)        /*!< Data byte 3 */
+
+/*******************  Bit definition for CAN_TDH2R register  ******************/
+#define  CAN_TDH2R_DATA4                     ((uint32_t)0x000000FF)        /*!< Data byte 4 */
+#define  CAN_TDH2R_DATA5                     ((uint32_t)0x0000FF00)        /*!< Data byte 5 */
+#define  CAN_TDH2R_DATA6                     ((uint32_t)0x00FF0000)        /*!< Data byte 6 */
+#define  CAN_TDH2R_DATA7                     ((uint32_t)0xFF000000)        /*!< Data byte 7 */
+
+/*******************  Bit definition for CAN_RI0R register  *******************/
+#define  CAN_RI0R_RTR                        ((uint32_t)0x00000002)        /*!< Remote Transmission Request */
+#define  CAN_RI0R_IDE                        ((uint32_t)0x00000004)        /*!< Identifier Extension */
+#define  CAN_RI0R_EXID                       ((uint32_t)0x001FFFF8)        /*!< Extended Identifier */
+#define  CAN_RI0R_STID                       ((uint32_t)0xFFE00000)        /*!< Standard Identifier or Extended Identifier */
+
+/*******************  Bit definition for CAN_RDT0R register  ******************/
+#define  CAN_RDT0R_DLC                       ((uint32_t)0x0000000F)        /*!< Data Length Code */
+#define  CAN_RDT0R_FMI                       ((uint32_t)0x0000FF00)        /*!< Filter Match Index */
+#define  CAN_RDT0R_TIME                      ((uint32_t)0xFFFF0000)        /*!< Message Time Stamp */
+
+/*******************  Bit definition for CAN_RDL0R register  ******************/
+#define  CAN_RDL0R_DATA0                     ((uint32_t)0x000000FF)        /*!< Data byte 0 */
+#define  CAN_RDL0R_DATA1                     ((uint32_t)0x0000FF00)        /*!< Data byte 1 */
+#define  CAN_RDL0R_DATA2                     ((uint32_t)0x00FF0000)        /*!< Data byte 2 */
+#define  CAN_RDL0R_DATA3                     ((uint32_t)0xFF000000)        /*!< Data byte 3 */
+
+/*******************  Bit definition for CAN_RDH0R register  ******************/
+#define  CAN_RDH0R_DATA4                     ((uint32_t)0x000000FF)        /*!< Data byte 4 */
+#define  CAN_RDH0R_DATA5                     ((uint32_t)0x0000FF00)        /*!< Data byte 5 */
+#define  CAN_RDH0R_DATA6                     ((uint32_t)0x00FF0000)        /*!< Data byte 6 */
+#define  CAN_RDH0R_DATA7                     ((uint32_t)0xFF000000)        /*!< Data byte 7 */
+
+/*******************  Bit definition for CAN_RI1R register  *******************/
+#define  CAN_RI1R_RTR                        ((uint32_t)0x00000002)        /*!< Remote Transmission Request */
+#define  CAN_RI1R_IDE                        ((uint32_t)0x00000004)        /*!< Identifier Extension */
+#define  CAN_RI1R_EXID                       ((uint32_t)0x001FFFF8)        /*!< Extended identifier */
+#define  CAN_RI1R_STID                       ((uint32_t)0xFFE00000)        /*!< Standard Identifier or Extended Identifier */
+
+/*******************  Bit definition for CAN_RDT1R register  ******************/
+#define  CAN_RDT1R_DLC                       ((uint32_t)0x0000000F)        /*!< Data Length Code */
+#define  CAN_RDT1R_FMI                       ((uint32_t)0x0000FF00)        /*!< Filter Match Index */
+#define  CAN_RDT1R_TIME                      ((uint32_t)0xFFFF0000)        /*!< Message Time Stamp */
+
+/*******************  Bit definition for CAN_RDL1R register  ******************/
+#define  CAN_RDL1R_DATA0                     ((uint32_t)0x000000FF)        /*!< Data byte 0 */
+#define  CAN_RDL1R_DATA1                     ((uint32_t)0x0000FF00)        /*!< Data byte 1 */
+#define  CAN_RDL1R_DATA2                     ((uint32_t)0x00FF0000)        /*!< Data byte 2 */
+#define  CAN_RDL1R_DATA3                     ((uint32_t)0xFF000000)        /*!< Data byte 3 */
+
+/*******************  Bit definition for CAN_RDH1R register  ******************/
+#define  CAN_RDH1R_DATA4                     ((uint32_t)0x000000FF)        /*!< Data byte 4 */
+#define  CAN_RDH1R_DATA5                     ((uint32_t)0x0000FF00)        /*!< Data byte 5 */
+#define  CAN_RDH1R_DATA6                     ((uint32_t)0x00FF0000)        /*!< Data byte 6 */
+#define  CAN_RDH1R_DATA7                     ((uint32_t)0xFF000000)        /*!< Data byte 7 */
+
+/*!< CAN filter registers */
+/*******************  Bit definition for CAN_FMR register  ********************/
+#define  CAN_FMR_FINIT                       ((uint8_t)0x01)               /*!< Filter Init Mode */
+
+/*******************  Bit definition for CAN_FM1R register  *******************/
+#define  CAN_FM1R_FBM                        ((uint16_t)0x3FFF)            /*!< Filter Mode */
+#define  CAN_FM1R_FBM0                       ((uint16_t)0x0001)            /*!< Filter Init Mode bit 0 */
+#define  CAN_FM1R_FBM1                       ((uint16_t)0x0002)            /*!< Filter Init Mode bit 1 */
+#define  CAN_FM1R_FBM2                       ((uint16_t)0x0004)            /*!< Filter Init Mode bit 2 */
+#define  CAN_FM1R_FBM3                       ((uint16_t)0x0008)            /*!< Filter Init Mode bit 3 */
+#define  CAN_FM1R_FBM4                       ((uint16_t)0x0010)            /*!< Filter Init Mode bit 4 */
+#define  CAN_FM1R_FBM5                       ((uint16_t)0x0020)            /*!< Filter Init Mode bit 5 */
+#define  CAN_FM1R_FBM6                       ((uint16_t)0x0040)            /*!< Filter Init Mode bit 6 */
+#define  CAN_FM1R_FBM7                       ((uint16_t)0x0080)            /*!< Filter Init Mode bit 7 */
+#define  CAN_FM1R_FBM8                       ((uint16_t)0x0100)            /*!< Filter Init Mode bit 8 */
+#define  CAN_FM1R_FBM9                       ((uint16_t)0x0200)            /*!< Filter Init Mode bit 9 */
+#define  CAN_FM1R_FBM10                      ((uint16_t)0x0400)            /*!< Filter Init Mode bit 10 */
+#define  CAN_FM1R_FBM11                      ((uint16_t)0x0800)            /*!< Filter Init Mode bit 11 */
+#define  CAN_FM1R_FBM12                      ((uint16_t)0x1000)            /*!< Filter Init Mode bit 12 */
+#define  CAN_FM1R_FBM13                      ((uint16_t)0x2000)            /*!< Filter Init Mode bit 13 */
+
+/*******************  Bit definition for CAN_FS1R register  *******************/
+#define  CAN_FS1R_FSC                        ((uint16_t)0x3FFF)            /*!< Filter Scale Configuration */
+#define  CAN_FS1R_FSC0                       ((uint16_t)0x0001)            /*!< Filter Scale Configuration bit 0 */
+#define  CAN_FS1R_FSC1                       ((uint16_t)0x0002)            /*!< Filter Scale Configuration bit 1 */
+#define  CAN_FS1R_FSC2                       ((uint16_t)0x0004)            /*!< Filter Scale Configuration bit 2 */
+#define  CAN_FS1R_FSC3                       ((uint16_t)0x0008)            /*!< Filter Scale Configuration bit 3 */
+#define  CAN_FS1R_FSC4                       ((uint16_t)0x0010)            /*!< Filter Scale Configuration bit 4 */
+#define  CAN_FS1R_FSC5                       ((uint16_t)0x0020)            /*!< Filter Scale Configuration bit 5 */
+#define  CAN_FS1R_FSC6                       ((uint16_t)0x0040)            /*!< Filter Scale Configuration bit 6 */
+#define  CAN_FS1R_FSC7                       ((uint16_t)0x0080)            /*!< Filter Scale Configuration bit 7 */
+#define  CAN_FS1R_FSC8                       ((uint16_t)0x0100)            /*!< Filter Scale Configuration bit 8 */
+#define  CAN_FS1R_FSC9                       ((uint16_t)0x0200)            /*!< Filter Scale Configuration bit 9 */
+#define  CAN_FS1R_FSC10                      ((uint16_t)0x0400)            /*!< Filter Scale Configuration bit 10 */
+#define  CAN_FS1R_FSC11                      ((uint16_t)0x0800)            /*!< Filter Scale Configuration bit 11 */
+#define  CAN_FS1R_FSC12                      ((uint16_t)0x1000)            /*!< Filter Scale Configuration bit 12 */
+#define  CAN_FS1R_FSC13                      ((uint16_t)0x2000)            /*!< Filter Scale Configuration bit 13 */
+
+/******************  Bit definition for CAN_FFA1R register  *******************/
+#define  CAN_FFA1R_FFA                       ((uint16_t)0x3FFF)            /*!< Filter FIFO Assignment */
+#define  CAN_FFA1R_FFA0                      ((uint16_t)0x0001)            /*!< Filter FIFO Assignment for Filter 0 */
+#define  CAN_FFA1R_FFA1                      ((uint16_t)0x0002)            /*!< Filter FIFO Assignment for Filter 1 */
+#define  CAN_FFA1R_FFA2                      ((uint16_t)0x0004)            /*!< Filter FIFO Assignment for Filter 2 */
+#define  CAN_FFA1R_FFA3                      ((uint16_t)0x0008)            /*!< Filter FIFO Assignment for Filter 3 */
+#define  CAN_FFA1R_FFA4                      ((uint16_t)0x0010)            /*!< Filter FIFO Assignment for Filter 4 */
+#define  CAN_FFA1R_FFA5                      ((uint16_t)0x0020)            /*!< Filter FIFO Assignment for Filter 5 */
+#define  CAN_FFA1R_FFA6                      ((uint16_t)0x0040)            /*!< Filter FIFO Assignment for Filter 6 */
+#define  CAN_FFA1R_FFA7                      ((uint16_t)0x0080)            /*!< Filter FIFO Assignment for Filter 7 */
+#define  CAN_FFA1R_FFA8                      ((uint16_t)0x0100)            /*!< Filter FIFO Assignment for Filter 8 */
+#define  CAN_FFA1R_FFA9                      ((uint16_t)0x0200)            /*!< Filter FIFO Assignment for Filter 9 */
+#define  CAN_FFA1R_FFA10                     ((uint16_t)0x0400)            /*!< Filter FIFO Assignment for Filter 10 */
+#define  CAN_FFA1R_FFA11                     ((uint16_t)0x0800)            /*!< Filter FIFO Assignment for Filter 11 */
+#define  CAN_FFA1R_FFA12                     ((uint16_t)0x1000)            /*!< Filter FIFO Assignment for Filter 12 */
+#define  CAN_FFA1R_FFA13                     ((uint16_t)0x2000)            /*!< Filter FIFO Assignment for Filter 13 */
+
+/*******************  Bit definition for CAN_FA1R register  *******************/
+#define  CAN_FA1R_FACT                       ((uint16_t)0x3FFF)            /*!< Filter Active */
+#define  CAN_FA1R_FACT0                      ((uint16_t)0x0001)            /*!< Filter 0 Active */
+#define  CAN_FA1R_FACT1                      ((uint16_t)0x0002)            /*!< Filter 1 Active */
+#define  CAN_FA1R_FACT2                      ((uint16_t)0x0004)            /*!< Filter 2 Active */
+#define  CAN_FA1R_FACT3                      ((uint16_t)0x0008)            /*!< Filter 3 Active */
+#define  CAN_FA1R_FACT4                      ((uint16_t)0x0010)            /*!< Filter 4 Active */
+#define  CAN_FA1R_FACT5                      ((uint16_t)0x0020)            /*!< Filter 5 Active */
+#define  CAN_FA1R_FACT6                      ((uint16_t)0x0040)            /*!< Filter 6 Active */
+#define  CAN_FA1R_FACT7                      ((uint16_t)0x0080)            /*!< Filter 7 Active */
+#define  CAN_FA1R_FACT8                      ((uint16_t)0x0100)            /*!< Filter 8 Active */
+#define  CAN_FA1R_FACT9                      ((uint16_t)0x0200)            /*!< Filter 9 Active */
+#define  CAN_FA1R_FACT10                     ((uint16_t)0x0400)            /*!< Filter 10 Active */
+#define  CAN_FA1R_FACT11                     ((uint16_t)0x0800)            /*!< Filter 11 Active */
+#define  CAN_FA1R_FACT12                     ((uint16_t)0x1000)            /*!< Filter 12 Active */
+#define  CAN_FA1R_FACT13                     ((uint16_t)0x2000)            /*!< Filter 13 Active */
+
+/*******************  Bit definition for CAN_F0R1 register  *******************/
+#define  CAN_F0R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F0R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F0R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F0R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F0R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F0R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F0R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F0R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F0R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F0R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F0R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F0R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F0R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F0R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F0R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F0R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F0R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F0R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F0R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F0R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F0R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F0R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F0R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F0R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F0R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F0R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F0R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F0R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F0R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F0R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F0R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F0R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F1R1 register  *******************/
+#define  CAN_F1R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F1R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F1R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F1R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F1R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F1R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F1R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F1R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F1R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F1R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F1R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F1R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F1R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F1R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F1R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F1R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F1R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F1R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F1R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F1R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F1R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F1R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F1R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F1R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F1R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F1R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F1R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F1R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F1R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F1R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F1R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F1R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F2R1 register  *******************/
+#define  CAN_F2R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F2R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F2R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F2R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F2R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F2R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F2R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F2R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F2R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F2R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F2R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F2R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F2R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F2R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F2R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F2R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F2R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F2R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F2R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F2R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F2R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F2R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F2R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F2R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F2R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F2R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F2R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F2R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F2R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F2R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F2R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F2R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F3R1 register  *******************/
+#define  CAN_F3R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F3R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F3R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F3R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F3R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F3R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F3R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F3R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F3R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F3R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F3R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F3R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F3R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F3R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F3R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F3R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F3R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F3R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F3R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F3R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F3R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F3R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F3R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F3R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F3R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F3R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F3R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F3R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F3R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F3R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F3R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F3R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F4R1 register  *******************/
+#define  CAN_F4R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F4R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F4R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F4R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F4R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F4R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F4R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F4R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F4R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F4R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F4R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F4R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F4R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F4R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F4R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F4R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F4R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F4R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F4R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F4R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F4R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F4R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F4R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F4R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F4R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F4R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F4R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F4R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F4R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F4R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F4R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F4R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F5R1 register  *******************/
+#define  CAN_F5R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F5R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F5R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F5R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F5R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F5R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F5R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F5R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F5R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F5R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F5R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F5R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F5R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F5R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F5R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F5R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F5R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F5R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F5R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F5R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F5R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F5R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F5R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F5R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F5R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F5R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F5R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F5R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F5R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F5R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F5R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F5R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F6R1 register  *******************/
+#define  CAN_F6R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F6R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F6R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F6R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F6R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F6R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F6R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F6R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F6R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F6R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F6R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F6R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F6R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F6R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F6R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F6R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F6R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F6R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F6R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F6R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F6R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F6R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F6R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F6R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F6R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F6R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F6R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F6R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F6R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F6R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F6R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F6R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F7R1 register  *******************/
+#define  CAN_F7R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F7R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F7R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F7R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F7R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F7R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F7R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F7R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F7R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F7R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F7R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F7R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F7R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F7R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F7R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F7R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F7R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F7R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F7R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F7R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F7R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F7R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F7R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F7R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F7R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F7R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F7R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F7R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F7R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F7R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F7R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F7R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F8R1 register  *******************/
+#define  CAN_F8R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F8R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F8R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F8R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F8R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F8R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F8R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F8R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F8R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F8R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F8R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F8R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F8R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F8R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F8R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F8R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F8R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F8R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F8R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F8R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F8R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F8R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F8R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F8R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F8R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F8R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F8R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F8R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F8R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F8R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F8R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F8R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F9R1 register  *******************/
+#define  CAN_F9R1_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F9R1_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F9R1_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F9R1_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F9R1_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F9R1_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F9R1_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F9R1_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F9R1_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F9R1_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F9R1_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F9R1_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F9R1_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F9R1_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F9R1_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F9R1_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F9R1_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F9R1_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F9R1_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F9R1_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F9R1_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F9R1_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F9R1_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F9R1_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F9R1_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F9R1_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F9R1_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F9R1_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F9R1_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F9R1_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F9R1_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F9R1_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F10R1 register  ******************/
+#define  CAN_F10R1_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F10R1_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F10R1_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F10R1_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F10R1_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F10R1_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F10R1_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F10R1_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F10R1_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F10R1_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F10R1_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F10R1_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F10R1_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F10R1_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F10R1_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F10R1_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F10R1_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F10R1_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F10R1_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F10R1_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F10R1_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F10R1_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F10R1_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F10R1_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F10R1_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F10R1_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F10R1_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F10R1_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F10R1_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F10R1_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F10R1_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F10R1_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F11R1 register  ******************/
+#define  CAN_F11R1_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F11R1_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F11R1_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F11R1_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F11R1_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F11R1_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F11R1_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F11R1_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F11R1_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F11R1_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F11R1_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F11R1_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F11R1_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F11R1_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F11R1_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F11R1_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F11R1_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F11R1_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F11R1_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F11R1_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F11R1_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F11R1_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F11R1_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F11R1_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F11R1_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F11R1_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F11R1_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F11R1_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F11R1_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F11R1_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F11R1_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F11R1_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F12R1 register  ******************/
+#define  CAN_F12R1_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F12R1_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F12R1_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F12R1_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F12R1_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F12R1_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F12R1_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F12R1_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F12R1_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F12R1_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F12R1_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F12R1_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F12R1_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F12R1_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F12R1_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F12R1_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F12R1_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F12R1_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F12R1_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F12R1_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F12R1_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F12R1_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F12R1_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F12R1_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F12R1_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F12R1_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F12R1_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F12R1_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F12R1_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F12R1_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F12R1_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F12R1_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F13R1 register  ******************/
+#define  CAN_F13R1_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F13R1_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F13R1_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F13R1_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F13R1_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F13R1_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F13R1_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F13R1_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F13R1_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F13R1_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F13R1_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F13R1_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F13R1_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F13R1_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F13R1_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F13R1_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F13R1_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F13R1_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F13R1_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F13R1_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F13R1_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F13R1_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F13R1_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F13R1_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F13R1_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F13R1_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F13R1_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F13R1_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F13R1_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F13R1_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F13R1_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F13R1_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F0R2 register  *******************/
+#define  CAN_F0R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F0R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F0R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F0R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F0R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F0R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F0R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F0R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F0R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F0R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F0R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F0R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F0R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F0R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F0R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F0R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F0R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F0R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F0R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F0R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F0R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F0R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F0R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F0R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F0R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F0R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F0R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F0R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F0R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F0R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F0R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F0R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F1R2 register  *******************/
+#define  CAN_F1R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F1R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F1R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F1R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F1R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F1R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F1R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F1R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F1R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F1R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F1R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F1R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F1R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F1R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F1R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F1R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F1R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F1R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F1R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F1R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F1R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F1R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F1R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F1R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F1R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F1R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F1R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F1R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F1R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F1R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F1R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F1R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F2R2 register  *******************/
+#define  CAN_F2R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F2R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F2R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F2R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F2R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F2R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F2R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F2R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F2R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F2R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F2R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F2R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F2R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F2R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F2R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F2R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F2R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F2R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F2R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F2R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F2R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F2R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F2R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F2R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F2R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F2R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F2R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F2R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F2R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F2R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F2R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F2R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F3R2 register  *******************/
+#define  CAN_F3R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F3R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F3R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F3R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F3R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F3R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F3R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F3R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F3R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F3R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F3R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F3R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F3R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F3R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F3R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F3R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F3R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F3R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F3R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F3R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F3R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F3R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F3R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F3R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F3R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F3R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F3R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F3R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F3R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F3R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F3R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F3R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F4R2 register  *******************/
+#define  CAN_F4R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F4R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F4R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F4R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F4R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F4R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F4R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F4R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F4R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F4R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F4R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F4R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F4R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F4R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F4R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F4R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F4R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F4R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F4R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F4R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F4R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F4R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F4R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F4R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F4R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F4R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F4R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F4R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F4R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F4R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F4R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F4R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F5R2 register  *******************/
+#define  CAN_F5R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F5R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F5R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F5R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F5R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F5R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F5R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F5R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F5R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F5R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F5R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F5R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F5R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F5R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F5R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F5R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F5R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F5R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F5R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F5R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F5R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F5R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F5R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F5R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F5R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F5R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F5R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F5R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F5R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F5R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F5R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F5R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F6R2 register  *******************/
+#define  CAN_F6R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F6R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F6R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F6R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F6R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F6R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F6R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F6R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F6R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F6R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F6R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F6R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F6R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F6R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F6R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F6R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F6R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F6R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F6R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F6R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F6R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F6R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F6R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F6R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F6R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F6R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F6R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F6R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F6R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F6R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F6R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F6R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F7R2 register  *******************/
+#define  CAN_F7R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F7R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F7R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F7R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F7R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F7R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F7R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F7R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F7R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F7R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F7R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F7R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F7R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F7R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F7R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F7R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F7R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F7R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F7R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F7R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F7R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F7R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F7R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F7R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F7R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F7R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F7R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F7R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F7R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F7R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F7R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F7R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F8R2 register  *******************/
+#define  CAN_F8R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F8R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F8R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F8R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F8R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F8R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F8R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F8R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F8R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F8R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F8R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F8R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F8R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F8R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F8R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F8R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F8R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F8R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F8R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F8R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F8R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F8R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F8R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F8R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F8R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F8R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F8R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F8R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F8R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F8R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F8R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F8R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F9R2 register  *******************/
+#define  CAN_F9R2_FB0                        ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F9R2_FB1                        ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F9R2_FB2                        ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F9R2_FB3                        ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F9R2_FB4                        ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F9R2_FB5                        ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F9R2_FB6                        ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F9R2_FB7                        ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F9R2_FB8                        ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F9R2_FB9                        ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F9R2_FB10                       ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F9R2_FB11                       ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F9R2_FB12                       ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F9R2_FB13                       ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F9R2_FB14                       ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F9R2_FB15                       ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F9R2_FB16                       ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F9R2_FB17                       ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F9R2_FB18                       ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F9R2_FB19                       ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F9R2_FB20                       ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F9R2_FB21                       ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F9R2_FB22                       ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F9R2_FB23                       ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F9R2_FB24                       ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F9R2_FB25                       ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F9R2_FB26                       ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F9R2_FB27                       ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F9R2_FB28                       ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F9R2_FB29                       ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F9R2_FB30                       ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F9R2_FB31                       ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F10R2 register  ******************/
+#define  CAN_F10R2_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F10R2_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F10R2_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F10R2_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F10R2_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F10R2_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F10R2_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F10R2_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F10R2_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F10R2_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F10R2_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F10R2_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F10R2_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F10R2_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F10R2_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F10R2_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F10R2_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F10R2_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F10R2_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F10R2_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F10R2_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F10R2_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F10R2_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F10R2_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F10R2_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F10R2_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F10R2_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F10R2_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F10R2_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F10R2_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F10R2_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F10R2_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F11R2 register  ******************/
+#define  CAN_F11R2_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F11R2_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F11R2_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F11R2_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F11R2_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F11R2_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F11R2_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F11R2_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F11R2_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F11R2_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F11R2_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F11R2_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F11R2_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F11R2_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F11R2_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F11R2_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F11R2_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F11R2_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F11R2_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F11R2_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F11R2_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F11R2_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F11R2_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F11R2_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F11R2_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F11R2_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F11R2_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F11R2_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F11R2_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F11R2_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F11R2_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F11R2_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F12R2 register  ******************/
+#define  CAN_F12R2_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F12R2_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F12R2_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F12R2_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F12R2_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F12R2_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F12R2_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F12R2_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F12R2_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F12R2_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F12R2_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F12R2_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F12R2_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F12R2_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F12R2_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F12R2_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F12R2_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F12R2_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F12R2_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F12R2_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F12R2_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F12R2_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F12R2_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F12R2_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F12R2_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F12R2_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F12R2_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F12R2_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F12R2_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F12R2_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F12R2_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F12R2_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/*******************  Bit definition for CAN_F13R2 register  ******************/
+#define  CAN_F13R2_FB0                       ((uint32_t)0x00000001)        /*!< Filter bit 0 */
+#define  CAN_F13R2_FB1                       ((uint32_t)0x00000002)        /*!< Filter bit 1 */
+#define  CAN_F13R2_FB2                       ((uint32_t)0x00000004)        /*!< Filter bit 2 */
+#define  CAN_F13R2_FB3                       ((uint32_t)0x00000008)        /*!< Filter bit 3 */
+#define  CAN_F13R2_FB4                       ((uint32_t)0x00000010)        /*!< Filter bit 4 */
+#define  CAN_F13R2_FB5                       ((uint32_t)0x00000020)        /*!< Filter bit 5 */
+#define  CAN_F13R2_FB6                       ((uint32_t)0x00000040)        /*!< Filter bit 6 */
+#define  CAN_F13R2_FB7                       ((uint32_t)0x00000080)        /*!< Filter bit 7 */
+#define  CAN_F13R2_FB8                       ((uint32_t)0x00000100)        /*!< Filter bit 8 */
+#define  CAN_F13R2_FB9                       ((uint32_t)0x00000200)        /*!< Filter bit 9 */
+#define  CAN_F13R2_FB10                      ((uint32_t)0x00000400)        /*!< Filter bit 10 */
+#define  CAN_F13R2_FB11                      ((uint32_t)0x00000800)        /*!< Filter bit 11 */
+#define  CAN_F13R2_FB12                      ((uint32_t)0x00001000)        /*!< Filter bit 12 */
+#define  CAN_F13R2_FB13                      ((uint32_t)0x00002000)        /*!< Filter bit 13 */
+#define  CAN_F13R2_FB14                      ((uint32_t)0x00004000)        /*!< Filter bit 14 */
+#define  CAN_F13R2_FB15                      ((uint32_t)0x00008000)        /*!< Filter bit 15 */
+#define  CAN_F13R2_FB16                      ((uint32_t)0x00010000)        /*!< Filter bit 16 */
+#define  CAN_F13R2_FB17                      ((uint32_t)0x00020000)        /*!< Filter bit 17 */
+#define  CAN_F13R2_FB18                      ((uint32_t)0x00040000)        /*!< Filter bit 18 */
+#define  CAN_F13R2_FB19                      ((uint32_t)0x00080000)        /*!< Filter bit 19 */
+#define  CAN_F13R2_FB20                      ((uint32_t)0x00100000)        /*!< Filter bit 20 */
+#define  CAN_F13R2_FB21                      ((uint32_t)0x00200000)        /*!< Filter bit 21 */
+#define  CAN_F13R2_FB22                      ((uint32_t)0x00400000)        /*!< Filter bit 22 */
+#define  CAN_F13R2_FB23                      ((uint32_t)0x00800000)        /*!< Filter bit 23 */
+#define  CAN_F13R2_FB24                      ((uint32_t)0x01000000)        /*!< Filter bit 24 */
+#define  CAN_F13R2_FB25                      ((uint32_t)0x02000000)        /*!< Filter bit 25 */
+#define  CAN_F13R2_FB26                      ((uint32_t)0x04000000)        /*!< Filter bit 26 */
+#define  CAN_F13R2_FB27                      ((uint32_t)0x08000000)        /*!< Filter bit 27 */
+#define  CAN_F13R2_FB28                      ((uint32_t)0x10000000)        /*!< Filter bit 28 */
+#define  CAN_F13R2_FB29                      ((uint32_t)0x20000000)        /*!< Filter bit 29 */
+#define  CAN_F13R2_FB30                      ((uint32_t)0x40000000)        /*!< Filter bit 30 */
+#define  CAN_F13R2_FB31                      ((uint32_t)0x80000000)        /*!< Filter bit 31 */
+
+/******************************************************************************/
+/*                                                                            */
+/*                        Serial Peripheral Interface                         */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for SPI_CR1 register  ********************/
+#define  SPI_CR1_CPHA                        ((uint16_t)0x0001)            /*!< Clock Phase */
+#define  SPI_CR1_CPOL                        ((uint16_t)0x0002)            /*!< Clock Polarity */
+#define  SPI_CR1_MSTR                        ((uint16_t)0x0004)            /*!< Master Selection */
+
+#define  SPI_CR1_BR                          ((uint16_t)0x0038)            /*!< BR[2:0] bits (Baud Rate Control) */
+#define  SPI_CR1_BR_0                        ((uint16_t)0x0008)            /*!< Bit 0 */
+#define  SPI_CR1_BR_1                        ((uint16_t)0x0010)            /*!< Bit 1 */
+#define  SPI_CR1_BR_2                        ((uint16_t)0x0020)            /*!< Bit 2 */
+
+#define  SPI_CR1_SPE                         ((uint16_t)0x0040)            /*!< SPI Enable */
+#define  SPI_CR1_LSBFIRST                    ((uint16_t)0x0080)            /*!< Frame Format */
+#define  SPI_CR1_SSI                         ((uint16_t)0x0100)            /*!< Internal slave select */
+#define  SPI_CR1_SSM                         ((uint16_t)0x0200)            /*!< Software slave management */
+#define  SPI_CR1_RXONLY                      ((uint16_t)0x0400)            /*!< Receive only */
+#define  SPI_CR1_DFF                         ((uint16_t)0x0800)            /*!< Data Frame Format */
+#define  SPI_CR1_CRCNEXT                     ((uint16_t)0x1000)            /*!< Transmit CRC next */
+#define  SPI_CR1_CRCEN                       ((uint16_t)0x2000)            /*!< Hardware CRC calculation enable */
+#define  SPI_CR1_BIDIOE                      ((uint16_t)0x4000)            /*!< Output enable in bidirectional mode */
+#define  SPI_CR1_BIDIMODE                    ((uint16_t)0x8000)            /*!< Bidirectional data mode enable */
+
+/*******************  Bit definition for SPI_CR2 register  ********************/
+#define  SPI_CR2_RXDMAEN                     ((uint8_t)0x01)               /*!< Rx Buffer DMA Enable */
+#define  SPI_CR2_TXDMAEN                     ((uint8_t)0x02)               /*!< Tx Buffer DMA Enable */
+#define  SPI_CR2_SSOE                        ((uint8_t)0x04)               /*!< SS Output Enable */
+#define  SPI_CR2_ERRIE                       ((uint8_t)0x20)               /*!< Error Interrupt Enable */
+#define  SPI_CR2_RXNEIE                      ((uint8_t)0x40)               /*!< RX buffer Not Empty Interrupt Enable */
+#define  SPI_CR2_TXEIE                       ((uint8_t)0x80)               /*!< Tx buffer Empty Interrupt Enable */
+
+/********************  Bit definition for SPI_SR register  ********************/
+#define  SPI_SR_RXNE                         ((uint8_t)0x01)               /*!< Receive buffer Not Empty */
+#define  SPI_SR_TXE                          ((uint8_t)0x02)               /*!< Transmit buffer Empty */
+#define  SPI_SR_CHSIDE                       ((uint8_t)0x04)               /*!< Channel side */
+#define  SPI_SR_UDR                          ((uint8_t)0x08)               /*!< Underrun flag */
+#define  SPI_SR_CRCERR                       ((uint8_t)0x10)               /*!< CRC Error flag */
+#define  SPI_SR_MODF                         ((uint8_t)0x20)               /*!< Mode fault */
+#define  SPI_SR_OVR                          ((uint8_t)0x40)               /*!< Overrun flag */
+#define  SPI_SR_BSY                          ((uint8_t)0x80)               /*!< Busy flag */
+
+/********************  Bit definition for SPI_DR register  ********************/
+#define  SPI_DR_DR                           ((uint16_t)0xFFFF)            /*!< Data Register */
+
+/*******************  Bit definition for SPI_CRCPR register  ******************/
+#define  SPI_CRCPR_CRCPOLY                   ((uint16_t)0xFFFF)            /*!< CRC polynomial register */
+
+/******************  Bit definition for SPI_RXCRCR register  ******************/
+#define  SPI_RXCRCR_RXCRC                    ((uint16_t)0xFFFF)            /*!< Rx CRC Register */
+
+/******************  Bit definition for SPI_TXCRCR register  ******************/
+#define  SPI_TXCRCR_TXCRC                    ((uint16_t)0xFFFF)            /*!< Tx CRC Register */
+
+/******************  Bit definition for SPI_I2SCFGR register  *****************/
+#define  SPI_I2SCFGR_CHLEN                   ((uint16_t)0x0001)            /*!< Channel length (number of bits per audio channel) */
+
+#define  SPI_I2SCFGR_DATLEN                  ((uint16_t)0x0006)            /*!< DATLEN[1:0] bits (Data length to be transferred) */
+#define  SPI_I2SCFGR_DATLEN_0                ((uint16_t)0x0002)            /*!< Bit 0 */
+#define  SPI_I2SCFGR_DATLEN_1                ((uint16_t)0x0004)            /*!< Bit 1 */
+
+#define  SPI_I2SCFGR_CKPOL                   ((uint16_t)0x0008)            /*!< steady state clock polarity */
+
+#define  SPI_I2SCFGR_I2SSTD                  ((uint16_t)0x0030)            /*!< I2SSTD[1:0] bits (I2S standard selection) */
+#define  SPI_I2SCFGR_I2SSTD_0                ((uint16_t)0x0010)            /*!< Bit 0 */
+#define  SPI_I2SCFGR_I2SSTD_1                ((uint16_t)0x0020)            /*!< Bit 1 */
+
+#define  SPI_I2SCFGR_PCMSYNC                 ((uint16_t)0x0080)            /*!< PCM frame synchronization */
+
+#define  SPI_I2SCFGR_I2SCFG                  ((uint16_t)0x0300)            /*!< I2SCFG[1:0] bits (I2S configuration mode) */
+#define  SPI_I2SCFGR_I2SCFG_0                ((uint16_t)0x0100)            /*!< Bit 0 */
+#define  SPI_I2SCFGR_I2SCFG_1                ((uint16_t)0x0200)            /*!< Bit 1 */
+
+#define  SPI_I2SCFGR_I2SE                    ((uint16_t)0x0400)            /*!< I2S Enable */
+#define  SPI_I2SCFGR_I2SMOD                  ((uint16_t)0x0800)            /*!< I2S mode selection */
+
+/******************  Bit definition for SPI_I2SPR register  *******************/
+#define  SPI_I2SPR_I2SDIV                    ((uint16_t)0x00FF)            /*!< I2S Linear prescaler */
+#define  SPI_I2SPR_ODD                       ((uint16_t)0x0100)            /*!< Odd factor for the prescaler */
+#define  SPI_I2SPR_MCKOE                     ((uint16_t)0x0200)            /*!< Master Clock Output Enable */
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Inter-integrated Circuit Interface                    */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for I2C_CR1 register  ********************/
+#define  I2C_CR1_PE                          ((uint16_t)0x0001)            /*!< Peripheral Enable */
+#define  I2C_CR1_SMBUS                       ((uint16_t)0x0002)            /*!< SMBus Mode */
+#define  I2C_CR1_SMBTYPE                     ((uint16_t)0x0008)            /*!< SMBus Type */
+#define  I2C_CR1_ENARP                       ((uint16_t)0x0010)            /*!< ARP Enable */
+#define  I2C_CR1_ENPEC                       ((uint16_t)0x0020)            /*!< PEC Enable */
+#define  I2C_CR1_ENGC                        ((uint16_t)0x0040)            /*!< General Call Enable */
+#define  I2C_CR1_NOSTRETCH                   ((uint16_t)0x0080)            /*!< Clock Stretching Disable (Slave mode) */
+#define  I2C_CR1_START                       ((uint16_t)0x0100)            /*!< Start Generation */
+#define  I2C_CR1_STOP                        ((uint16_t)0x0200)            /*!< Stop Generation */
+#define  I2C_CR1_ACK                         ((uint16_t)0x0400)            /*!< Acknowledge Enable */
+#define  I2C_CR1_POS                         ((uint16_t)0x0800)            /*!< Acknowledge/PEC Position (for data reception) */
+#define  I2C_CR1_PEC                         ((uint16_t)0x1000)            /*!< Packet Error Checking */
+#define  I2C_CR1_ALERT                       ((uint16_t)0x2000)            /*!< SMBus Alert */
+#define  I2C_CR1_SWRST                       ((uint16_t)0x8000)            /*!< Software Reset */
+
+/*******************  Bit definition for I2C_CR2 register  ********************/
+#define  I2C_CR2_FREQ                        ((uint16_t)0x003F)            /*!< FREQ[5:0] bits (Peripheral Clock Frequency) */
+#define  I2C_CR2_FREQ_0                      ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  I2C_CR2_FREQ_1                      ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  I2C_CR2_FREQ_2                      ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  I2C_CR2_FREQ_3                      ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  I2C_CR2_FREQ_4                      ((uint16_t)0x0010)            /*!< Bit 4 */
+#define  I2C_CR2_FREQ_5                      ((uint16_t)0x0020)            /*!< Bit 5 */
+
+#define  I2C_CR2_ITERREN                     ((uint16_t)0x0100)            /*!< Error Interrupt Enable */
+#define  I2C_CR2_ITEVTEN                     ((uint16_t)0x0200)            /*!< Event Interrupt Enable */
+#define  I2C_CR2_ITBUFEN                     ((uint16_t)0x0400)            /*!< Buffer Interrupt Enable */
+#define  I2C_CR2_DMAEN                       ((uint16_t)0x0800)            /*!< DMA Requests Enable */
+#define  I2C_CR2_LAST                        ((uint16_t)0x1000)            /*!< DMA Last Transfer */
+
+/*******************  Bit definition for I2C_OAR1 register  *******************/
+#define  I2C_OAR1_ADD1_7                     ((uint16_t)0x00FE)            /*!< Interface Address */
+#define  I2C_OAR1_ADD8_9                     ((uint16_t)0x0300)            /*!< Interface Address */
+
+#define  I2C_OAR1_ADD0                       ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  I2C_OAR1_ADD1                       ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  I2C_OAR1_ADD2                       ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  I2C_OAR1_ADD3                       ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  I2C_OAR1_ADD4                       ((uint16_t)0x0010)            /*!< Bit 4 */
+#define  I2C_OAR1_ADD5                       ((uint16_t)0x0020)            /*!< Bit 5 */
+#define  I2C_OAR1_ADD6                       ((uint16_t)0x0040)            /*!< Bit 6 */
+#define  I2C_OAR1_ADD7                       ((uint16_t)0x0080)            /*!< Bit 7 */
+#define  I2C_OAR1_ADD8                       ((uint16_t)0x0100)            /*!< Bit 8 */
+#define  I2C_OAR1_ADD9                       ((uint16_t)0x0200)            /*!< Bit 9 */
+
+#define  I2C_OAR1_ADDMODE                    ((uint16_t)0x8000)            /*!< Addressing Mode (Slave mode) */
+
+/*******************  Bit definition for I2C_OAR2 register  *******************/
+#define  I2C_OAR2_ENDUAL                     ((uint8_t)0x01)               /*!< Dual addressing mode enable */
+#define  I2C_OAR2_ADD2                       ((uint8_t)0xFE)               /*!< Interface address */
+
+/********************  Bit definition for I2C_DR register  ********************/
+#define  I2C_DR_DR                           ((uint8_t)0xFF)               /*!< 8-bit Data Register */
+
+/*******************  Bit definition for I2C_SR1 register  ********************/
+#define  I2C_SR1_SB                          ((uint16_t)0x0001)            /*!< Start Bit (Master mode) */
+#define  I2C_SR1_ADDR                        ((uint16_t)0x0002)            /*!< Address sent (master mode)/matched (slave mode) */
+#define  I2C_SR1_BTF                         ((uint16_t)0x0004)            /*!< Byte Transfer Finished */
+#define  I2C_SR1_ADD10                       ((uint16_t)0x0008)            /*!< 10-bit header sent (Master mode) */
+#define  I2C_SR1_STOPF                       ((uint16_t)0x0010)            /*!< Stop detection (Slave mode) */
+#define  I2C_SR1_RXNE                        ((uint16_t)0x0040)            /*!< Data Register not Empty (receivers) */
+#define  I2C_SR1_TXE                         ((uint16_t)0x0080)            /*!< Data Register Empty (transmitters) */
+#define  I2C_SR1_BERR                        ((uint16_t)0x0100)            /*!< Bus Error */
+#define  I2C_SR1_ARLO                        ((uint16_t)0x0200)            /*!< Arbitration Lost (master mode) */
+#define  I2C_SR1_AF                          ((uint16_t)0x0400)            /*!< Acknowledge Failure */
+#define  I2C_SR1_OVR                         ((uint16_t)0x0800)            /*!< Overrun/Underrun */
+#define  I2C_SR1_PECERR                      ((uint16_t)0x1000)            /*!< PEC Error in reception */
+#define  I2C_SR1_TIMEOUT                     ((uint16_t)0x4000)            /*!< Timeout or Tlow Error */
+#define  I2C_SR1_SMBALERT                    ((uint16_t)0x8000)            /*!< SMBus Alert */
+
+/*******************  Bit definition for I2C_SR2 register  ********************/
+#define  I2C_SR2_MSL                         ((uint16_t)0x0001)            /*!< Master/Slave */
+#define  I2C_SR2_BUSY                        ((uint16_t)0x0002)            /*!< Bus Busy */
+#define  I2C_SR2_TRA                         ((uint16_t)0x0004)            /*!< Transmitter/Receiver */
+#define  I2C_SR2_GENCALL                     ((uint16_t)0x0010)            /*!< General Call Address (Slave mode) */
+#define  I2C_SR2_SMBDEFAULT                  ((uint16_t)0x0020)            /*!< SMBus Device Default Address (Slave mode) */
+#define  I2C_SR2_SMBHOST                     ((uint16_t)0x0040)            /*!< SMBus Host Header (Slave mode) */
+#define  I2C_SR2_DUALF                       ((uint16_t)0x0080)            /*!< Dual Flag (Slave mode) */
+#define  I2C_SR2_PEC                         ((uint16_t)0xFF00)            /*!< Packet Error Checking Register */
+
+/*******************  Bit definition for I2C_CCR register  ********************/
+#define  I2C_CCR_CCR                         ((uint16_t)0x0FFF)            /*!< Clock Control Register in Fast/Standard mode (Master mode) */
+#define  I2C_CCR_DUTY                        ((uint16_t)0x4000)            /*!< Fast Mode Duty Cycle */
+#define  I2C_CCR_FS                          ((uint16_t)0x8000)            /*!< I2C Master Mode Selection */
+
+/******************  Bit definition for I2C_TRISE register  *******************/
+#define  I2C_TRISE_TRISE                     ((uint8_t)0x3F)               /*!< Maximum Rise Time in Fast/Standard mode (Master mode) */
+
+/******************************************************************************/
+/*                                                                            */
+/*         Universal Synchronous Asynchronous Receiver Transmitter            */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for USART_SR register  *******************/
+#define  USART_SR_PE                         ((uint16_t)0x0001)            /*!< Parity Error */
+#define  USART_SR_FE                         ((uint16_t)0x0002)            /*!< Framing Error */
+#define  USART_SR_NE                         ((uint16_t)0x0004)            /*!< Noise Error Flag */
+#define  USART_SR_ORE                        ((uint16_t)0x0008)            /*!< OverRun Error */
+#define  USART_SR_IDLE                       ((uint16_t)0x0010)            /*!< IDLE line detected */
+#define  USART_SR_RXNE                       ((uint16_t)0x0020)            /*!< Read Data Register Not Empty */
+#define  USART_SR_TC                         ((uint16_t)0x0040)            /*!< Transmission Complete */
+#define  USART_SR_TXE                        ((uint16_t)0x0080)            /*!< Transmit Data Register Empty */
+#define  USART_SR_LBD                        ((uint16_t)0x0100)            /*!< LIN Break Detection Flag */
+#define  USART_SR_CTS                        ((uint16_t)0x0200)            /*!< CTS Flag */
+
+/*******************  Bit definition for USART_DR register  *******************/
+#define  USART_DR_DR                         ((uint16_t)0x01FF)            /*!< Data value */
+
+/******************  Bit definition for USART_BRR register  *******************/
+#define  USART_BRR_DIV_Fraction              ((uint16_t)0x000F)            /*!< Fraction of USARTDIV */
+#define  USART_BRR_DIV_Mantissa              ((uint16_t)0xFFF0)            /*!< Mantissa of USARTDIV */
+
+/******************  Bit definition for USART_CR1 register  *******************/
+#define  USART_CR1_SBK                       ((uint16_t)0x0001)            /*!< Send Break */
+#define  USART_CR1_RWU                       ((uint16_t)0x0002)            /*!< Receiver wakeup */
+#define  USART_CR1_RE                        ((uint16_t)0x0004)            /*!< Receiver Enable */
+#define  USART_CR1_TE                        ((uint16_t)0x0008)            /*!< Transmitter Enable */
+#define  USART_CR1_IDLEIE                    ((uint16_t)0x0010)            /*!< IDLE Interrupt Enable */
+#define  USART_CR1_RXNEIE                    ((uint16_t)0x0020)            /*!< RXNE Interrupt Enable */
+#define  USART_CR1_TCIE                      ((uint16_t)0x0040)            /*!< Transmission Complete Interrupt Enable */
+#define  USART_CR1_TXEIE                     ((uint16_t)0x0080)            /*!< PE Interrupt Enable */
+#define  USART_CR1_PEIE                      ((uint16_t)0x0100)            /*!< PE Interrupt Enable */
+#define  USART_CR1_PS                        ((uint16_t)0x0200)            /*!< Parity Selection */
+#define  USART_CR1_PCE                       ((uint16_t)0x0400)            /*!< Parity Control Enable */
+#define  USART_CR1_WAKE                      ((uint16_t)0x0800)            /*!< Wakeup method */
+#define  USART_CR1_M                         ((uint16_t)0x1000)            /*!< Word length */
+#define  USART_CR1_UE                        ((uint16_t)0x2000)            /*!< USART Enable */
+#define  USART_CR1_OVER8                     ((uint16_t)0x8000)            /*!< USART Oversmapling 8-bits */
+
+/******************  Bit definition for USART_CR2 register  *******************/
+#define  USART_CR2_ADD                       ((uint16_t)0x000F)            /*!< Address of the USART node */
+#define  USART_CR2_LBDL                      ((uint16_t)0x0020)            /*!< LIN Break Detection Length */
+#define  USART_CR2_LBDIE                     ((uint16_t)0x0040)            /*!< LIN Break Detection Interrupt Enable */
+#define  USART_CR2_LBCL                      ((uint16_t)0x0100)            /*!< Last Bit Clock pulse */
+#define  USART_CR2_CPHA                      ((uint16_t)0x0200)            /*!< Clock Phase */
+#define  USART_CR2_CPOL                      ((uint16_t)0x0400)            /*!< Clock Polarity */
+#define  USART_CR2_CLKEN                     ((uint16_t)0x0800)            /*!< Clock Enable */
+
+#define  USART_CR2_STOP                      ((uint16_t)0x3000)            /*!< STOP[1:0] bits (STOP bits) */
+#define  USART_CR2_STOP_0                    ((uint16_t)0x1000)            /*!< Bit 0 */
+#define  USART_CR2_STOP_1                    ((uint16_t)0x2000)            /*!< Bit 1 */
+
+#define  USART_CR2_LINEN                     ((uint16_t)0x4000)            /*!< LIN mode enable */
+
+/******************  Bit definition for USART_CR3 register  *******************/
+#define  USART_CR3_EIE                       ((uint16_t)0x0001)            /*!< Error Interrupt Enable */
+#define  USART_CR3_IREN                      ((uint16_t)0x0002)            /*!< IrDA mode Enable */
+#define  USART_CR3_IRLP                      ((uint16_t)0x0004)            /*!< IrDA Low-Power */
+#define  USART_CR3_HDSEL                     ((uint16_t)0x0008)            /*!< Half-Duplex Selection */
+#define  USART_CR3_NACK                      ((uint16_t)0x0010)            /*!< Smartcard NACK enable */
+#define  USART_CR3_SCEN                      ((uint16_t)0x0020)            /*!< Smartcard mode enable */
+#define  USART_CR3_DMAR                      ((uint16_t)0x0040)            /*!< DMA Enable Receiver */
+#define  USART_CR3_DMAT                      ((uint16_t)0x0080)            /*!< DMA Enable Transmitter */
+#define  USART_CR3_RTSE                      ((uint16_t)0x0100)            /*!< RTS Enable */
+#define  USART_CR3_CTSE                      ((uint16_t)0x0200)            /*!< CTS Enable */
+#define  USART_CR3_CTSIE                     ((uint16_t)0x0400)            /*!< CTS Interrupt Enable */
+#define  USART_CR3_ONEBIT                    ((uint16_t)0x0800)            /*!< One Bit method */
+
+/******************  Bit definition for USART_GTPR register  ******************/
+#define  USART_GTPR_PSC                      ((uint16_t)0x00FF)            /*!< PSC[7:0] bits (Prescaler value) */
+#define  USART_GTPR_PSC_0                    ((uint16_t)0x0001)            /*!< Bit 0 */
+#define  USART_GTPR_PSC_1                    ((uint16_t)0x0002)            /*!< Bit 1 */
+#define  USART_GTPR_PSC_2                    ((uint16_t)0x0004)            /*!< Bit 2 */
+#define  USART_GTPR_PSC_3                    ((uint16_t)0x0008)            /*!< Bit 3 */
+#define  USART_GTPR_PSC_4                    ((uint16_t)0x0010)            /*!< Bit 4 */
+#define  USART_GTPR_PSC_5                    ((uint16_t)0x0020)            /*!< Bit 5 */
+#define  USART_GTPR_PSC_6                    ((uint16_t)0x0040)            /*!< Bit 6 */
+#define  USART_GTPR_PSC_7                    ((uint16_t)0x0080)            /*!< Bit 7 */
+
+#define  USART_GTPR_GT                       ((uint16_t)0xFF00)            /*!< Guard time value */
+
+/******************************************************************************/
+/*                                                                            */
+/*                                 Debug MCU                                  */
+/*                                                                            */
+/******************************************************************************/
+
+/****************  Bit definition for DBGMCU_IDCODE register  *****************/
+#define  DBGMCU_IDCODE_DEV_ID                ((uint32_t)0x00000FFF)        /*!< Device Identifier */
+
+#define  DBGMCU_IDCODE_REV_ID                ((uint32_t)0xFFFF0000)        /*!< REV_ID[15:0] bits (Revision Identifier) */
+#define  DBGMCU_IDCODE_REV_ID_0              ((uint32_t)0x00010000)        /*!< Bit 0 */
+#define  DBGMCU_IDCODE_REV_ID_1              ((uint32_t)0x00020000)        /*!< Bit 1 */
+#define  DBGMCU_IDCODE_REV_ID_2              ((uint32_t)0x00040000)        /*!< Bit 2 */
+#define  DBGMCU_IDCODE_REV_ID_3              ((uint32_t)0x00080000)        /*!< Bit 3 */
+#define  DBGMCU_IDCODE_REV_ID_4              ((uint32_t)0x00100000)        /*!< Bit 4 */
+#define  DBGMCU_IDCODE_REV_ID_5              ((uint32_t)0x00200000)        /*!< Bit 5 */
+#define  DBGMCU_IDCODE_REV_ID_6              ((uint32_t)0x00400000)        /*!< Bit 6 */
+#define  DBGMCU_IDCODE_REV_ID_7              ((uint32_t)0x00800000)        /*!< Bit 7 */
+#define  DBGMCU_IDCODE_REV_ID_8              ((uint32_t)0x01000000)        /*!< Bit 8 */
+#define  DBGMCU_IDCODE_REV_ID_9              ((uint32_t)0x02000000)        /*!< Bit 9 */
+#define  DBGMCU_IDCODE_REV_ID_10             ((uint32_t)0x04000000)        /*!< Bit 10 */
+#define  DBGMCU_IDCODE_REV_ID_11             ((uint32_t)0x08000000)        /*!< Bit 11 */
+#define  DBGMCU_IDCODE_REV_ID_12             ((uint32_t)0x10000000)        /*!< Bit 12 */
+#define  DBGMCU_IDCODE_REV_ID_13             ((uint32_t)0x20000000)        /*!< Bit 13 */
+#define  DBGMCU_IDCODE_REV_ID_14             ((uint32_t)0x40000000)        /*!< Bit 14 */
+#define  DBGMCU_IDCODE_REV_ID_15             ((uint32_t)0x80000000)        /*!< Bit 15 */
+
+/******************  Bit definition for DBGMCU_CR register  *******************/
+#define  DBGMCU_CR_DBG_SLEEP                 ((uint32_t)0x00000001)        /*!< Debug Sleep Mode */
+#define  DBGMCU_CR_DBG_STOP                  ((uint32_t)0x00000002)        /*!< Debug Stop Mode */
+#define  DBGMCU_CR_DBG_STANDBY               ((uint32_t)0x00000004)        /*!< Debug Standby mode */
+#define  DBGMCU_CR_TRACE_IOEN                ((uint32_t)0x00000020)        /*!< Trace Pin Assignment Control */
+
+#define  DBGMCU_CR_TRACE_MODE                ((uint32_t)0x000000C0)        /*!< TRACE_MODE[1:0] bits (Trace Pin Assignment Control) */
+#define  DBGMCU_CR_TRACE_MODE_0              ((uint32_t)0x00000040)        /*!< Bit 0 */
+#define  DBGMCU_CR_TRACE_MODE_1              ((uint32_t)0x00000080)        /*!< Bit 1 */
+
+#define  DBGMCU_CR_DBG_IWDG_STOP             ((uint32_t)0x00000100)        /*!< Debug Independent Watchdog stopped when Core is halted */
+#define  DBGMCU_CR_DBG_WWDG_STOP             ((uint32_t)0x00000200)        /*!< Debug Window Watchdog stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM1_STOP             ((uint32_t)0x00000400)        /*!< TIM1 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM2_STOP             ((uint32_t)0x00000800)        /*!< TIM2 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM3_STOP             ((uint32_t)0x00001000)        /*!< TIM3 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM4_STOP             ((uint32_t)0x00002000)        /*!< TIM4 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_CAN1_STOP             ((uint32_t)0x00004000)        /*!< Debug CAN1 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT    ((uint32_t)0x00008000)        /*!< SMBUS timeout mode stopped when Core is halted */
+#define  DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT    ((uint32_t)0x00010000)        /*!< SMBUS timeout mode stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM8_STOP             ((uint32_t)0x00020000)        /*!< TIM8 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM5_STOP             ((uint32_t)0x00040000)        /*!< TIM5 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM6_STOP             ((uint32_t)0x00080000)        /*!< TIM6 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_TIM7_STOP             ((uint32_t)0x00100000)        /*!< TIM7 counter stopped when core is halted */
+#define  DBGMCU_CR_DBG_CAN2_STOP             ((uint32_t)0x00200000)        /*!< Debug CAN2 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM15_STOP            ((uint32_t)0x00400000)        /*!< Debug TIM15 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM16_STOP            ((uint32_t)0x00800000)        /*!< Debug TIM16 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM17_STOP            ((uint32_t)0x01000000)        /*!< Debug TIM17 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM12_STOP            ((uint32_t)0x02000000)        /*!< Debug TIM12 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM13_STOP            ((uint32_t)0x04000000)        /*!< Debug TIM13 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM14_STOP            ((uint32_t)0x08000000)        /*!< Debug TIM14 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM9_STOP             ((uint32_t)0x10000000)        /*!< Debug TIM9 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM10_STOP            ((uint32_t)0x20000000)        /*!< Debug TIM10 stopped when Core is halted */
+#define  DBGMCU_CR_DBG_TIM11_STOP            ((uint32_t)0x40000000)        /*!< Debug TIM11 stopped when Core is halted */
+
+/******************************************************************************/
+/*                                                                            */
+/*                      FLASH and Option Bytes Registers                      */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for FLASH_ACR register  ******************/
+#define  FLASH_ACR_LATENCY                   ((uint8_t)0x03)               /*!< LATENCY[2:0] bits (Latency) */
+#define  FLASH_ACR_LATENCY_0                 ((uint8_t)0x00)               /*!< Bit 0 */
+#define  FLASH_ACR_LATENCY_1                 ((uint8_t)0x01)               /*!< Bit 0 */
+#define  FLASH_ACR_LATENCY_2                 ((uint8_t)0x02)               /*!< Bit 1 */
+
+#define  FLASH_ACR_HLFCYA                    ((uint8_t)0x08)               /*!< Flash Half Cycle Access Enable */
+#define  FLASH_ACR_PRFTBE                    ((uint8_t)0x10)               /*!< Prefetch Buffer Enable */
+#define  FLASH_ACR_PRFTBS                    ((uint8_t)0x20)               /*!< Prefetch Buffer Status */
+
+/******************  Bit definition for FLASH_KEYR register  ******************/
+#define  FLASH_KEYR_FKEYR                    ((uint32_t)0xFFFFFFFF)        /*!< FPEC Key */
+
+/*****************  Bit definition for FLASH_OPTKEYR register  ****************/
+#define  FLASH_OPTKEYR_OPTKEYR               ((uint32_t)0xFFFFFFFF)        /*!< Option Byte Key */
+
+/******************  Bit definition for FLASH_SR register  *******************/
+#define  FLASH_SR_BSY                        ((uint8_t)0x01)               /*!< Busy */
+#define  FLASH_SR_PGERR                      ((uint8_t)0x04)               /*!< Programming Error */
+#define  FLASH_SR_WRPRTERR                   ((uint8_t)0x10)               /*!< Write Protection Error */
+#define  FLASH_SR_EOP                        ((uint8_t)0x20)               /*!< End of operation */
+
+/*******************  Bit definition for FLASH_CR register  *******************/
+#define  FLASH_CR_PG                         ((uint16_t)0x0001)            /*!< Programming */
+#define  FLASH_CR_PER                        ((uint16_t)0x0002)            /*!< Page Erase */
+#define  FLASH_CR_MER                        ((uint16_t)0x0004)            /*!< Mass Erase */
+#define  FLASH_CR_OPTPG                      ((uint16_t)0x0010)            /*!< Option Byte Programming */
+#define  FLASH_CR_OPTER                      ((uint16_t)0x0020)            /*!< Option Byte Erase */
+#define  FLASH_CR_STRT                       ((uint16_t)0x0040)            /*!< Start */
+#define  FLASH_CR_LOCK                       ((uint16_t)0x0080)            /*!< Lock */
+#define  FLASH_CR_OPTWRE                     ((uint16_t)0x0200)            /*!< Option Bytes Write Enable */
+#define  FLASH_CR_ERRIE                      ((uint16_t)0x0400)            /*!< Error Interrupt Enable */
+#define  FLASH_CR_EOPIE                      ((uint16_t)0x1000)            /*!< End of operation interrupt enable */
+
+/*******************  Bit definition for FLASH_AR register  *******************/
+#define  FLASH_AR_FAR                        ((uint32_t)0xFFFFFFFF)        /*!< Flash Address */
+
+/******************  Bit definition for FLASH_OBR register  *******************/
+#define  FLASH_OBR_OPTERR                    ((uint16_t)0x0001)            /*!< Option Byte Error */
+#define  FLASH_OBR_RDPRT                     ((uint16_t)0x0002)            /*!< Read protection */
+
+#define  FLASH_OBR_USER                      ((uint16_t)0x03FC)            /*!< User Option Bytes */
+#define  FLASH_OBR_WDG_SW                    ((uint16_t)0x0004)            /*!< WDG_SW */
+#define  FLASH_OBR_nRST_STOP                 ((uint16_t)0x0008)            /*!< nRST_STOP */
+#define  FLASH_OBR_nRST_STDBY                ((uint16_t)0x0010)            /*!< nRST_STDBY */
+#define  FLASH_OBR_BFB2                      ((uint16_t)0x0020)            /*!< BFB2 */
+
+/******************  Bit definition for FLASH_WRPR register  ******************/
+#define  FLASH_WRPR_WRP                        ((uint32_t)0xFFFFFFFF)        /*!< Write Protect */
+
+/*----------------------------------------------------------------------------*/
+
+/******************  Bit definition for FLASH_RDP register  *******************/
+#define  FLASH_RDP_RDP                       ((uint32_t)0x000000FF)        /*!< Read protection option byte */
+#define  FLASH_RDP_nRDP                      ((uint32_t)0x0000FF00)        /*!< Read protection complemented option byte */
+
+/******************  Bit definition for FLASH_USER register  ******************/
+#define  FLASH_USER_USER                     ((uint32_t)0x00FF0000)        /*!< User option byte */
+#define  FLASH_USER_nUSER                    ((uint32_t)0xFF000000)        /*!< User complemented option byte */
+
+/******************  Bit definition for FLASH_Data0 register  *****************/
+#define  FLASH_Data0_Data0                   ((uint32_t)0x000000FF)        /*!< User data storage option byte */
+#define  FLASH_Data0_nData0                  ((uint32_t)0x0000FF00)        /*!< User data storage complemented option byte */
+
+/******************  Bit definition for FLASH_Data1 register  *****************/
+#define  FLASH_Data1_Data1                   ((uint32_t)0x00FF0000)        /*!< User data storage option byte */
+#define  FLASH_Data1_nData1                  ((uint32_t)0xFF000000)        /*!< User data storage complemented option byte */
+
+/******************  Bit definition for FLASH_WRP0 register  ******************/
+#define  FLASH_WRP0_WRP0                     ((uint32_t)0x000000FF)        /*!< Flash memory write protection option bytes */
+#define  FLASH_WRP0_nWRP0                    ((uint32_t)0x0000FF00)        /*!< Flash memory write protection complemented option bytes */
+
+/******************  Bit definition for FLASH_WRP1 register  ******************/
+#define  FLASH_WRP1_WRP1                     ((uint32_t)0x00FF0000)        /*!< Flash memory write protection option bytes */
+#define  FLASH_WRP1_nWRP1                    ((uint32_t)0xFF000000)        /*!< Flash memory write protection complemented option bytes */
+
+/******************  Bit definition for FLASH_WRP2 register  ******************/
+#define  FLASH_WRP2_WRP2                     ((uint32_t)0x000000FF)        /*!< Flash memory write protection option bytes */
+#define  FLASH_WRP2_nWRP2                    ((uint32_t)0x0000FF00)        /*!< Flash memory write protection complemented option bytes */
+
+/******************  Bit definition for FLASH_WRP3 register  ******************/
+#define  FLASH_WRP3_WRP3                     ((uint32_t)0x00FF0000)        /*!< Flash memory write protection option bytes */
+#define  FLASH_WRP3_nWRP3                    ((uint32_t)0xFF000000)        /*!< Flash memory write protection complemented option bytes */
+
+#ifdef STM32F10X_CL
+/******************************************************************************/
+/*                Ethernet MAC Registers bits definitions                     */
+/******************************************************************************/
+/* Bit definition for Ethernet MAC Control Register register */
+#define ETH_MACCR_WD      ((uint32_t)0x00800000)  /* Watchdog disable */
+#define ETH_MACCR_JD      ((uint32_t)0x00400000)  /* Jabber disable */
+#define ETH_MACCR_IFG     ((uint32_t)0x000E0000)  /* Inter-frame gap */
+  #define ETH_MACCR_IFG_96Bit     ((uint32_t)0x00000000)  /* Minimum IFG between frames during transmission is 96Bit */
+  #define ETH_MACCR_IFG_88Bit     ((uint32_t)0x00020000)  /* Minimum IFG between frames during transmission is 88Bit */
+  #define ETH_MACCR_IFG_80Bit     ((uint32_t)0x00040000)  /* Minimum IFG between frames during transmission is 80Bit */
+  #define ETH_MACCR_IFG_72Bit     ((uint32_t)0x00060000)  /* Minimum IFG between frames during transmission is 72Bit */
+  #define ETH_MACCR_IFG_64Bit     ((uint32_t)0x00080000)  /* Minimum IFG between frames during transmission is 64Bit */        
+  #define ETH_MACCR_IFG_56Bit     ((uint32_t)0x000A0000)  /* Minimum IFG between frames during transmission is 56Bit */
+  #define ETH_MACCR_IFG_48Bit     ((uint32_t)0x000C0000)  /* Minimum IFG between frames during transmission is 48Bit */
+  #define ETH_MACCR_IFG_40Bit     ((uint32_t)0x000E0000)  /* Minimum IFG between frames during transmission is 40Bit */              
+#define ETH_MACCR_CSD     ((uint32_t)0x00010000)  /* Carrier sense disable (during transmission) */
+#define ETH_MACCR_FES     ((uint32_t)0x00004000)  /* Fast ethernet speed */
+#define ETH_MACCR_ROD     ((uint32_t)0x00002000)  /* Receive own disable */
+#define ETH_MACCR_LM      ((uint32_t)0x00001000)  /* loopback mode */
+#define ETH_MACCR_DM      ((uint32_t)0x00000800)  /* Duplex mode */
+#define ETH_MACCR_IPCO    ((uint32_t)0x00000400)  /* IP Checksum offload */
+#define ETH_MACCR_RD      ((uint32_t)0x00000200)  /* Retry disable */
+#define ETH_MACCR_APCS    ((uint32_t)0x00000080)  /* Automatic Pad/CRC stripping */
+#define ETH_MACCR_BL      ((uint32_t)0x00000060)  /* Back-off limit: random integer number (r) of slot time delays before rescheduling
+                                                       a transmission attempt during retries after a collision: 0 =< r <2^k */
+  #define ETH_MACCR_BL_10    ((uint32_t)0x00000000)  /* k = min (n, 10) */
+  #define ETH_MACCR_BL_8     ((uint32_t)0x00000020)  /* k = min (n, 8) */
+  #define ETH_MACCR_BL_4     ((uint32_t)0x00000040)  /* k = min (n, 4) */
+  #define ETH_MACCR_BL_1     ((uint32_t)0x00000060)  /* k = min (n, 1) */ 
+#define ETH_MACCR_DC      ((uint32_t)0x00000010)  /* Defferal check */
+#define ETH_MACCR_TE      ((uint32_t)0x00000008)  /* Transmitter enable */
+#define ETH_MACCR_RE      ((uint32_t)0x00000004)  /* Receiver enable */
+
+/* Bit definition for Ethernet MAC Frame Filter Register */
+#define ETH_MACFFR_RA     ((uint32_t)0x80000000)  /* Receive all */ 
+#define ETH_MACFFR_HPF    ((uint32_t)0x00000400)  /* Hash or perfect filter */ 
+#define ETH_MACFFR_SAF    ((uint32_t)0x00000200)  /* Source address filter enable */ 
+#define ETH_MACFFR_SAIF   ((uint32_t)0x00000100)  /* SA inverse filtering */ 
+#define ETH_MACFFR_PCF    ((uint32_t)0x000000C0)  /* Pass control frames: 3 cases */
+  #define ETH_MACFFR_PCF_BlockAll                ((uint32_t)0x00000040)  /* MAC filters all control frames from reaching the application */
+  #define ETH_MACFFR_PCF_ForwardAll              ((uint32_t)0x00000080)  /* MAC forwards all control frames to application even if they fail the Address Filter */
+  #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0)  /* MAC forwards control frames that pass the Address Filter. */ 
+#define ETH_MACFFR_BFD    ((uint32_t)0x00000020)  /* Broadcast frame disable */ 
+#define ETH_MACFFR_PAM 	  ((uint32_t)0x00000010)  /* Pass all mutlicast */ 
+#define ETH_MACFFR_DAIF   ((uint32_t)0x00000008)  /* DA Inverse filtering */ 
+#define ETH_MACFFR_HM     ((uint32_t)0x00000004)  /* Hash multicast */ 
+#define ETH_MACFFR_HU     ((uint32_t)0x00000002)  /* Hash unicast */
+#define ETH_MACFFR_PM     ((uint32_t)0x00000001)  /* Promiscuous mode */
+
+/* Bit definition for Ethernet MAC Hash Table High Register */
+#define ETH_MACHTHR_HTH   ((uint32_t)0xFFFFFFFF)  /* Hash table high */
+
+/* Bit definition for Ethernet MAC Hash Table Low Register */
+#define ETH_MACHTLR_HTL   ((uint32_t)0xFFFFFFFF)  /* Hash table low */
+
+/* Bit definition for Ethernet MAC MII Address Register */
+#define ETH_MACMIIAR_PA   ((uint32_t)0x0000F800)  /* Physical layer address */ 
+#define ETH_MACMIIAR_MR   ((uint32_t)0x000007C0)  /* MII register in the selected PHY */ 
+#define ETH_MACMIIAR_CR   ((uint32_t)0x0000001C)  /* CR clock range: 6 cases */ 
+  #define ETH_MACMIIAR_CR_Div42   ((uint32_t)0x00000000)  /* HCLK:60-72 MHz; MDC clock= HCLK/42 */
+  #define ETH_MACMIIAR_CR_Div16   ((uint32_t)0x00000008)  /* HCLK:20-35 MHz; MDC clock= HCLK/16 */
+  #define ETH_MACMIIAR_CR_Div26   ((uint32_t)0x0000000C)  /* HCLK:35-60 MHz; MDC clock= HCLK/26 */
+#define ETH_MACMIIAR_MW   ((uint32_t)0x00000002)  /* MII write */ 
+#define ETH_MACMIIAR_MB   ((uint32_t)0x00000001)  /* MII busy */ 
+  
+/* Bit definition for Ethernet MAC MII Data Register */
+#define ETH_MACMIIDR_MD   ((uint32_t)0x0000FFFF)  /* MII data: read/write data from/to PHY */
+
+/* Bit definition for Ethernet MAC Flow Control Register */
+#define ETH_MACFCR_PT     ((uint32_t)0xFFFF0000)  /* Pause time */
+#define ETH_MACFCR_ZQPD   ((uint32_t)0x00000080)  /* Zero-quanta pause disable */
+#define ETH_MACFCR_PLT    ((uint32_t)0x00000030)  /* Pause low threshold: 4 cases */
+  #define ETH_MACFCR_PLT_Minus4   ((uint32_t)0x00000000)  /* Pause time minus 4 slot times */
+  #define ETH_MACFCR_PLT_Minus28  ((uint32_t)0x00000010)  /* Pause time minus 28 slot times */
+  #define ETH_MACFCR_PLT_Minus144 ((uint32_t)0x00000020)  /* Pause time minus 144 slot times */
+  #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030)  /* Pause time minus 256 slot times */      
+#define ETH_MACFCR_UPFD   ((uint32_t)0x00000008)  /* Unicast pause frame detect */
+#define ETH_MACFCR_RFCE   ((uint32_t)0x00000004)  /* Receive flow control enable */
+#define ETH_MACFCR_TFCE   ((uint32_t)0x00000002)  /* Transmit flow control enable */
+#define ETH_MACFCR_FCBBPA ((uint32_t)0x00000001)  /* Flow control busy/backpressure activate */
+
+/* Bit definition for Ethernet MAC VLAN Tag Register */
+#define ETH_MACVLANTR_VLANTC ((uint32_t)0x00010000)  /* 12-bit VLAN tag comparison */
+#define ETH_MACVLANTR_VLANTI ((uint32_t)0x0000FFFF)  /* VLAN tag identifier (for receive frames) */
+
+/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */ 
+#define ETH_MACRWUFFR_D   ((uint32_t)0xFFFFFFFF)  /* Wake-up frame filter register data */
+/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers.
+   Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */
+/* Wake-UpFrame Filter Reg0 : Filter 0 Byte Mask
+   Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask
+   Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask
+   Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask
+   Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command - 
+                              RSVD - Filter1 Command - RSVD - Filter0 Command
+   Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset
+   Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16
+   Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */
+
+/* Bit definition for Ethernet MAC PMT Control and Status Register */ 
+#define ETH_MACPMTCSR_WFFRPR ((uint32_t)0x80000000)  /* Wake-Up Frame Filter Register Pointer Reset */
+#define ETH_MACPMTCSR_GU     ((uint32_t)0x00000200)  /* Global Unicast */
+#define ETH_MACPMTCSR_WFR    ((uint32_t)0x00000040)  /* Wake-Up Frame Received */
+#define ETH_MACPMTCSR_MPR    ((uint32_t)0x00000020)  /* Magic Packet Received */
+#define ETH_MACPMTCSR_WFE    ((uint32_t)0x00000004)  /* Wake-Up Frame Enable */
+#define ETH_MACPMTCSR_MPE    ((uint32_t)0x00000002)  /* Magic Packet Enable */
+#define ETH_MACPMTCSR_PD     ((uint32_t)0x00000001)  /* Power Down */
+
+/* Bit definition for Ethernet MAC Status Register */
+#define ETH_MACSR_TSTS      ((uint32_t)0x00000200)  /* Time stamp trigger status */
+#define ETH_MACSR_MMCTS     ((uint32_t)0x00000040)  /* MMC transmit status */
+#define ETH_MACSR_MMMCRS    ((uint32_t)0x00000020)  /* MMC receive status */
+#define ETH_MACSR_MMCS      ((uint32_t)0x00000010)  /* MMC status */
+#define ETH_MACSR_PMTS      ((uint32_t)0x00000008)  /* PMT status */
+
+/* Bit definition for Ethernet MAC Interrupt Mask Register */
+#define ETH_MACIMR_TSTIM     ((uint32_t)0x00000200)  /* Time stamp trigger interrupt mask */
+#define ETH_MACIMR_PMTIM     ((uint32_t)0x00000008)  /* PMT interrupt mask */
+
+/* Bit definition for Ethernet MAC Address0 High Register */
+#define ETH_MACA0HR_MACA0H   ((uint32_t)0x0000FFFF)  /* MAC address0 high */
+
+/* Bit definition for Ethernet MAC Address0 Low Register */
+#define ETH_MACA0LR_MACA0L   ((uint32_t)0xFFFFFFFF)  /* MAC address0 low */
+
+/* Bit definition for Ethernet MAC Address1 High Register */
+#define ETH_MACA1HR_AE       ((uint32_t)0x80000000)  /* Address enable */
+#define ETH_MACA1HR_SA       ((uint32_t)0x40000000)  /* Source address */
+#define ETH_MACA1HR_MBC      ((uint32_t)0x3F000000)  /* Mask byte control: bits to mask for comparison of the MAC Address bytes */
+  #define ETH_MACA1HR_MBC_HBits15_8    ((uint32_t)0x20000000)  /* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA1HR_MBC_HBits7_0     ((uint32_t)0x10000000)  /* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA1HR_MBC_LBits31_24   ((uint32_t)0x08000000)  /* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA1HR_MBC_LBits23_16   ((uint32_t)0x04000000)  /* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA1HR_MBC_LBits15_8    ((uint32_t)0x02000000)  /* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA1HR_MBC_LBits7_0     ((uint32_t)0x01000000)  /* Mask MAC Address low reg bits [7:0] */ 
+#define ETH_MACA1HR_MACA1H   ((uint32_t)0x0000FFFF)  /* MAC address1 high */
+
+/* Bit definition for Ethernet MAC Address1 Low Register */
+#define ETH_MACA1LR_MACA1L   ((uint32_t)0xFFFFFFFF)  /* MAC address1 low */
+
+/* Bit definition for Ethernet MAC Address2 High Register */
+#define ETH_MACA2HR_AE       ((uint32_t)0x80000000)  /* Address enable */
+#define ETH_MACA2HR_SA       ((uint32_t)0x40000000)  /* Source address */
+#define ETH_MACA2HR_MBC      ((uint32_t)0x3F000000)  /* Mask byte control */
+  #define ETH_MACA2HR_MBC_HBits15_8    ((uint32_t)0x20000000)  /* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA2HR_MBC_HBits7_0     ((uint32_t)0x10000000)  /* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA2HR_MBC_LBits31_24   ((uint32_t)0x08000000)  /* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA2HR_MBC_LBits23_16   ((uint32_t)0x04000000)  /* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA2HR_MBC_LBits15_8    ((uint32_t)0x02000000)  /* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA2HR_MBC_LBits7_0     ((uint32_t)0x01000000)  /* Mask MAC Address low reg bits [70] */
+#define ETH_MACA2HR_MACA2H   ((uint32_t)0x0000FFFF)  /* MAC address1 high */
+
+/* Bit definition for Ethernet MAC Address2 Low Register */
+#define ETH_MACA2LR_MACA2L   ((uint32_t)0xFFFFFFFF)  /* MAC address2 low */
+
+/* Bit definition for Ethernet MAC Address3 High Register */
+#define ETH_MACA3HR_AE       ((uint32_t)0x80000000)  /* Address enable */
+#define ETH_MACA3HR_SA       ((uint32_t)0x40000000)  /* Source address */
+#define ETH_MACA3HR_MBC      ((uint32_t)0x3F000000)  /* Mask byte control */
+  #define ETH_MACA3HR_MBC_HBits15_8    ((uint32_t)0x20000000)  /* Mask MAC Address high reg bits [15:8] */
+  #define ETH_MACA3HR_MBC_HBits7_0     ((uint32_t)0x10000000)  /* Mask MAC Address high reg bits [7:0] */
+  #define ETH_MACA3HR_MBC_LBits31_24   ((uint32_t)0x08000000)  /* Mask MAC Address low reg bits [31:24] */
+  #define ETH_MACA3HR_MBC_LBits23_16   ((uint32_t)0x04000000)  /* Mask MAC Address low reg bits [23:16] */
+  #define ETH_MACA3HR_MBC_LBits15_8    ((uint32_t)0x02000000)  /* Mask MAC Address low reg bits [15:8] */
+  #define ETH_MACA3HR_MBC_LBits7_0     ((uint32_t)0x01000000)  /* Mask MAC Address low reg bits [70] */
+#define ETH_MACA3HR_MACA3H   ((uint32_t)0x0000FFFF)  /* MAC address3 high */
+
+/* Bit definition for Ethernet MAC Address3 Low Register */
+#define ETH_MACA3LR_MACA3L   ((uint32_t)0xFFFFFFFF)  /* MAC address3 low */
+
+/******************************************************************************/
+/*                Ethernet MMC Registers bits definition                      */
+/******************************************************************************/
+
+/* Bit definition for Ethernet MMC Contol Register */
+#define ETH_MMCCR_MCF        ((uint32_t)0x00000008)  /* MMC Counter Freeze */
+#define ETH_MMCCR_ROR        ((uint32_t)0x00000004)  /* Reset on Read */
+#define ETH_MMCCR_CSR        ((uint32_t)0x00000002)  /* Counter Stop Rollover */
+#define ETH_MMCCR_CR         ((uint32_t)0x00000001)  /* Counters Reset */
+
+/* Bit definition for Ethernet MMC Receive Interrupt Register */
+#define ETH_MMCRIR_RGUFS     ((uint32_t)0x00020000)  /* Set when Rx good unicast frames counter reaches half the maximum value */
+#define ETH_MMCRIR_RFAES     ((uint32_t)0x00000040)  /* Set when Rx alignment error counter reaches half the maximum value */
+#define ETH_MMCRIR_RFCES     ((uint32_t)0x00000020)  /* Set when Rx crc error counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmit Interrupt Register */
+#define ETH_MMCTIR_TGFS      ((uint32_t)0x00200000)  /* Set when Tx good frame count counter reaches half the maximum value */
+#define ETH_MMCTIR_TGFMSCS   ((uint32_t)0x00008000)  /* Set when Tx good multi col counter reaches half the maximum value */
+#define ETH_MMCTIR_TGFSCS    ((uint32_t)0x00004000)  /* Set when Tx good single col counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Receive Interrupt Mask Register */
+#define ETH_MMCRIMR_RGUFM    ((uint32_t)0x00020000)  /* Mask the interrupt when Rx good unicast frames counter reaches half the maximum value */
+#define ETH_MMCRIMR_RFAEM    ((uint32_t)0x00000040)  /* Mask the interrupt when when Rx alignment error counter reaches half the maximum value */
+#define ETH_MMCRIMR_RFCEM    ((uint32_t)0x00000020)  /* Mask the interrupt when Rx crc error counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmit Interrupt Mask Register */
+#define ETH_MMCTIMR_TGFM     ((uint32_t)0x00200000)  /* Mask the interrupt when Tx good frame count counter reaches half the maximum value */
+#define ETH_MMCTIMR_TGFMSCM  ((uint32_t)0x00008000)  /* Mask the interrupt when Tx good multi col counter reaches half the maximum value */
+#define ETH_MMCTIMR_TGFSCM   ((uint32_t)0x00004000)  /* Mask the interrupt when Tx good single col counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames after Single Collision Counter Register */
+#define ETH_MMCTGFSCCR_TGFSCC     ((uint32_t)0xFFFFFFFF)  /* Number of successfully transmitted frames after a single collision in Half-duplex mode. */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames after More than a Single Collision Counter Register */
+#define ETH_MMCTGFMSCCR_TGFMSCC   ((uint32_t)0xFFFFFFFF)  /* Number of successfully transmitted frames after more than a single collision in Half-duplex mode. */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames Counter Register */
+#define ETH_MMCTGFCR_TGFC    ((uint32_t)0xFFFFFFFF)  /* Number of good frames transmitted. */
+
+/* Bit definition for Ethernet MMC Received Frames with CRC Error Counter Register */
+#define ETH_MMCRFCECR_RFCEC  ((uint32_t)0xFFFFFFFF)  /* Number of frames received with CRC error. */
+
+/* Bit definition for Ethernet MMC Received Frames with Alignement Error Counter Register */
+#define ETH_MMCRFAECR_RFAEC  ((uint32_t)0xFFFFFFFF)  /* Number of frames received with alignment (dribble) error */
+
+/* Bit definition for Ethernet MMC Received Good Unicast Frames Counter Register */
+#define ETH_MMCRGUFCR_RGUFC  ((uint32_t)0xFFFFFFFF)  /* Number of good unicast frames received. */
+
+/******************************************************************************/
+/*               Ethernet PTP Registers bits definition                       */
+/******************************************************************************/
+
+/* Bit definition for Ethernet PTP Time Stamp Contol Register */
+#define ETH_PTPTSCR_TSARU    ((uint32_t)0x00000020)  /* Addend register update */
+#define ETH_PTPTSCR_TSITE    ((uint32_t)0x00000010)  /* Time stamp interrupt trigger enable */
+#define ETH_PTPTSCR_TSSTU    ((uint32_t)0x00000008)  /* Time stamp update */
+#define ETH_PTPTSCR_TSSTI    ((uint32_t)0x00000004)  /* Time stamp initialize */
+#define ETH_PTPTSCR_TSFCU    ((uint32_t)0x00000002)  /* Time stamp fine or coarse update */
+#define ETH_PTPTSCR_TSE      ((uint32_t)0x00000001)  /* Time stamp enable */
+
+/* Bit definition for Ethernet PTP Sub-Second Increment Register */
+#define ETH_PTPSSIR_STSSI    ((uint32_t)0x000000FF)  /* System time Sub-second increment value */
+
+/* Bit definition for Ethernet PTP Time Stamp High Register */
+#define ETH_PTPTSHR_STS      ((uint32_t)0xFFFFFFFF)  /* System Time second */
+
+/* Bit definition for Ethernet PTP Time Stamp Low Register */
+#define ETH_PTPTSLR_STPNS    ((uint32_t)0x80000000)  /* System Time Positive or negative time */
+#define ETH_PTPTSLR_STSS     ((uint32_t)0x7FFFFFFF)  /* System Time sub-seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp High Update Register */
+#define ETH_PTPTSHUR_TSUS    ((uint32_t)0xFFFFFFFF)  /* Time stamp update seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp Low Update Register */
+#define ETH_PTPTSLUR_TSUPNS  ((uint32_t)0x80000000)  /* Time stamp update Positive or negative time */
+#define ETH_PTPTSLUR_TSUSS   ((uint32_t)0x7FFFFFFF)  /* Time stamp update sub-seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp Addend Register */
+#define ETH_PTPTSAR_TSA      ((uint32_t)0xFFFFFFFF)  /* Time stamp addend */
+
+/* Bit definition for Ethernet PTP Target Time High Register */
+#define ETH_PTPTTHR_TTSH     ((uint32_t)0xFFFFFFFF)  /* Target time stamp high */
+
+/* Bit definition for Ethernet PTP Target Time Low Register */
+#define ETH_PTPTTLR_TTSL     ((uint32_t)0xFFFFFFFF)  /* Target time stamp low */
+
+/******************************************************************************/
+/*                 Ethernet DMA Registers bits definition                     */
+/******************************************************************************/
+
+/* Bit definition for Ethernet DMA Bus Mode Register */
+#define ETH_DMABMR_AAB       ((uint32_t)0x02000000)  /* Address-Aligned beats */
+#define ETH_DMABMR_FPM        ((uint32_t)0x01000000)  /* 4xPBL mode */
+#define ETH_DMABMR_USP       ((uint32_t)0x00800000)  /* Use separate PBL */
+#define ETH_DMABMR_RDP       ((uint32_t)0x007E0000)  /* RxDMA PBL */
+  #define ETH_DMABMR_RDP_1Beat    ((uint32_t)0x00020000)  /* maximum number of beats to be transferred in one RxDMA transaction is 1 */
+  #define ETH_DMABMR_RDP_2Beat    ((uint32_t)0x00040000)  /* maximum number of beats to be transferred in one RxDMA transaction is 2 */
+  #define ETH_DMABMR_RDP_4Beat    ((uint32_t)0x00080000)  /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+  #define ETH_DMABMR_RDP_8Beat    ((uint32_t)0x00100000)  /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+  #define ETH_DMABMR_RDP_16Beat   ((uint32_t)0x00200000)  /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+  #define ETH_DMABMR_RDP_32Beat   ((uint32_t)0x00400000)  /* maximum number of beats to be transferred in one RxDMA transaction is 32 */                
+  #define ETH_DMABMR_RDP_4xPBL_4Beat   ((uint32_t)0x01020000)  /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+  #define ETH_DMABMR_RDP_4xPBL_8Beat   ((uint32_t)0x01040000)  /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+  #define ETH_DMABMR_RDP_4xPBL_16Beat  ((uint32_t)0x01080000)  /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+  #define ETH_DMABMR_RDP_4xPBL_32Beat  ((uint32_t)0x01100000)  /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+  #define ETH_DMABMR_RDP_4xPBL_64Beat  ((uint32_t)0x01200000)  /* maximum number of beats to be transferred in one RxDMA transaction is 64 */
+  #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000)  /* maximum number of beats to be transferred in one RxDMA transaction is 128 */  
+#define ETH_DMABMR_FB        ((uint32_t)0x00010000)  /* Fixed Burst */
+#define ETH_DMABMR_RTPR      ((uint32_t)0x0000C000)  /* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_1_1     ((uint32_t)0x00000000)  /* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_2_1     ((uint32_t)0x00004000)  /* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_3_1     ((uint32_t)0x00008000)  /* Rx Tx priority ratio */
+  #define ETH_DMABMR_RTPR_4_1     ((uint32_t)0x0000C000)  /* Rx Tx priority ratio */  
+#define ETH_DMABMR_PBL    ((uint32_t)0x00003F00)  /* Programmable burst length */
+  #define ETH_DMABMR_PBL_1Beat    ((uint32_t)0x00000100)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
+  #define ETH_DMABMR_PBL_2Beat    ((uint32_t)0x00000200)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
+  #define ETH_DMABMR_PBL_4Beat    ((uint32_t)0x00000400)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+  #define ETH_DMABMR_PBL_8Beat    ((uint32_t)0x00000800)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+  #define ETH_DMABMR_PBL_16Beat   ((uint32_t)0x00001000)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+  #define ETH_DMABMR_PBL_32Beat   ((uint32_t)0x00002000)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */                
+  #define ETH_DMABMR_PBL_4xPBL_4Beat   ((uint32_t)0x01000100)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+  #define ETH_DMABMR_PBL_4xPBL_8Beat   ((uint32_t)0x01000200)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+  #define ETH_DMABMR_PBL_4xPBL_16Beat  ((uint32_t)0x01000400)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+  #define ETH_DMABMR_PBL_4xPBL_32Beat  ((uint32_t)0x01000800)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+  #define ETH_DMABMR_PBL_4xPBL_64Beat  ((uint32_t)0x01001000)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
+  #define ETH_DMABMR_PBL_4xPBL_128Beat ((uint32_t)0x01002000)  /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
+#define ETH_DMABMR_DSL       ((uint32_t)0x0000007C)  /* Descriptor Skip Length */
+#define ETH_DMABMR_DA        ((uint32_t)0x00000002)  /* DMA arbitration scheme */
+#define ETH_DMABMR_SR        ((uint32_t)0x00000001)  /* Software reset */
+
+/* Bit definition for Ethernet DMA Transmit Poll Demand Register */
+#define ETH_DMATPDR_TPD      ((uint32_t)0xFFFFFFFF)  /* Transmit poll demand */
+
+/* Bit definition for Ethernet DMA Receive Poll Demand Register */
+#define ETH_DMARPDR_RPD      ((uint32_t)0xFFFFFFFF)  /* Receive poll demand  */
+
+/* Bit definition for Ethernet DMA Receive Descriptor List Address Register */
+#define ETH_DMARDLAR_SRL     ((uint32_t)0xFFFFFFFF)  /* Start of receive list */
+
+/* Bit definition for Ethernet DMA Transmit Descriptor List Address Register */
+#define ETH_DMATDLAR_STL     ((uint32_t)0xFFFFFFFF)  /* Start of transmit list */
+
+/* Bit definition for Ethernet DMA Status Register */
+#define ETH_DMASR_TSTS       ((uint32_t)0x20000000)  /* Time-stamp trigger status */
+#define ETH_DMASR_PMTS       ((uint32_t)0x10000000)  /* PMT status */
+#define ETH_DMASR_MMCS       ((uint32_t)0x08000000)  /* MMC status */
+#define ETH_DMASR_EBS        ((uint32_t)0x03800000)  /* Error bits status */
+  /* combination with EBS[2:0] for GetFlagStatus function */
+  #define ETH_DMASR_EBS_DescAccess      ((uint32_t)0x02000000)  /* Error bits 0-data buffer, 1-desc. access */
+  #define ETH_DMASR_EBS_ReadTransf      ((uint32_t)0x01000000)  /* Error bits 0-write trnsf, 1-read transfr */
+  #define ETH_DMASR_EBS_DataTransfTx    ((uint32_t)0x00800000)  /* Error bits 0-Rx DMA, 1-Tx DMA */
+#define ETH_DMASR_TPS         ((uint32_t)0x00700000)  /* Transmit process state */
+  #define ETH_DMASR_TPS_Stopped         ((uint32_t)0x00000000)  /* Stopped - Reset or Stop Tx Command issued  */
+  #define ETH_DMASR_TPS_Fetching        ((uint32_t)0x00100000)  /* Running - fetching the Tx descriptor */
+  #define ETH_DMASR_TPS_Waiting         ((uint32_t)0x00200000)  /* Running - waiting for status */
+  #define ETH_DMASR_TPS_Reading         ((uint32_t)0x00300000)  /* Running - reading the data from host memory */
+  #define ETH_DMASR_TPS_Suspended       ((uint32_t)0x00600000)  /* Suspended - Tx Descriptor unavailabe */
+  #define ETH_DMASR_TPS_Closing         ((uint32_t)0x00700000)  /* Running - closing Rx descriptor */
+#define ETH_DMASR_RPS         ((uint32_t)0x000E0000)  /* Receive process state */
+  #define ETH_DMASR_RPS_Stopped         ((uint32_t)0x00000000)  /* Stopped - Reset or Stop Rx Command issued */
+  #define ETH_DMASR_RPS_Fetching        ((uint32_t)0x00020000)  /* Running - fetching the Rx descriptor */
+  #define ETH_DMASR_RPS_Waiting         ((uint32_t)0x00060000)  /* Running - waiting for packet */
+  #define ETH_DMASR_RPS_Suspended       ((uint32_t)0x00080000)  /* Suspended - Rx Descriptor unavailable */
+  #define ETH_DMASR_RPS_Closing         ((uint32_t)0x000A0000)  /* Running - closing descriptor */
+  #define ETH_DMASR_RPS_Queuing         ((uint32_t)0x000E0000)  /* Running - queuing the recieve frame into host memory */
+#define ETH_DMASR_NIS        ((uint32_t)0x00010000)  /* Normal interrupt summary */
+#define ETH_DMASR_AIS        ((uint32_t)0x00008000)  /* Abnormal interrupt summary */
+#define ETH_DMASR_ERS        ((uint32_t)0x00004000)  /* Early receive status */
+#define ETH_DMASR_FBES       ((uint32_t)0x00002000)  /* Fatal bus error status */
+#define ETH_DMASR_ETS        ((uint32_t)0x00000400)  /* Early transmit status */
+#define ETH_DMASR_RWTS       ((uint32_t)0x00000200)  /* Receive watchdog timeout status */
+#define ETH_DMASR_RPSS       ((uint32_t)0x00000100)  /* Receive process stopped status */
+#define ETH_DMASR_RBUS       ((uint32_t)0x00000080)  /* Receive buffer unavailable status */
+#define ETH_DMASR_RS         ((uint32_t)0x00000040)  /* Receive status */
+#define ETH_DMASR_TUS        ((uint32_t)0x00000020)  /* Transmit underflow status */
+#define ETH_DMASR_ROS        ((uint32_t)0x00000010)  /* Receive overflow status */
+#define ETH_DMASR_TJTS       ((uint32_t)0x00000008)  /* Transmit jabber timeout status */
+#define ETH_DMASR_TBUS       ((uint32_t)0x00000004)  /* Transmit buffer unavailable status */
+#define ETH_DMASR_TPSS       ((uint32_t)0x00000002)  /* Transmit process stopped status */
+#define ETH_DMASR_TS         ((uint32_t)0x00000001)  /* Transmit status */
+
+/* Bit definition for Ethernet DMA Operation Mode Register */
+#define ETH_DMAOMR_DTCEFD    ((uint32_t)0x04000000)  /* Disable Dropping of TCP/IP checksum error frames */
+#define ETH_DMAOMR_RSF       ((uint32_t)0x02000000)  /* Receive store and forward */
+#define ETH_DMAOMR_DFRF      ((uint32_t)0x01000000)  /* Disable flushing of received frames */
+#define ETH_DMAOMR_TSF       ((uint32_t)0x00200000)  /* Transmit store and forward */
+#define ETH_DMAOMR_FTF       ((uint32_t)0x00100000)  /* Flush transmit FIFO */
+#define ETH_DMAOMR_TTC       ((uint32_t)0x0001C000)  /* Transmit threshold control */
+  #define ETH_DMAOMR_TTC_64Bytes       ((uint32_t)0x00000000)  /* threshold level of the MTL Transmit FIFO is 64 Bytes */
+  #define ETH_DMAOMR_TTC_128Bytes      ((uint32_t)0x00004000)  /* threshold level of the MTL Transmit FIFO is 128 Bytes */
+  #define ETH_DMAOMR_TTC_192Bytes      ((uint32_t)0x00008000)  /* threshold level of the MTL Transmit FIFO is 192 Bytes */
+  #define ETH_DMAOMR_TTC_256Bytes      ((uint32_t)0x0000C000)  /* threshold level of the MTL Transmit FIFO is 256 Bytes */
+  #define ETH_DMAOMR_TTC_40Bytes       ((uint32_t)0x00010000)  /* threshold level of the MTL Transmit FIFO is 40 Bytes */
+  #define ETH_DMAOMR_TTC_32Bytes       ((uint32_t)0x00014000)  /* threshold level of the MTL Transmit FIFO is 32 Bytes */
+  #define ETH_DMAOMR_TTC_24Bytes       ((uint32_t)0x00018000)  /* threshold level of the MTL Transmit FIFO is 24 Bytes */
+  #define ETH_DMAOMR_TTC_16Bytes       ((uint32_t)0x0001C000)  /* threshold level of the MTL Transmit FIFO is 16 Bytes */
+#define ETH_DMAOMR_ST        ((uint32_t)0x00002000)  /* Start/stop transmission command */
+#define ETH_DMAOMR_FEF       ((uint32_t)0x00000080)  /* Forward error frames */
+#define ETH_DMAOMR_FUGF      ((uint32_t)0x00000040)  /* Forward undersized good frames */
+#define ETH_DMAOMR_RTC       ((uint32_t)0x00000018)  /* receive threshold control */
+  #define ETH_DMAOMR_RTC_64Bytes       ((uint32_t)0x00000000)  /* threshold level of the MTL Receive FIFO is 64 Bytes */
+  #define ETH_DMAOMR_RTC_32Bytes       ((uint32_t)0x00000008)  /* threshold level of the MTL Receive FIFO is 32 Bytes */
+  #define ETH_DMAOMR_RTC_96Bytes       ((uint32_t)0x00000010)  /* threshold level of the MTL Receive FIFO is 96 Bytes */
+  #define ETH_DMAOMR_RTC_128Bytes      ((uint32_t)0x00000018)  /* threshold level of the MTL Receive FIFO is 128 Bytes */
+#define ETH_DMAOMR_OSF       ((uint32_t)0x00000004)  /* operate on second frame */
+#define ETH_DMAOMR_SR        ((uint32_t)0x00000002)  /* Start/stop receive */
+
+/* Bit definition for Ethernet DMA Interrupt Enable Register */
+#define ETH_DMAIER_NISE      ((uint32_t)0x00010000)  /* Normal interrupt summary enable */
+#define ETH_DMAIER_AISE      ((uint32_t)0x00008000)  /* Abnormal interrupt summary enable */
+#define ETH_DMAIER_ERIE      ((uint32_t)0x00004000)  /* Early receive interrupt enable */
+#define ETH_DMAIER_FBEIE     ((uint32_t)0x00002000)  /* Fatal bus error interrupt enable */
+#define ETH_DMAIER_ETIE      ((uint32_t)0x00000400)  /* Early transmit interrupt enable */
+#define ETH_DMAIER_RWTIE     ((uint32_t)0x00000200)  /* Receive watchdog timeout interrupt enable */
+#define ETH_DMAIER_RPSIE     ((uint32_t)0x00000100)  /* Receive process stopped interrupt enable */
+#define ETH_DMAIER_RBUIE     ((uint32_t)0x00000080)  /* Receive buffer unavailable interrupt enable */
+#define ETH_DMAIER_RIE       ((uint32_t)0x00000040)  /* Receive interrupt enable */
+#define ETH_DMAIER_TUIE      ((uint32_t)0x00000020)  /* Transmit Underflow interrupt enable */
+#define ETH_DMAIER_ROIE      ((uint32_t)0x00000010)  /* Receive Overflow interrupt enable */
+#define ETH_DMAIER_TJTIE     ((uint32_t)0x00000008)  /* Transmit jabber timeout interrupt enable */
+#define ETH_DMAIER_TBUIE     ((uint32_t)0x00000004)  /* Transmit buffer unavailable interrupt enable */
+#define ETH_DMAIER_TPSIE     ((uint32_t)0x00000002)  /* Transmit process stopped interrupt enable */
+#define ETH_DMAIER_TIE       ((uint32_t)0x00000001)  /* Transmit interrupt enable */
+
+/* Bit definition for Ethernet DMA Missed Frame and Buffer Overflow Counter Register */
+#define ETH_DMAMFBOCR_OFOC   ((uint32_t)0x10000000)  /* Overflow bit for FIFO overflow counter */
+#define ETH_DMAMFBOCR_MFA    ((uint32_t)0x0FFE0000)  /* Number of frames missed by the application */
+#define ETH_DMAMFBOCR_OMFC   ((uint32_t)0x00010000)  /* Overflow bit for missed frame counter */
+#define ETH_DMAMFBOCR_MFC    ((uint32_t)0x0000FFFF)  /* Number of frames missed by the controller */
+
+/* Bit definition for Ethernet DMA Current Host Transmit Descriptor Register */
+#define ETH_DMACHTDR_HTDAP   ((uint32_t)0xFFFFFFFF)  /* Host transmit descriptor address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Receive Descriptor Register */
+#define ETH_DMACHRDR_HRDAP   ((uint32_t)0xFFFFFFFF)  /* Host receive descriptor address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Transmit Buffer Address Register */
+#define ETH_DMACHTBAR_HTBAP  ((uint32_t)0xFFFFFFFF)  /* Host transmit buffer address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Receive Buffer Address Register */
+#define ETH_DMACHRBAR_HRBAP  ((uint32_t)0xFFFFFFFF)  /* Host receive buffer address pointer */
+#endif /* STM32F10X_CL */
+
+/**
+  * @}
+  */
+
+ /**
+  * @}
+  */ 
+
+#ifdef USE_STDPERIPH_DRIVER
+  #include "stm32f10x_conf.h"
+#endif
+
+/** @addtogroup Exported_macro
+  * @{
+  */
+
+#define SET_BIT(REG, BIT)     ((REG) |= (BIT))
+
+#define CLEAR_BIT(REG, BIT)   ((REG) &= ~(BIT))
+
+#define READ_BIT(REG, BIT)    ((REG) & (BIT))
+
+#define CLEAR_REG(REG)        ((REG) = (0x0))
+
+#define WRITE_REG(REG, VAL)   ((REG) = (VAL))
+
+#define READ_REG(REG)         ((REG))
+
+#define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_H */
+
+/**
+  * @}
+  */
+
+  /**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis_boot/stm32f10x_conf.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,78 @@
+/**
+  ******************************************************************************
+  * @file    RTC/Calendar/stm32f10x_conf.h 
+  * @author  MCD Application Team
+  * @version V3.4.0
+  * @date    10/15/2010
+  * @brief   Library configuration file.
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_CONF_H
+#define __STM32F10x_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment the line below to enable peripheral header file inclusion */
+/* #include "stm32f10x_adc.h" */
+/* #include "stm32f10x_bkp.h" */
+/* #include "stm32f10x_can.h" */
+/* #include "stm32f10x_cec.h" */
+/* #include "stm32f10x_crc.h" */
+/* #include "stm32f10x_dac.h" */
+/* #include "stm32f10x_dbgmcu.h" */
+/* #include "stm32f10x_dma.h" */
+/* #include "stm32f10x_exti.h" */
+/* #include "stm32f10x_flash.h" */
+/* #include "stm32f10x_fsmc.h" */
+/* #include "stm32f10x_gpio.h" */
+/* #include "stm32f10x_i2c.h" */
+/* #include "stm32f10x_iwdg.h" */
+/* #include "stm32f10x_pwr.h" */
+/* #include "stm32f10x_rcc.h" */
+/* #include "stm32f10x_rtc.h"  */
+/* #include "stm32f10x_sdio.h" */
+/* #include "stm32f10x_spi.h" */
+/* #include "stm32f10x_tim.h" */
+/* #include "stm32f10x_usart.h" */
+/* #include "stm32f10x_wwdg.h" */
+/* #include "misc.h" */ /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Uncomment the line below to expanse the "assert_param" macro in the 
+   Standard Peripheral Library drivers code */
+/* #define USE_FULL_ASSERT    1 */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT
+
+/**
+  * @brief  The assert_param macro is used for function's parameters check.
+  * @param  expr: If expr is false, it calls assert_failed function
+  *   which reports the name of the source file and the source
+  *   line number of the call that failed. 
+  *   If expr is true, it returns no value.
+  * @retval None
+  */
+  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+  void assert_failed(uint8_t* file, uint32_t line);
+#else
+  #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#endif /* __STM32F10x_CONF_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis_boot/system_stm32f10x.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1094 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32f10x.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
+  * 
+  * 1.  This file provides two functions and one global variable to be called from 
+  *     user application:
+  *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+  *                      factors, AHB/APBx prescalers and Flash settings). 
+  *                      This function is called at startup just after reset and 
+  *                      before branch to main program. This call is made inside
+  *                      the "startup_stm32f10x_xx.s" file.
+  *
+  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+  *                                  by the user application to setup the SysTick 
+  *                                  timer or configure other parameters.
+  *                                     
+  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+  *                                 be called whenever the core clock is changed
+  *                                 during program execution.
+  *
+  * 2. After each device reset the HSI (8 MHz) is used as system clock source.
+  *    Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to
+  *    configure the system clock before to branch to main program.
+  *
+  * 3. If the system clock source selected by user fails to startup, the SystemInit()
+  *    function will do nothing and HSI still used as system clock source. User can 
+  *    add some code to deal with this issue inside the SetSysClock() function.
+  *
+  * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on
+  *    the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file. 
+  *    When HSE is used as system clock source, directly or through PLL, and you
+  *    are using different crystal you have to adapt the HSE value to your own
+  *    configuration.
+  *        
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32f10x_system
+  * @{
+  */  
+  
+/** @addtogroup STM32F10x_System_Private_Includes
+  * @{
+  */
+
+#include "stm32f10x.h"
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_Defines
+  * @{
+  */
+
+/*!< Uncomment the line corresponding to the desired System clock (SYSCLK)
+   frequency (after reset the HSI is used as SYSCLK source)
+   
+   IMPORTANT NOTE:
+   ============== 
+   1. After each device reset the HSI is used as System clock source.
+
+   2. Please make sure that the selected System clock doesn't exceed your device's
+      maximum frequency.
+      
+   3. If none of the define below is enabled, the HSI is used as System clock
+    source.
+
+   4. The System clock configuration functions provided within this file assume that:
+        - For Low, Medium and High density Value line devices an external 8MHz 
+          crystal is used to drive the System clock.
+        - For Low, Medium and High density devices an external 8MHz crystal is
+          used to drive the System clock.
+        - For Connectivity line devices an external 25MHz crystal is used to drive
+          the System clock.
+     If you are using different crystal you have to adapt those functions accordingly.
+    */
+    
+#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
+/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
+ #define SYSCLK_FREQ_24MHz  24000000
+#else
+/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
+/* #define SYSCLK_FREQ_24MHz  24000000 */ 
+/* #define SYSCLK_FREQ_36MHz  36000000 */
+/* #define SYSCLK_FREQ_48MHz  48000000 */
+/* #define SYSCLK_FREQ_56MHz  56000000 */
+#define SYSCLK_FREQ_72MHz  72000000
+#endif
+
+/*!< Uncomment the following line if you need to use external SRAM mounted
+     on STM3210E-EVAL board (STM32 High density and XL-density devices) or on 
+     STM32100E-EVAL board (STM32 High-density value line devices) as data memory */ 
+#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
+/* #define DATA_IN_ExtSRAM */
+#endif
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */ 
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field. 
+                                  This value must be a multiple of 0x200. */
+
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_Variables
+  * @{
+  */
+
+/*******************************************************************************
+*  Clock Definitions
+*******************************************************************************/
+#ifdef SYSCLK_FREQ_HSE
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */
+#elif defined SYSCLK_FREQ_24MHz
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */
+#elif defined SYSCLK_FREQ_36MHz
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */
+#elif defined SYSCLK_FREQ_48MHz
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */
+#elif defined SYSCLK_FREQ_56MHz
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */
+#elif defined SYSCLK_FREQ_72MHz
+  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */
+#else /*!< HSI Selected as System Clock source */
+  uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */
+#endif
+
+__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_FunctionPrototypes
+  * @{
+  */
+
+static void SetSysClock(void);
+
+#ifdef SYSCLK_FREQ_HSE
+  static void SetSysClockToHSE(void);
+#elif defined SYSCLK_FREQ_24MHz
+  static void SetSysClockTo24(void);
+#elif defined SYSCLK_FREQ_36MHz
+  static void SetSysClockTo36(void);
+#elif defined SYSCLK_FREQ_48MHz
+  static void SetSysClockTo48(void);
+#elif defined SYSCLK_FREQ_56MHz
+  static void SetSysClockTo56(void);  
+#elif defined SYSCLK_FREQ_72MHz
+  static void SetSysClockTo72(void);
+#endif
+
+#ifdef DATA_IN_ExtSRAM
+  static void SystemInit_ExtMemCtl(void); 
+#endif /* DATA_IN_ExtSRAM */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Setup the microcontroller system
+  *         Initialize the Embedded Flash Interface, the PLL and update the 
+  *         SystemCoreClock variable.
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+void SystemInit (void)
+{
+  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
+  /* Set HSION bit */
+  RCC->CR |= (uint32_t)0x00000001;
+
+  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
+#ifndef STM32F10X_CL
+  RCC->CFGR &= (uint32_t)0xF8FF0000;
+#else
+  RCC->CFGR &= (uint32_t)0xF0FF0000;
+#endif /* STM32F10X_CL */   
+  
+  /* Reset HSEON, CSSON and PLLON bits */
+  RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+  /* Reset HSEBYP bit */
+  RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
+  RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+#ifdef STM32F10X_CL
+  /* Reset PLL2ON and PLL3ON bits */
+  RCC->CR &= (uint32_t)0xEBFFFFFF;
+
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x00FF0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;      
+#else
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+#endif /* STM32F10X_CL */
+    
+#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
+  #ifdef DATA_IN_ExtSRAM
+    SystemInit_ExtMemCtl(); 
+  #endif /* DATA_IN_ExtSRAM */
+#endif 
+
+  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
+  /* Configure the Flash Latency cycles and enable prefetch buffer */
+  SetSysClock();
+
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif 
+}
+
+/**
+  * @brief  Update SystemCoreClock variable according to Clock Register Values.
+  *         The SystemCoreClock variable contains the core clock (HCLK), it can
+  *         be used by the user application to setup the SysTick timer or configure
+  *         other parameters.
+  *           
+  * @note   Each time the core clock (HCLK) changes, this function must be called
+  *         to update SystemCoreClock variable value. Otherwise, any configuration
+  *         based on this variable will be incorrect.         
+  *     
+  * @note   - The system frequency computed by this function is not the real 
+  *           frequency in the chip. It is calculated based on the predefined 
+  *           constant and the selected clock source:
+  *             
+  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+  *                                              
+  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+  *                          
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 
+  *             or HSI_VALUE(*) multiplied by the PLL factors.
+  *         
+  *         (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
+  *             8 MHz) but the real value may vary depending on the variations
+  *             in voltage and temperature.   
+  *    
+  *         (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
+  *              8 MHz or 25 MHz, depedning on the product used), user has to ensure
+  *              that HSE_VALUE is same as the real frequency of the crystal used.
+  *              Otherwise, this function may have wrong result.
+  *                
+  *         - The result of this function could be not correct when using fractional
+  *           value for HSE crystal.
+  * @param  None
+  * @retval None
+  */
+void SystemCoreClockUpdate (void)
+{
+  uint32_t tmp = 0, pllmull = 0, pllsource = 0;
+
+#ifdef  STM32F10X_CL
+  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
+#endif /* STM32F10X_CL */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
+  uint32_t prediv1factor = 0;
+#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */
+    
+  /* Get SYSCLK source -------------------------------------------------------*/
+  tmp = RCC->CFGR & RCC_CFGR_SWS;
+  
+  switch (tmp)
+  {
+    case 0x00:  /* HSI used as system clock */
+      SystemCoreClock = HSI_VALUE;
+      break;
+    case 0x04:  /* HSE used as system clock */
+      SystemCoreClock = HSE_VALUE;
+      break;
+    case 0x08:  /* PLL used as system clock */
+
+      /* Get PLL clock source and multiplication factor ----------------------*/
+      pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+      pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+      
+#ifndef STM32F10X_CL      
+      pllmull = ( pllmull >> 18) + 2;
+      
+      if (pllsource == 0x00)
+      {
+        /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {
+ #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
+       prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+       /* HSE oscillator clock selected as PREDIV1 clock entry */
+       SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 
+ #else
+        /* HSE selected as PLL clock entry */
+        if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
+        {/* HSE oscillator clock divided by 2 */
+          SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
+        }
+        else
+        {
+          SystemCoreClock = HSE_VALUE * pllmull;
+        }
+ #endif
+      }
+#else
+      pllmull = pllmull >> 18;
+      
+      if (pllmull != 0x0D)
+      {
+         pllmull += 2;
+      }
+      else
+      { /* PLL multiplication factor = PLL input clock * 6.5 */
+        pllmull = 13 / 2; 
+      }
+            
+      if (pllsource == 0x00)
+      {
+        /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {/* PREDIV1 selected as PLL clock entry */
+        
+        /* Get PREDIV1 clock source and division factor */
+        prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
+        prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+        
+        if (prediv1source == 0)
+        { 
+          /* HSE oscillator clock selected as PREDIV1 clock entry */
+          SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;          
+        }
+        else
+        {/* PLL2 clock selected as PREDIV1 clock entry */
+          
+          /* Get PREDIV2 division factor and PLL2 multiplication factor */
+          prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
+          pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; 
+          SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         
+        }
+      }
+#endif /* STM32F10X_CL */ 
+      break;
+
+    default:
+      SystemCoreClock = HSI_VALUE;
+      break;
+  }
+  
+  /* Compute HCLK clock frequency ----------------*/
+  /* Get HCLK prescaler */
+  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+  /* HCLK clock frequency */
+  SystemCoreClock >>= tmp;  
+}
+
+/**
+  * @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClock(void)
+{
+#ifdef SYSCLK_FREQ_HSE
+  SetSysClockToHSE();
+#elif defined SYSCLK_FREQ_24MHz
+  SetSysClockTo24();
+#elif defined SYSCLK_FREQ_36MHz
+  SetSysClockTo36();
+#elif defined SYSCLK_FREQ_48MHz
+  SetSysClockTo48();
+#elif defined SYSCLK_FREQ_56MHz
+  SetSysClockTo56();  
+#elif defined SYSCLK_FREQ_72MHz
+  SetSysClockTo72();
+#endif
+ 
+ /* If none of the define above is enabled, the HSI is used as System clock
+    source (default after reset) */ 
+}
+
+/**
+  * @brief  Setup the external memory controller. Called in startup_stm32f10x.s 
+  *          before jump to __main
+  * @param  None
+  * @retval None
+  */ 
+#ifdef DATA_IN_ExtSRAM
+/**
+  * @brief  Setup the external memory controller. 
+  *         Called in startup_stm32f10x_xx.s/.c before jump to main.
+  * 	      This function configures the external SRAM mounted on STM3210E-EVAL
+  *         board (STM32 High density devices). This SRAM will be used as program
+  *         data memory (including heap and stack).
+  * @param  None
+  * @retval None
+  */ 
+void SystemInit_ExtMemCtl(void) 
+{
+/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 
+  required, then adjust the Register Addresses */
+
+  /* Enable FSMC clock */
+  RCC->AHBENR = 0x00000114;
+  
+  /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */  
+  RCC->APB2ENR = 0x000001E0;
+  
+/* ---------------  SRAM Data lines, NOE and NWE configuration ---------------*/
+/*----------------  SRAM Address lines configuration -------------------------*/
+/*----------------  NOE and NWE configuration --------------------------------*/  
+/*----------------  NE3 configuration ----------------------------------------*/
+/*----------------  NBL0, NBL1 configuration ---------------------------------*/
+  
+  GPIOD->CRL = 0x44BB44BB;  
+  GPIOD->CRH = 0xBBBBBBBB;
+
+  GPIOE->CRL = 0xB44444BB;  
+  GPIOE->CRH = 0xBBBBBBBB;
+
+  GPIOF->CRL = 0x44BBBBBB;  
+  GPIOF->CRH = 0xBBBB4444;
+
+  GPIOG->CRL = 0x44BBBBBB;  
+  GPIOG->CRH = 0x44444B44;
+   
+/*----------------  FSMC Configuration ---------------------------------------*/  
+/*----------------  Enable FSMC Bank1_SRAM Bank ------------------------------*/
+  
+  FSMC_Bank1->BTCR[4] = 0x00001011;
+  FSMC_Bank1->BTCR[5] = 0x00000200;
+}
+#endif /* DATA_IN_ExtSRAM */
+
+#ifdef SYSCLK_FREQ_HSE
+/**
+  * @brief  Selects HSE as System clock source and configure HCLK, PCLK2
+  *         and PCLK1 prescalers.
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockToHSE(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+
+#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 0 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+
+#ifndef STM32F10X_CL
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
+#else
+    if (HSE_VALUE <= 24000000)
+	{
+      FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
+	}
+	else
+	{
+      FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
+	}
+#endif /* STM32F10X_CL */
+#endif
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
+    
+    /* Select HSE as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;    
+
+    /* Wait till HSE is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  }  
+}
+#elif defined SYSCLK_FREQ_24MHz
+/**
+  * @brief  Sets System clock frequency to 24MHz and configure HCLK, PCLK2 
+  *         and PCLK1 prescalers.
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockTo24(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 0 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;    
+#endif
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
+    
+#ifdef STM32F10X_CL
+    /* Configure PLLs ------------------------------------------------------*/
+    /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ 
+    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
+                            RCC_CFGR_PLLMULL6); 
+
+    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
+    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */       
+    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
+                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
+    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
+                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
+  
+    /* Enable PLL2 */
+    RCC->CR |= RCC_CR_PLL2ON;
+    /* Wait till PLL2 is ready */
+    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
+    {
+    }   
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+    /*  PLL configuration:  = (HSE / 2) * 6 = 24 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6);
+#else    
+    /*  PLL configuration:  = (HSE / 2) * 6 = 24 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6);
+#endif /* STM32F10X_CL */
+
+    /* Enable PLL */
+    RCC->CR |= RCC_CR_PLLON;
+
+    /* Wait till PLL is ready */
+    while((RCC->CR & RCC_CR_PLLRDY) == 0)
+    {
+    }
+
+    /* Select PLL as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
+
+    /* Wait till PLL is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  } 
+}
+#elif defined SYSCLK_FREQ_36MHz
+/**
+  * @brief  Sets System clock frequency to 36MHz and configure HCLK, PCLK2 
+  *         and PCLK1 prescalers. 
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockTo36(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 1 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;    
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
+    
+#ifdef STM32F10X_CL
+    /* Configure PLLs ------------------------------------------------------*/
+    
+    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ 
+    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
+                            RCC_CFGR_PLLMULL9); 
+
+	/*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
+    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
+        
+    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
+                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
+    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
+                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
+  
+    /* Enable PLL2 */
+    RCC->CR |= RCC_CR_PLL2ON;
+    /* Wait till PLL2 is ready */
+    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
+    {
+    }
+    
+#else    
+    /*  PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9);
+#endif /* STM32F10X_CL */
+
+    /* Enable PLL */
+    RCC->CR |= RCC_CR_PLLON;
+
+    /* Wait till PLL is ready */
+    while((RCC->CR & RCC_CR_PLLRDY) == 0)
+    {
+    }
+
+    /* Select PLL as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
+
+    /* Wait till PLL is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  } 
+}
+#elif defined SYSCLK_FREQ_48MHz
+/**
+  * @brief  Sets System clock frequency to 48MHz and configure HCLK, PCLK2 
+  *         and PCLK1 prescalers. 
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockTo48(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 1 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;    
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+    
+#ifdef STM32F10X_CL
+    /* Configure PLLs ------------------------------------------------------*/
+    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
+    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
+        
+    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
+                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
+    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
+                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
+  
+    /* Enable PLL2 */
+    RCC->CR |= RCC_CR_PLL2ON;
+    /* Wait till PLL2 is ready */
+    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
+    {
+    }
+    
+   
+    /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ 
+    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
+                            RCC_CFGR_PLLMULL6); 
+#else    
+    /*  PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
+#endif /* STM32F10X_CL */
+
+    /* Enable PLL */
+    RCC->CR |= RCC_CR_PLLON;
+
+    /* Wait till PLL is ready */
+    while((RCC->CR & RCC_CR_PLLRDY) == 0)
+    {
+    }
+
+    /* Select PLL as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
+
+    /* Wait till PLL is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  } 
+}
+
+#elif defined SYSCLK_FREQ_56MHz
+/**
+  * @brief  Sets System clock frequency to 56MHz and configure HCLK, PCLK2 
+  *         and PCLK1 prescalers. 
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockTo56(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 2 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+
+#ifdef STM32F10X_CL
+    /* Configure PLLs ------------------------------------------------------*/
+    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
+    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
+        
+    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
+                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
+    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
+                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
+  
+    /* Enable PLL2 */
+    RCC->CR |= RCC_CR_PLL2ON;
+    /* Wait till PLL2 is ready */
+    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
+    {
+    }
+    
+   
+    /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ 
+    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
+                            RCC_CFGR_PLLMULL7); 
+#else     
+    /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7);
+
+#endif /* STM32F10X_CL */
+
+    /* Enable PLL */
+    RCC->CR |= RCC_CR_PLLON;
+
+    /* Wait till PLL is ready */
+    while((RCC->CR & RCC_CR_PLLRDY) == 0)
+    {
+    }
+
+    /* Select PLL as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
+
+    /* Wait till PLL is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  } 
+}
+
+#elif defined SYSCLK_FREQ_72MHz
+/**
+  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 
+  *         and PCLK1 prescalers. 
+  * @note   This function should be used only after reset.
+  * @param  None
+  * @retval None
+  */
+static void SetSysClockTo72(void)
+{
+  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+  
+  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
+  /* Enable HSE */    
+  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+ 
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC->CR & RCC_CR_HSERDY;
+    StartUpCounter++;  
+  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+  {
+    HSEStatus = (uint32_t)0x01;
+  }
+  else
+  {
+    HSEStatus = (uint32_t)0x00;
+  }  
+
+  if (HSEStatus == (uint32_t)0x01)
+  {
+    /* Enable Prefetch Buffer */
+    FLASH->ACR |= FLASH_ACR_PRFTBE;
+
+    /* Flash 2 wait state */
+    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
+    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    
+
+ 
+    /* HCLK = SYSCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+      
+    /* PCLK2 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+    
+    /* PCLK1 = HCLK */
+    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+
+#ifdef STM32F10X_CL
+    /* Configure PLLs ------------------------------------------------------*/
+    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
+    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
+        
+    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
+                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
+    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
+                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
+  
+    /* Enable PLL2 */
+    RCC->CR |= RCC_CR_PLL2ON;
+    /* Wait till PLL2 is ready */
+    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
+    {
+    }
+    
+   
+    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
+    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
+                            RCC_CFGR_PLLMULL9); 
+#else    
+    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
+                                        RCC_CFGR_PLLMULL));
+    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
+#endif /* STM32F10X_CL */
+
+    /* Enable PLL */
+    RCC->CR |= RCC_CR_PLLON;
+
+    /* Wait till PLL is ready */
+    while((RCC->CR & RCC_CR_PLLRDY) == 0)
+    {
+    }
+    
+    /* Select PLL as system clock source */
+    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
+
+    /* Wait till PLL is used as system clock source */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
+    {
+    }
+  }
+  else
+  { /* If HSE fails to start-up, the application will have wrong clock 
+         configuration. User can add here some code to deal with this error */
+  }
+}
+#endif
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */    
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmsis_boot/system_stm32f10x.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,98 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32f10x.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32f10x_system
+  * @{
+  */  
+  
+/**
+  * @brief Define to prevent recursive inclusion
+  */
+#ifndef __SYSTEM_STM32F10X_H
+#define __SYSTEM_STM32F10X_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/** @addtogroup STM32F10x_System_Includes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @addtogroup STM32F10x_System_Exported_types
+  * @{
+  */
+
+extern uint32_t SystemCoreClock;          /*!< System Clock Frequency (Core Clock) */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Exported_Constants
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F10x_System_Exported_Functions
+  * @{
+  */
+  
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SYSTEM_STM32F10X_H */
+
+/**
+  * @}
+  */
+  
+/**
+  * @}
+  */  
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/csv/alarm_codes_en_US.csv	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,10 @@
+"Alarm Code in v1.1+"," Alarm Message in v1.0-"," Alarm Description"
+"1","Hard limit","Hard limit has been triggered. Machine position is likely lost due to sudden halt. Re-homing is highly recommended."
+"2","Soft limit","Soft limit alarm. G-code motion target exceeds machine travel. Machine position retained. Alarm may be safely unlocked."
+"3","Abort during cycle","Reset while in motion. Machine position is likely lost due to sudden halt. Re-homing is highly recommended."
+"4","Probe fail","Probe fail. Probe is not in the expected initial state before starting probe cycle when G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered."
+"5","Probe fail","Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4."
+"6","Homing fail","Homing fail. The active homing cycle was reset."
+"7","Homing fail","Homing fail. Safety door was opened during homing cycle."
+"8","Homing fail","Homing fail. Pull off travel failed to clear limit switch. Try increasing pull-off setting or check wiring."
+"9","Homing fail","Homing fail. Could not find limit switch within search distances. Try increasing max travel, decreasing pull-off distance, or check wiring."
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/csv/build_option_codes_en_US.csv	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,21 @@
+"OPT: Code"," Build-Option Description","State"
+"V","Variable spindle","Enabled"
+"N","Line numbers","Enabled"
+"M","Mist coolant M7","Enabled"
+"C","CoreXY","Enabled"
+"P","Parking motion","Enabled"
+"Z","Homing force origin","Enabled"
+"H","Homing single axis commands","Enabled"
+"T","Two limit switches on axis","Enabled"
+"A","Allow feed rate overrides in probe cycles","Enabled"
+"D","Use spindle direction as enable pin","Enabled"
+"0","Spindle enable off when speed is zero","Enabled"
+"S","Software limit pin debouncing","Enabled"
+"R","Parking override control","Enabled"
+"*","Restore all EEPROM command","Disabled"
+"$","Restore EEPROM `$` settings command","Disabled"
+"#","Restore EEPROM parameter data command","Disabled"
+"I","Build info write user string command","Disabled"
+"E","Force sync upon EEPROM write","Disabled"
+"W","Force sync upon work coordinate offset change","Disabled"
+"L","Homing initialization auto-lock","Disabled"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/csv/error_codes_en_US.csv	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,37 @@
+Error Code in v1.1+ ,Error Message in v1.0-, Error Description
+1,Expected command letter,G-code words consist of a letter and a value. Letter was not found.
+2,Bad number format,Missing the expected G-code word value or numeric value format is not valid.
+3,Invalid statement,Grbl '$' system command was not recognized or supported.
+4,Value < 0,Negative value received for an expected positive value.
+5,Setting disabled,Homing cycle failure. Homing is not enabled via settings.
+6,Value < 3 usec,Minimum step pulse time must be greater than 3usec.
+7,EEPROM read fail. Using defaults,An EEPROM read failed. Auto-restoring affected EEPROM to default values.
+8,Not idle,Grbl '$' command cannot be used unless Grbl is IDLE. Ensures smooth operation during a job.
+9,G-code lock,G-code commands are locked out during alarm or jog state.
+10,Homing not enabled,Soft limits cannot be enabled without homing also enabled.
+11,Line overflow,Max characters per line exceeded. Received command line was not executed.
+12,Step rate > 30kHz,Grbl '$' setting value cause the step rate to exceed the maximum supported.
+13,Check Door,Safety door detected as opened and door state initiated.
+14,Line length exceeded,Build info or startup line exceeded EEPROM line length limit. Line not stored.
+15,Travel exceeded,Jog target exceeds machine travel. Jog command has been ignored.
+16,Invalid jog command,Jog command has no '=' or contains prohibited g-code.
+17,Setting disabled,Laser mode requires PWM output.
+20,Unsupported command,Unsupported or invalid g-code command found in block.
+21,Modal group violation,More than one g-code command from same modal group found in block.
+22,Undefined feed rate,Feed rate has not yet been set or is undefined.
+23,Invalid gcode ID:23,G-code command in block requires an integer value.
+24,Invalid gcode ID:24,More than one g-code command that requires axis words found in block.
+25,Invalid gcode ID:25,Repeated g-code word found in block.
+26,Invalid gcode ID:26,No axis words found in block for g-code command or current modal state which requires them.
+27,Invalid gcode ID:27,Line number value is invalid.
+28,Invalid gcode ID:28,G-code command is missing a required value word.
+29,Invalid gcode ID:29,G59.x work coordinate systems are not supported.
+30,Invalid gcode ID:30,G53 only allowed with G0 and G1 motion modes.
+31,Invalid gcode ID:31,Axis words found in block when no command or current modal state uses them.
+32,Invalid gcode ID:32,G2 and G3 arcs require at least one in-plane axis word.
+33,Invalid gcode ID:33,Motion command target is invalid.
+34,Invalid gcode ID:34,Arc radius value is invalid.
+35,Invalid gcode ID:35,G2 and G3 arcs require at least one in-plane offset word.
+36,Invalid gcode ID:36,Unused value words found in block.
+37,Invalid gcode ID:37,G43.1 dynamic tool length offset is not assigned to configured tool length axis.
+38,Invalid gcode ID:38,Tool number greater than max supported value.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/csv/setting_codes_en_US.csv	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,35 @@
+"$-Code"," Setting"," Units"," Setting Description"
+"0","Step pulse time","microseconds","Sets time length per step. Minimum 3usec."
+"1","Step idle delay","milliseconds","Sets a short hold delay when stopping to let dynamics settle before disabling steppers. Value 255 keeps motors enabled with no delay."
+"2","Step pulse invert","mask","Inverts the step signal. Set axis bit to invert (00000ZYX)."
+"3","Step direction invert","mask","Inverts the direction signal. Set axis bit to invert (00000ZYX)."
+"4","Invert step enable pin","boolean","Inverts the stepper driver enable pin signal."
+"5","Invert limit pins","boolean","Inverts the all of the limit input pins."
+"6","Invert probe pin","boolean","Inverts the probe input pin signal."
+"10","Status report options","mask","Alters data included in status reports."
+"11","Junction deviation","millimeters","Sets how fast Grbl travels through consecutive motions. Lower value slows it down."
+"12","Arc tolerance","millimeters","Sets the G2 and G3 arc tracing accuracy based on radial error. Beware: A very small value may effect performance."
+"13","Report in inches","boolean","Enables inch units when returning any position and rate value that is not a settings value."
+"20","Soft limits enable","boolean","Enables soft limits checks within machine travel and sets alarm when exceeded. Requires homing."
+"21","Hard limits enable","boolean","Enables hard limits. Immediately halts motion and throws an alarm when switch is triggered."
+"22","Homing cycle enable","boolean","Enables homing cycle. Requires limit switches on all axes."
+"23","Homing direction invert","mask","Homing searches for a switch in the positive direction. Set axis bit (00000ZYX) to search in negative direction."
+"24","Homing locate feed rate","mm/min","Feed rate to slowly engage limit switch to determine its location accurately."
+"25","Homing search seek rate","mm/min","Seek rate to quickly find the limit switch before the slower locating phase."
+"26","Homing switch debounce delay","milliseconds","Sets a short delay between phases of homing cycle to let a switch debounce."
+"27","Homing switch pull-off distance","millimeters","Retract distance after triggering switch to disengage it. Homing will fail if switch isn't cleared."
+"30","Maximum spindle speed","RPM","Maximum spindle speed. Sets PWM to 100% duty cycle."
+"31","Minimum spindle speed","RPM","Minimum spindle speed. Sets PWM to 0.4% or lowest duty cycle."
+"32","Laser-mode enable","boolean","Enables laser mode. Consecutive G1/2/3 commands will not halt when spindle speed is changed."
+"100","X-axis travel resolution","step/mm","X-axis travel resolution in steps per millimeter."
+"101","Y-axis travel resolution","step/mm","Y-axis travel resolution in steps per millimeter."
+"102","Z-axis travel resolution","step/mm","Z-axis travel resolution in steps per millimeter."
+"110","X-axis maximum rate","mm/min","X-axis maximum rate. Used as G0 rapid rate."
+"111","Y-axis maximum rate","mm/min","Y-axis maximum rate. Used as G0 rapid rate."
+"112","Z-axis maximum rate","mm/min","Z-axis maximum rate. Used as G0 rapid rate."
+"120","X-axis acceleration","mm/sec^2","X-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
+"121","Y-axis acceleration","mm/sec^2","Y-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
+"122","Z-axis acceleration","mm/sec^2","Z-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
+"130","X-axis maximum travel","millimeters","Maximum X-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
+"131","Y-axis maximum travel","millimeters","Maximum Y-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
+"132","Z-axis maximum travel","millimeters","Maximum Z-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v0.7.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,433 @@
+----------------
+Date: 2012-01-17
+Author: Sonny Jeon
+Subject: Update readme.textile
+
+----------------
+Date: 2012-01-17
+Author: Sonny Jeon
+Subject: Merge pull request #47 from chamnit/v0_7
+
+Merging chamnit/v0_7 to grbl/master
+
+----------------
+Date: 2012-01-17
+Author: Sonny Jeon
+Subject: Merge chamnit/v0_7 with grbl/master
+
+
+----------------
+Date: 2012-01-17
+Author: Sonny Jeon
+Subject: Update readme.textile
+
+----------------
+Date: 2012-01-17
+Author: Sonny Jeon
+Subject: Merge pull request #39 from chamnit/edge
+
+Merging chamnit/grbl edge v0.8a to grbl/grbl edge
+
+----------------
+Date: 2012-01-15
+Author: Sonny Jeon
+Subject: Propagated premature step end bug fix from the edge branch. Updated printFloat() function.
+
+- Will not be uploading a hex build of this, unless asked.
+
+
+----------------
+Date: 2012-01-15
+Author: Sonny Jeon
+Subject: Fix bug with premature step end. Refactored _delay_ms() and square() for better portability.
+
+- Fixed a premature step end bug dating back to Simen's 0.7b edge
+version is fixed, from which this code is forked from. Caused by Timer2
+constantly overflowing calling the Step Reset Interrupt every 128usec.
+Now Timer2 is always disabled after a step end and should free up some
+cycles for the main program. Could be more than one way to fix this
+problem. I'm open to suggestions.
+
+- _delay_ms() refactored to accept only constants to comply with
+current compilers. square() removed since not available with some
+compilers.
+
+
+----------------
+Date: 2012-01-10
+Author: Sonny Jeon
+Subject: Extended position reporting with both home and work coordinates. Home position now retained after reset. Other minor changes/fixes.
+
+- Grbl now tracks both home and work (G92) coordinate systems and does
+live updates when G92 is called.
+- Rudimentary home and work position status reporting. Works but still
+under major construction.
+- Updated the main streaming script. Has a disabled periodic timer for
+querying status reports, disabled only because the Python timer doesn't
+consistently restart after the script exits. Add here only for user
+testing.
+- Fixed a bug to prevent an endless serial_write loop during status
+reports.
+- Refactored the planner variables to make it more clear what they are
+and make it easier for clear them.
+
+
+----------------
+Date: 2012-01-09
+Author: Sonny Jeon
+Subject: Corrected a minor streaming script character counting bug.
+
+----------------
+Date: 2012-01-09
+Author: Sonny Jeon
+Subject: Updated line in streaming script.
+
+----------------
+Date: 2012-01-06
+Author: Sonny Jeon
+Subject: Position reporting, refactored system variables, serial print fixes, updated streaming scripts.
+
+- Added machine position reporting to status queries. This will be
+further developed with part positioning/offsets and maintaining
+location upon reset.
+
+- System variables refactored into a global struct for better
+readability.
+
+- Removed old obsolete Ruby streaming scripts. These were no longer
+compatible. Updated Python streaming scripts.
+
+- Fixed printFloat() and other printing functions.
+
+- Decreased planner buffer back to 18 blocks and increased TX serial
+buffer to 64 bytes. Need the memory space for future developments.
+
+- Begun adding run-time modes to grbl, where block delete toggle, mm/in
+reporting modes, jog modes, etc can be set during runtime. Will be
+fleshed out and placed into EEPROM when everything is added.
+
+
+----------------
+Date: 2011-12-10
+Author: Sonny Jeon
+Subject: Various minor updates and variable definition corrections. Removed deprecated acceleration manager.
+
+- Removed deprecated acceleration manager (non-functional since v0.7b)
+- Updated variable types and function headers. - Updated stepper
+interrupt to ISR() from SIGNAL()+sei(). - General code cleanup.
+
+
+----------------
+Date: 2011-12-08
+Author: Sonny Jeon
+Subject: Initial v0.8 ALPHA commit. Features multi-tasking run-time command execution (feed hold, cycle start, reset, status query). Extensive re-structuring of code for future features.
+
+- ALPHA status. - Multitasking ability with run-time command executions
+for real-time control and feedback. - Decelerating feed hold and resume
+during operation. - System abort/reset, which immediately kills all
+movement and re-initializes grbl. - Re-structured grbl to easily allow
+for new features: Status reporting, jogging, backlash compensation. (To
+be completed in the following releases.) - Resized TX/RX serial buffers
+(32/128 bytes) - Increased planner buffer size to 20 blocks. - Updated
+documentation.
+
+
+----------------
+Date: 2011-11-19
+Author: Sonny Jeon
+Subject: Updated README and reordered branch versions.
+
+
+----------------
+Date: 2011-11-19
+Author: Sonny Jeon
+Subject: Re-ordered stepper idle function to first disable interrupt.
+
+----------------
+Date: 2011-11-11
+Author: Sonny Jeon
+Subject: Corrected clearing of target and position variable for the go home routine. Thanks Jens!
+
+----------------
+Date: 2011-10-11
+Author: Sonny Jeon
+Subject: Delete a new work file shouldn't have been synced.
+
+
+----------------
+Date: 2011-10-11
+Author: Sonny Jeon
+Subject: Third time's a charm! No more deceleration issues! Updated grbl version and settings. General cleanup.
+
+- Fleshed out the original idea to completely remove the long slope at
+the end of deceleration issue. This third time should absolutely
+eliminate it.
+- Changed the acceleration setting to kept as mm/min^2 internally,
+since this was creating unneccessary additional computation in the
+planner. Human readable value kept at mm/sec^2.
+- Updated grbl version 0.7d and settings version to 4. NOTE: Please
+check settings after update. These may have changed, but shouldn't.
+- Before updating the new features (pause, e-stop, federate override,
+etc), the edge branch will soon be merged with the master, barring any
+immediate issues that people may have, and the edge branch will be the
+testing ground for the new grbl version 0.8.
+
+
+----------------
+Date: 2011-10-07
+Author: Sonny Jeon
+Subject: Forgot something! Comments on what the last change does.
+
+
+----------------
+Date: 2011-10-06
+Author: Sonny Jeon
+Subject: Minor update to further eliminate the ole long slope deceleration issue. New update note!
+
+- Added another way to further ensure the long slope deceleration issue
+is eliminated. If the stepper rate change is too great near zero, the
+stepper rate is adjusted at half increments to the end of travel,
+creating a smooth transition. - If the new STEPPER_IDLE_LOCK_TIME is
+set as zero, this delay is not compiled at compile-time. - NOTE: The
+next update is likely going to be major, involving a full re-write of
+the stepper.c program to integrate a simple way to apply pauses,
+jogging, e-stop, and feedrate overrides. The interface should be
+flexible enough to be easily modified for use with either hardware
+switches or software commands. Coming soon.
+
+
+----------------
+Date: 2011-09-29
+Author: Sonny Jeon
+Subject: Added complete stop delay at the end of all motion. Moved grbl preprocessor script into a new repository.
+
+Added a very short (25 ms) user-definable delay before the steppers are
+disabled at the motors are disabled and grbl goes idle. This ensures
+any residual inertia at the end of the last motion does not cause the
+axes to drift and grbl to lose its position when manually entering
+g-code or when performing a tool change and starting the next
+operation.
+
+
+----------------
+Date: 2011-09-25
+Author: Sonny Jeon
+Subject: Updated some comments and fixed a bug in the new stepper logic.
+
+- The stepper logic was not initiating the decelerations for certain
+cases. Just re-arranged the logic to fix it.
+
+
+----------------
+Date: 2011-09-24
+Author: Sonny Jeon
+Subject: Fixed long slope at deceleration issue. Moved things into config.h. New MINIMUM_PLANNER_SPEED parameter.
+
+- The long standing issue of a long slope at deceleration is likely
+fixed. The stepper program was not tracking and timing the end of
+acceleration and start of deceleration exactly and now is fixed to
+start and stop on time. Also, to ensure a better acceleration curve fit
+used by the planner, the stepper program delays the start of the
+accelerations by a half trapezoid tick to employ the midpoint rule. -
+Settings version 3 migration (not fully tested, but should work) -
+Added a MINIMUM_PLANNER_SPEED user-defined parameter to planner to let
+a user change this if problems arise for some reason. - Moved all
+user-definable #define parameters into config.h with clear comments on
+what they do and recommendations of how to change them. - Minor
+housekeeping.
+
+
+----------------
+Date: 2011-09-18
+Author: Sonny J
+Subject: Fixed minor bugs in planner. Increased max dwell time. Long slope bug stop-gap solution note.
+
+- Fixed the planner TODO regarding minimum nominal speeds. Re-arranged
+calculations to be both more efficient and guaranteed to be greater
+than zero. - Missed a parenthesis location on the rate_delta
+calculation. Should fix a nearly in-perceptible issue with incorrect
+acceleration ramping in diagonal directions. - Increased maximum dwell
+time from 6.5sec to an 18hour max. A crazy amount more, but that's how
+the math works out. - Converted the internal feedrate values to mm/min
+only, as it was switching between mm/min to mm/sec and back to mm/min.
+Also added a feedrate > 0 check in gcode.c. - Identified the long slope
+at the end of rapid de/ac-celerations noted by stephanix. Problem with
+the numerical integration truncation error between the exact solution
+of estimate_acceleration_distance and how grbl actually performs the
+acceleration ramps discretely. Increasing the
+ACCELERATION_TICKS_PER_SECOND in config.h helps fix this problem.
+Investigating further.
+
+
+----------------
+Date: 2011-09-15
+Author: Sonny J
+Subject: More '%' modulo opertor removals and some housecleaning.
+
+- Serial functions contained quite a few modulo operations that would
+be executed with high frequency when streaming. AVR processors are very
+slow when operating these. In one test on the Arduino forums, it showed
+about a 15x slow down compared to a simple if-then statement. -
+Clarified some variable names and types and comments.
+
+
+----------------
+Date: 2011-09-13
+Author: Sonny J
+Subject: Further planner improvements and misc minor bug fixes. Memory savings and increased buffer size.
+
+- Update grbl version and settings version to automatically reset
+eeprom. FYI, this will reset your grbl settings. - Saved
+3*BLOCK_BUFFER_SIZE doubles in static memory by removing obsolete
+variables: speed_x, speed_y, and speed_z. - Increased buffer size
+conservatively to 18 from 16. (Probably can do 20). - Removed expensive!
+modulo operator from block indexing function. Reduces significant
+computational overhead. - Re-organized some sqrt() calls to be more
+efficient during time critical planning cases, rather than non-time
+critical. - Minor bug fix in planner max junction velocity logic. -
+Simplified arc logic and removed need to multiply for CW or CCW
+direction.
+
+
+----------------
+Date: 2011-09-06
+Author: Sonny J
+Subject: Optimized planner re-write. Significantly faster. Full arc support enabled by rotation matrix approach.
+
+- Significant improvements in the planner. Removed or reordered
+repetitive and expensive calculations by order of importance:
+recalculating unchanged blocks, trig functions [sin(), cos(), tan()],
+sqrt(), divides, and multiplications. Blocks long enough for nominal
+speed to be guaranteed to be reached ignored by planner. Done by
+introducing two uint8_t flags per block. Reduced computational overhead
+by an order of magnitude.   - Arc motion generation completely
+re-written and optimized. Now runs with acceleration planner. Removed
+all but one trig function (atan2) from initialization. Streamlined
+computations. Segment target locations generated by vector
+transformation and small angle approximation. Arc path correction
+implemented for accumulated error of approximation and single precision
+calculation of Arduino. Bug fix in message passing.
+
+
+----------------
+Date: 2011-09-04
+Author: Sonny J
+Subject: Minor update for memory savings in ring buffer and fleshed out commenting.
+
+No changes in functionality. Path vectors moved from ring buffer to
+local planner static variables to save 3*(BUFFER_SIZE - 1) doubles in
+memory. Detailed comments. Really need to stop micro-updating. Should be
+the last until a planner optimization (ala Jens Geisler) has been
+completed.
+
+
+----------------
+Date: 2011-09-04
+Author: Sonny J
+Subject: More minor bug fixes in planner.
+
+Reverse planner was over-writing the initial/buffer tail entry speed,
+which reset the forward planner and caused it to lose track of its
+speed. Should now accelerate into short linear segments much nicer now.
+
+
+----------------
+Date: 2011-09-03
+Author: Sonny J
+Subject: Minor bug fixes in planner.
+
+
+----------------
+Date: 2011-09-03
+Author: Sonny J
+Subject: Add G02/03 arc conversion/pre-processor script and example streaming script
+
+Beta pre-processor script used to clean and streamline g-code for
+streaming and converts G02/03 arcs into linear segments. Allows for full
+acceleration support if the pre-processed g-code is then streamed to
+grill, sans G02/03 arcs. Added a simple example streaming script for
+Python users.
+
+
+----------------
+Date: 2011-09-03
+Author: Sonny J
+Subject: Significantly improved junction control and fixed computation bugs in planner
+
+- Junction jerk now re-defined as junction_deviation. The distance from
+the junction to the edge of a circle tangent to both previous and
+current path lines. The circle radii is used to compute the maximum
+junction velocity by centripetal acceleration. More robust and
+simplified way to compute jerk.   - Fixed bugs related to entry and exit
+factors. They were computed based on the current nominal speeds but not
+when computing exit factors for neighboring blocks. Removed factors and
+replaced with entry speeds only. Factors now only computed for stepper
+trapezoid rate conversions.  - Misc: Added min(), next_block_index,
+prev_block_index functions for clarity.
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Moved comment and block delete handling into protocol.c from gcode.c. Fixes bug when comment and block delete are not isolated. Blank lines ignored.
+
+Comments, block delete characters, and blank lines are no longer passed
+to the gcode parser and should free up some memory by ignoring these
+characters. Gcode parser now expects clean gcode only. There was a bug
+if there were block deletes or comments not in the first character (i.e.
+spindle on/off for proofing geode without turning it on, or a NXX
+followed by a comment). This should fix it by bypassing the problem.
+Left a commented line for easily turning on and off block deletes for a
+later feature, if desired.
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Revert ea5b8942db2616e93fc0478922010c3bab7c0481^..HEAD
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Moved comment and block delete handling into protocol.c from gcode.c. Fixes bug when comment and block delete are not isolated. Blank lines ignored.
+
+Comments, block delete characters, and blank lines are no longer passed
+to the gcode parser and should free up some memory by ignoring these
+characters. Gcode parser now expects clean gcode only. There was a bug
+if there were block deletes or comments not in the first character (i.e.
+spindle on/off for proofing geode without turning it on, or a NXX
+followed by a comment). This should fix it by bypassing the problem.
+Left a commented line for easily turning on and off block deletes for a
+later feature, if desired.
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Revert 517a0f659a06182c89cafe27ee371edccad777a4^..HEAD
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Revert "Moved comment and block delete handling to be done in protocol.c rather than gcode.c. Prevents these from being held in memory. Also, fixes bug when comments and block delete character are mixed with g-code."
+
+This reverts commit ea5b8942db2616e93fc0478922010c3bab7c0481.
+
+
+----------------
+Date: 2011-08-15
+Author: Sonny J
+Subject: Revert fdc90f1821f1f5edb7756fcddce75b4b4fbf6bbf^..HEAD
+
+
+----------------
+Date: 2011-08-15
+Author: chamnit
+Subject: Removed comment and block delete handling from gcode.c. Parser expects clean gcode.
+
+----------------
+Date: 2011-08-15
+Author: chamnit
+Subject: Moved comment and block delete handling to be done in protocol.c rather than gcode.c. Prevents these from being held in memory. Also, fixes bug when comments and block delete character are mixed with g-code.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v0.8c.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,831 @@
+----------------
+Date: 2012-11-25
+Author: Sonny Jeon
+Subject: G28/G30 post move bug fix. Altered file permissions.
+
+
+----------------
+Date: 2012-11-25
+Author: Sonny Jeon
+Subject: G28/G30 post move bug fix.
+
+- Fixed a bug when after moving to a pre-defined position G28/G30, the
+next move would go someplace unexpected. The g-code parser position
+vector wasn't getting updated.
+
+
+----------------
+Date: 2012-11-20
+Author: Sonny Jeon
+Subject: Merge error fix.
+
+
+----------------
+Date: 2012-11-20
+Author: Sonny Jeon
+Subject: Merge v0.8 edge to master
+
+
+----------------
+Date: 2012-11-19
+Author: Sonny Jeon
+Subject: Updated interface protocol. Fixed M2 bug.
+
+- Updated interface protocol to play nicer with interface programs. All
+Grbl responses beginning with '$' signifies a setting. Bracketed '[]'
+responses are feedback messages containing either state, parameter, or
+general messages. Chevron '<>' response are from the real-time status
+messages, i.e. position.
+
+- M2 Program end command was causing a system alarm. Fixed. Thanks
+@blinkenlight !
+
+
+----------------
+Date: 2012-11-18
+Author: Sonny Jeon
+Subject: Updated readme
+
+
+----------------
+Date: 2012-11-18
+Author: Sonny Jeon
+Subject: Homing search sequence now compile-time option. New defaults.h file. Tidying up.
+
+- The homing sequence is now a compile-time option, where a user can
+choose which axes(s) move in sequence during the search phase. Up to 3
+sequences. Works with the locating phase and the pull-off maneuver.
+
+- New defaults.h file to store user generated default settings for
+different machines. Mainly to be used as a central repo, but each set
+may be select to be compiled in as a config.h define.
+
+
+----------------
+Date: 2012-11-15
+Author: Sonny Jeon
+Subject: Added Grbl state in status report. Removed switch support.
+
+- Added Grbl state (Idle, Running, Queued, Hold, etc) to the real-time
+status reporting feature as feedback to the user of what Grbl is doing.
+Updated the help message to reflect this change.
+
+- Removed switches (dry run, block delete, single block mode). To keep
+Grbl simple and not muddled up from things that can easily be taken
+care of by an external interface, these were removed.
+
+- Check g-code mode was retained, but the command was moved to '$C'
+from '$S0'.
+
+
+----------------
+Date: 2012-11-14
+Author: Sonny Jeon
+Subject: Re-factored system states and alarm management. Serial baud support greater than 57600.
+
+- Refactored system states to be more clear and concise. Alarm locks
+processes when position is unknown to indicate to user something has
+gone wrong.
+
+- Changed mc_alarm to mc_reset, which now manages the system reset
+function. Centralizes it.
+
+- Renamed '$X' kill homing lock to kill alarm lock.
+
+- Created an alarm error reporting method to clear up what is an alarm:
+message vs a status error: message. For GUIs mainly. Alarm codes are
+negative. Status codes are positive.
+
+- Serial baud support upto 115200. Previous baudrate calc was unstable
+for 57600 and above.
+
+- Alarm state locks out all g-code blocks, including startup scripts,
+but allows user to access settings and internal commands. For example,
+to disable hard limits, if they are problematic.
+
+- Hard limits do not respond in an alarm state.
+
+- Fixed a problem with the hard limit interrupt during the homing
+cycle. The interrupt register is still active during the homing cycle
+and still signal the interrupt to trigger when re-enabled. Instead,
+just disabled the register.
+
+- Homing rate adjusted. All axes move at homing seek rate, regardless
+of how many axes move at the same time. This is unlike how the stepper
+module does it as a point to point rate.
+
+- New config.h settings to disable the homing rate adjustment and the
+force homing upon powerup.
+
+- Reduced the number of startup lines back down to 2 from 3. This
+discourages users from placing motion block in there, which can be very
+dangerous.
+
+- Startup blocks now run only after an alarm-free reset or after a
+homing cycle. Does not run when $X kill is called. For satefy reasons
+
+
+----------------
+Date: 2012-11-10
+Author: Sonny Jeon
+Subject: Tweaks. Seek rate updates when set. CCW arc full circle fix.
+
+- Fixed a minor issue where the seek rates would not immediately be
+used and only would after a reset. Should update live now.
+
+- A full circle IJ offset CCW arc would not do anything. Fixed bug via
+a simple if-then statement.
+
+- Radius mode tweaks to check for negative value in sqrt() rather than
+isnan() it. Error report updated to indicate what actually happened.
+
+
+----------------
+Date: 2012-11-09
+Author: Sonny Jeon
+Subject: Added note that D13 can't be used as input, pulled-high.
+
+
+----------------
+Date: 2012-11-09
+Author: Sonny Jeon
+Subject: Fixed homing cycle hanging after locating switches.
+
+
+----------------
+Date: 2012-11-08
+Author: Sonny Jeon
+Subject: Housekeeping.
+
+- Added some more notes to config.h.
+
+- Added the ability to override some of the #defines around Grbl in
+config.h, like planner buffer size, line buffer size, serial
+send/receive buffers. Mainly to centralize the configurations to be
+able to port to different microcontrollers later.
+
+
+----------------
+Date: 2012-11-08
+Author: Sonny Jeon
+Subject: Sanguino compile patch
+
+@daapp : Sanguino compile serial USART path. Thanks!
+
+
+----------------
+Date: 2012-11-07
+Author: Sonny Jeon
+Subject: More tweaks. Removed dry run. Trimmed all messages to save flash space.
+
+- Removed the dry run switch. It was getting overly complicated for
+what it needed to do. In practice, single block mode and feed rate
+overrides (coming in next release) does a much better job with dry runs
+than 'dry run'.
+
+- Trimmed all of Grbl's messages from help, status, feedback to
+settings. Saved 0.6KB+ of flash space that could be used for v0.9
+features.
+
+- Removed some settings inits when set. Will depend on user to power
+cycle to get some of these to reload.
+
+- Fixed a bug with settings version not re-writing old settings, when
+it should. Thanks Alden!
+
+
+----------------
+Date: 2012-11-06
+Author: Sonny Jeon
+Subject: Merge pull request #132 from hin/header_dependencies
+
+Header dependencies
+
+----------------
+Date: 2012-11-05
+Author: Sonny Jeon
+Subject: Tweaks and bug fixes. Increase to 3 startup blocks. Remove purge/added unlock command
+
+- Increased the number of startup blocks to 3 for no good reason other
+than it doesn't increase the flash size.
+
+- Removed the purge buffer command and replaced with an disable homing
+lock command.
+
+- Homing now blocks all g-code commands (not system commands) until the
+homing cycle has been performed or the disable homing lock is sent.
+Homing is required upon startup or if Grbl loses it position. This is
+for safety reasons.
+
+- Cleaned up some of the Grbl states and re-organized it to be little
+more cohesive.
+
+- Cleaned up the feedback and status messages to not use so much flash
+space, as it's a premium now.
+
+ - Check g-code and dry run switches how are mutually exclusive and
+can't be enabled when the other is. And automatically resets Grbl when
+disabled.
+
+- Some bug fixes and other minor tweaks.
+
+
+----------------
+Date: 2012-11-05
+Author: Hans Insulander
+Subject: Ignore dependency files
+
+
+----------------
+Date: 2012-11-05
+Author: Hans Insulander
+Subject: Generate header dependencies and use them in Makefile
+
+
+----------------
+Date: 2012-11-05
+Author: Sonny Jeon
+Subject: Tweaked dry run and check g-code switches. Now resets when toggled off.
+
+- To make managing the code easier and to help ensure a user starts
+with a fresh reset, the functionality of check g-code and dry run has
+been changed to automatically perform a soft reset when toggled off.
+Position will not be lost, unless there is a cycle active. Feed hold
+before toggling off it needed.
+
+This is mainly a safety issue. If a user dry runs a program and kills
+it mid-program, and then restarts it thinking to run it as normal, the
+g-code modes that we're set may not be what they expect, and very bad
+things can happen.
+
+- NOTE: Grbl is at 83.5% of flash capacity. Not a lot of room left, but
+I think we can squeeze in some more!
+
+
+----------------
+Date: 2012-11-04
+Author: Sonny Jeon
+Subject: Runtime command pinned out! Re-organized coolant pins.
+
+- Pinned out cycle start(A2), feed hold(A1), and reset(A0) runtime
+commands. These pins are held high with the internal pull-up resistor
+enabled. All you have to do is connect a normally-open switch to the
+pin and ground. That's it.
+
+- Moved the coolant control pins to A3 (and the optional mist control
+to A4).
+
+- Moved all of the MASK defines into the config.h file to centralize
+them.
+
+
+----------------
+Date: 2012-11-04
+Author: Sonny Jeon
+Subject: Tweaks and minor bug fixes. Added purge buffer command.
+
+- Added a purge buffer (and lock) command. This is an advanced option
+to clear any queued blocks in the buffer in the event of system
+position being lost or homed. These queued blocks will likely not move
+correctly if not purged. In typical use, the purging command releases
+the homing axes lock in case a user need to move the axes off their
+hard limit switches, but position is not guaranteed. Homing is advised
+immediately after.
+
+- Created a system-wide sync current position function. Cleans up some
+of the repetitive tasks in various places in the code that do the same
+thing.
+
+- Removed the clear all switches command '$S'. Not really needed and
+helped clean up a sync call.
+
+- Other minor tweaks. Readme updated slightly..
+
+
+----------------
+Date: 2012-11-03
+Author: Sonny Jeon
+Subject: New startup script setting. New dry run, check gcode switches. New system state variable. Lots of reorganizing.
+
+(All v0.8 features installed. Still likely buggy, but now thourough
+testing will need to start to squash them all. As soon as we're done,
+this will be pushed to master and v0.9 development will be started.
+Please report ANY issues to us so we can get this rolled out ASAP.)
+
+- User startup script! A user can now save one (up to 5 as compile-time
+option) block of g-code in EEPROM memory. This will be run everytime
+Grbl resets. Mainly to be used as a way to set your preferences, like
+G21, G54, etc.
+
+- New dry run and check g-code switches. Dry run moves ALL motions at
+rapids rate ignoring spindle, coolant, and dwell commands. For rapid
+physical proofing of your code. The check g-code switch ignores all
+motion and provides the user a way to check if there are any errors in
+their program that Grbl may not like.
+
+- Program restart! (sort of). Program restart is typically an advanced
+feature that allows users to restart a program mid-stream. The check
+g-code switch can perform this feature by enabling the switch at the
+start of the program, and disabling it at the desired point with some
+minimal changes.
+
+- New system state variable. This state variable tracks all of the
+different state processes that Grbl performs, i.e. cycle start, feed
+hold, homing, etc. This is mainly for making managing of these task
+easier and more clear.
+
+- Position lost state variable. Only when homing is enabled, Grbl will
+refuse to move until homing is completed and position is known. This is
+mainly for safety. Otherwise, it will let users fend for themselves.
+
+- Moved the default settings defines into config.h. The plan is to
+eventually create a set of config.h's for particular as-built machines
+to help users from doing it themselves.
+
+- Moved around misc defines into .h files. And lots of other little
+things.
+
+
+----------------
+Date: 2012-11-01
+Author: Sonny Jeon
+Subject: Added block delete, opt stop, single block mode. New parser state and parameter feedback. Overhauled '$' command.
+
+NOTE: Another incremental update. Likely buggy, still a ways to go
+before everything is installed, such as startup blocks.
+
+- Changed the '$' command to print help. '$$' now prints Grbl settings.
+The help now instructs the user of runtime commands, switch toggling,
+homing, etc. Jogging will be added to these in v0.9.
+
+- Added switches: block delete, opt stop, and single block mode.
+
+- Now can print the g-code parser state and persistent parameters
+(coord sys) to view what Grbl has internally.
+
+- Made the gc struct in the g-code parser global to be able to print
+the states. Also moved coordinate system tracking from sys to gc struct.
+
+- Changed up the welcome flag and updated version to v0.8c.
+
+- Removed spindle speed from gcode parser. Not used.
+
+
+----------------
+Date: 2012-11-01
+Author: Sonny Jeon
+Subject: New report module. 6 persistent work coordinates. New G-codes and settings. README and minor bug updates
+
+(NOTE: This push is likely buggy so proceed with caution. Just
+uploading to let people know where we're going.)
+
+- New report.c module. Moved all feedback functions into this module to
+centralize these processes. Includes realtime status reports, status
+messages, feedback messages.
+
+- Official support 6 work coordinate systems (G54-G59), which are
+persistently held in EEPROM memory.
+
+- New g-code support: G28.1, G30.1 stores current machine position as a
+home position into EEPROM. G10 L20 Px stores current machine position
+into work coordinates without needing to explicitly send XYZ words.
+
+- Homing performed with '$H' command. G28/G30 no longer start the
+homing cycle. This is how it's supposed to be.
+
+- New settings: Stepper enable invert and n_arc correction installed.
+
+- Updated and changed up some limits and homing functionality. Pull-off
+travel will now move after the homing cycle regardless of hard limits
+enabled. Fixed direction of pull-off travel (went wrong way).
+
+- Started on designing an internal Grbl command protocol based on the
+'$' settings letter. Commands with non numeric characters after '$'
+will perform switch commands, homing cycle, jogging, printing
+paramters, etc. Much more to do here.
+
+- Updated README to reflect all of the new features.
+
+
+----------------
+Date: 2012-10-21
+Author: Sonny Jeon
+Subject: Added misc message to indicate how to exit ALARM mode.
+
+
+----------------
+Date: 2012-10-21
+Author: Sonny Jeon
+Subject: New alarm method. Re(re)organized status messages.
+
+- Installed a new 'alarm' method to centralize motion kills across
+alarm or reset events. Right now, this is controlled by system abort
+and hard limits. But, in the future, a g-code parser error may call
+this too as a safety feature.
+
+- Re(re)organized status messages to just print all errors, regardless
+from where it was called. This centralizes them into one place.
+
+- Misc messages method installed for any user feedback that is not a
+confirmation or error. Mainly so that there is a place to perform
+warnings and such.
+
+- New stuff installed and still made the flash size smaller by saving
+flash space from clearing out repeated '\r\n' pgmstrings.
+
+- Fixed a bug where hard limits message would print everytime a system
+abort was sent.
+
+
+----------------
+Date: 2012-10-21
+Author: Sonny Jeon
+Subject: Re-organized status messages to be more coherent and centralized.
+
+- Reorganized all of the status message feedback from both the g-code
+parser and settings modules to be centralized into two message modules:
+status feedback from executing a line and warnings for misc feedback.
+
+- Pulled out the printPgmString() messages in settings.c and placed it
+into the new module. (settings_dump() not moved).
+
+- Some other minor edits. Renaming defines, comment updates, etc.
+
+
+----------------
+Date: 2012-10-18
+Author: Sonny Jeon
+Subject: Hard limits code minor updates.
+
+- Fixed a bug that would not disable the steppers if a user issues a
+system abort during a homing cycle.
+
+- Updated the hard limit interrupt to be more correct and to issue a
+shutdown for the right situations when the switch has been triggered.
+
+- Added a status message to indicate to the user what happened and what
+to do upon a hard limit trigger.
+
+
+----------------
+Date: 2012-10-16
+Author: Sonny Jeon
+Subject: Hard limits, homing direction, pull-off limits after homing, status reports in mm or inches, system alarm, and more.
+
+- Thank you statement added for Alden Hart of Synthetos.
+
+- Hard limits option added, which also works with homing by pulling off
+the switches to help prevent unintended triggering. Hard limits use a
+interrupt to sense a falling edge pin change and immediately go into
+alarm mode, which stops everything and forces the user to issue a reset
+(Ctrl-x) or reboot.
+
+- Auto cycle start now a configuration option.
+
+- Alarm mode: A new method to kill all Grbl processes in the event of
+something catastrophic or potentially catastropic. Just works with hard
+limits for now, but will be expanded to include g-code errors (most
+likely) and other events.
+
+- Updated status reports to be configurable in inches or mm mode. Much
+more to do here, but this is the first step.
+
+- New settings: auto cycle start, hard limit enable, homing direction
+mask (which works the same as the stepper mask), homing pulloff
+distance (or distance traveled from homed machine zero to prevent
+accidental limit trip).
+
+- Minor memory liberation and calculation speed ups.
+
+
+----------------
+Date: 2012-10-13
+Author: Sonny Jeon
+Subject: Minor updates, improvements, and bug fixes.
+
+- Allowed status_message function to be called by others. This is to
+centralize all feedback into protocol.c.
+
+- Fixed a bug where line number words 'N' were causing the parser to
+error out.
+
+- Allowed homing routine feed rates to move slower than the
+MINIMUM_STEP_RATE parameter in config.h.
+
+- Homing performs idle lock at the end of the routine.
+
+- Stepper idle lock time will now not disable the steppers when the
+value is set at 255. This is accomodate users who prefer to keep their
+axes enabled at all times.
+
+- Moved some defines around to where they need to be.
+
+
+----------------
+Date: 2012-10-12
+Author: Sonny Jeon
+Subject: Updated delay_us() function to accept long integers
+
+
+----------------
+Date: 2012-10-11
+Author: Sonny Jeon
+Subject: (2x) speed increase in printFloat() function. Decimal places setting added.
+
+- printFloat() function execution doubled in speed. This is a precursor
+to status reporting, since GUIs may query real-time position rapidly.
+
+- Decimal places added to settings (for now). This may disappear in
+future pushes, but here for testing purposes.
+
+
+----------------
+Date: 2012-10-11
+Author: Sonny Jeon
+Subject: Homing stepper enable bit fix.
+
+
+----------------
+Date: 2012-10-10
+Author: Sonny Jeon
+Subject: Homing direction pin bits fixed. Lite refactoring of settings.
+
+
+----------------
+Date: 2012-10-09
+Author: Sonny Jeon
+Subject: Improved homing cycle. New settings: homing enable/rates, debounce and step idle lock time.
+
+- Homing cycle will now cycle twice (spec more/less in config) to
+improve repeatability and accuracy by decreasing overshoot.
+
+- New Grbl settings added: Enable/disable homing cycles, homing seek
+and feed rates, switch debounce delay, and stepper idle lock time.
+
+- Please note that these settings may change upon the next push, since
+there will be more added soon. Grbl *should* not re-write your old
+settings, just re-write the new ones. So, make sure you keep these
+written down somewhere in case they get lost from a code bug.
+
+- Refactored settings migration to be a little smaller and managable
+going forward.
+
+
+----------------
+Date: 2012-10-08
+Author: Sonny Jeon
+Subject: Fixed an issue with leaving the limit switches during a homing cycle.
+
+
+----------------
+Date: 2012-10-08
+Author: Sonny Jeon
+Subject: Updated version number to v0.8b to reflect changes.
+
+
+----------------
+Date: 2012-10-08
+Author: Sonny Jeon
+Subject: Limit pin internal pull-resistors enabled. Re-wrote read_double() function. Correctly changed all 'double's to 'float's.
+
+- Limit pin internal pull-resistors now enabled. Normal high operation.
+This will be the standard going forward.
+
+- Updated all of the 'double' variable types to 'float' to reflect what
+happens when compiled for the Arduino. Also done for compatibility
+reasons to @jgeisler0303 's Grbl simulator code.
+
+- G-code parser will now ignore 'E' exponent values, since they are
+reserved g-code characters for some machines. Thanks @csdexter!
+
+- The read_double() function was re-written and optimized for use in
+Grbl. The strtod() avr lib was removed.
+
+
+----------------
+Date: 2012-09-30
+Author: Sonny Jeon
+Subject: Updated limit/homing routine. Works, but needs more TLC.
+
+- Added acceleration to the homing routine.
+
+- Homing now accounts for different step rates when moving multiple
+axes without exceeding acceleration limits.
+
+- Homing now updates all internal positioning variables to machine zero
+after completion.
+
+- "Poor-man's" debounce delay added.
+
+- Updated the delay_us() function to perform faster and more accurate
+microsecond delays. Previously, the single increments would add
+noticeable time drift for larger delays.
+
+- Fix a bug in the stepper.c prescalar calculations that was changed in
+the last commit.
+
+- Other minor fixes.
+
+
+----------------
+Date: 2012-09-21
+Author: Sonny Jeon
+Subject: Minor prescalar optimization. Changed up some defines.
+
+
+----------------
+Date: 2012-09-21
+Author: Sonny Jeon
+Subject: Added coolant control (M7*, M8, M9). Mist control can be enabled via config.h.
+
+- Added coolant control! Flood control (M8) functions on analog pin 0.
+Mist control (M7) is compile-time optional and is on analog pin 1. (Use
+only if you have multiple coolants on your system). Based on work by
+@openpnp.
+
+- Fixed some variable assignments in spindle control.
+
+
+----------------
+Date: 2012-09-21
+Author: Sonny Jeon
+Subject: Merge pull request #120 from tmpvar/configurable-makefile
+
+Add support for overriding DEVICE and PROGRAMMER
+
+----------------
+Date: 2012-09-21
+Author: Elijah Insua
+Subject: Add support for overriding DEVICE and PROGRAMMER
+
+By setting environment variables.
+
+example: PROGRAMMER=-c arduino -P /dev/tty.usbmodemfa131 make flash
+
+
+----------------
+Date: 2012-09-19
+Author: Sonny Jeon
+Subject: M30 minor bug fix.
+
+Order of operations was off. Now works as intended,
+
+
+----------------
+Date: 2012-06-27
+Author: Sonny Jeon
+Subject: No changes. Github commit bug.
+
+
+----------------
+Date: 2012-06-26
+Author: Sonny Jeon
+Subject: Added step pulse delay after direction set (Compile-time option only). Updated read me.
+
+Added a compile-time only experimental feature that creates a
+user-specified time delay between a step pulse and a direction pin set
+(in config.h). This is for users with hardware-specific issues
+(opto-couplers) that need more than a few microseconds between events,
+which can lead to slowly progressing step drift after many many
+direction changes. We suggest to try the hack/fix posted in the Wiki
+before using this, as this experimental feature may cause Grbl to take
+a performance hit at high step rates and about complex curves.
+
+
+----------------
+Date: 2012-03-10
+Author: Sonny Jeon
+Subject: Minor fix related to spindle_stop() crashing abort in certain cases.
+
+- Updated spindle_stop() to fix abort bug and to be more in line with
+v0.8.
+
+
+----------------
+Date: 2012-03-05
+Author: Sonny Jeon
+Subject: Minor updates.
+
+- Updated makefile to be more universally compatible by not requiring
+grep or ruby.
+
+- Edited XON/XOFF flow control usage, noting that FTDI-based Arduinos
+are known to work, but not Atmega8U2-based Arduino. Still officially
+not supported, but added for advanced users.
+
+- Minor edits.
+
+
+----------------
+Date: 2012-02-25
+Author: Sonny Jeon
+Subject: Minor include related compile fix. Added experimental XON/XOFF flow control. Not officially supported!
+
+- A latency issue related to USB-to-serial converters on the Arduino
+does not allow for XON/XOFF flow control to work correctly on standard
+terminal programs. It seems that only specialized UI's or avoiding the
+USB port all together solves this problem. However, XON/XOFF flow
+control is added for advanced users only as a compile-time option. This
+feature is officially *NOT* supported by grbl, but let us know of any
+successes with it!
+
+
+----------------
+Date: 2012-02-12
+Author: Sonny Jeon
+Subject: Spindle DDR pins init minor fix.
+
+
+----------------
+Date: 2012-02-11
+Author: Sonny Jeon
+Subject: Fix to enable spindle DDR ports.
+
+----------------
+Date: 2012-02-11
+Author: Sonny Jeon
+Subject: Minor compiler compatibility update for _delay_us().
+
+
+----------------
+Date: 2012-02-11
+Author: Sonny Jeon
+Subject: G54 work coordinate support (w/ G10,G92.1). Re-factored g-code parser with error checking. Minor compiler compatibility changes.
+
+- G54 work coordinate system support. Up to 6 work coordinate systems
+(G54-G59) available as a compile-time option.
+
+- G10 command added to set work coordinate offsets from machine
+position.
+
+- G92/G92.1 position offsets and cancellation support. Properly follows
+NIST standard rules with other systems.
+
+- G53 absolute override now works correctly with new coordinate systems.
+
+- Revamped g-code parser with robust error checking. Providing user
+feedback with bad commands. Follows NIST standards.
+
+- Planner module slightly changed to only expected position movements
+in terms of machine coordinates only. This was to simplify coordinate
+system handling, which is done solely by the g-code parser.
+
+- Upon grbl system abort, machine position and work positions are
+retained, while G92 offsets are reset per NIST standards.
+
+- Compiler compatibility update for _delay_us().
+
+- Updated README.
+
+
+----------------
+Date: 2012-01-31
+Author: Sonny Jeon
+Subject: printFloat rounding fix. Affected settings. Recommend using new build.
+
+printFloat was printing incorrectly and adding a value of 5 to every
+float instead of 0.0005 when rounding to 3 decimal places. The printed
+settings values do not accurately portray the actual stored value.
+Recommend using newly posted build.
+
+
+----------------
+Date: 2012-01-28
+Author: Sonny Jeon
+Subject: Program stop support (M0,M1*,M2,M30*), proper position retainment upon reset, misc minor updates.
+
+- Program stop support (M0,M1*,M2,M30*). *Optional stop to be done.
+*Pallet shuttle not supported.
+
+- Work position is set equal to machine position upon reset, as
+according to NIST RS274-NGC guidelines. G92 is disabled.
+
+- Renamed mc_set_current_position() to mc_set_coordinate_offset().
+
+- Fixed bug in plan_synchronize(). Would exit right before last step is
+finished and caused issues with program stops. Now fixed.
+
+- Spindle now stops upon a run-time abort command.
+
+- Updated readme and misc upkeeping.
+
+
+----------------
+Date: 2012-01-27
+Author: Sonny Jeon
+Subject: Streaming script argparse bugfix.
+
+
+----------------
+Date: 2012-01-27
+Author: Sonny Jeon
+Subject: Updated streaming scripts. Compiler compatibility for _delay_ms().
+
+- Moved obsolete streaming scripts to folder for reference.
+
+- Added a more complex Python streaming script which uses the serial
+buffer as an additional streaming buffer.
+
+- Removed all references to a _delay_ms(variable) to allow for better
+porting across different compilers.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v0.9g.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2409 @@
+----------------
+Date: 2014-09-05
+Author: Sonny Jeon
+Subject: Minor bug fix and CPU pin map update.
+
+- Sometime I HATE github. This push is just here to be able to describe
+the last two pushes today that had a merging conflict and lost all of
+the commit comments before.
+
+- Setting $10 would cause $11 to be the same value. Missed a break
+statement in the switch-case. Oops! Now fixed.
+
+- CPU pin map for the future versions of Grbl introduced, but not yet
+finalized. Still working on it and it’s subject to change.
+
+- Added a new high-speed machining test g-code routine written by Todd
+Fleming. Mills a pocket at 15,000mm/min. Do not use when connected to
+your machine! You’ve been warned!
+
+
+----------------
+Date: 2014-09-05
+Author: Sonny Jeon
+Subject: Updated README.md
+
+
+----------------
+Date: 2014-09-05
+Author: Sonny Jeon
+Subject: Merge branch 'master' of https://github.com/grbl/grbl
+
+Conflicts:
+	README.md
+
+
+----------------
+Date: 2014-08-24
+Author: Sonny Jeon
+Subject: Merge pull request #472 from BinaryConstruct/edge
+
+Add defaults for OX CNC
+
+----------------
+Date: 2014-08-24
+Author: BinaryConstruct
+Subject: Add defaults for OX CNC
+
+
+----------------
+Date: 2014-08-22
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-22
+Author: Sonny Jeon
+Subject: Updated build date.
+
+
+----------------
+Date: 2014-08-22
+Author: Sonny Jeon
+Subject: WPos report bug fix when MPos disabled.
+
+
+----------------
+Date: 2014-08-18
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-17
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-17
+Author: Sonny Jeon
+Subject: Updated bitly link to master firmware
+
+
+----------------
+Date: 2014-08-17
+Author: Sonny Jeon
+Subject: Merge branch 'master' into edge
+
+
+----------------
+Date: 2014-08-17
+Author: Sonny Jeon
+Subject: Final minor updates for master release.
+
+- Updated ShapeOko2 defaults based on machine testing of the basic
+model provided by Inventables. (or close to it.) Should be pretty
+conservative but much faster than before. For example, X and Y axes are
+set at (10x) faster at 5000mm/min. It can run much faster than this,
+but this seems like a safe speed for everyone.
+
+- Updated README for master release.
+
+- Added some new settings methods for clearing the EEPROM when changing
+versions. Needs some more work, but it should ok for master release.
+Should work on it more for the next version.
+
+
+----------------
+Date: 2014-08-13
+Author: Sonny Jeon
+Subject: Added EEPROM force clear.
+
+- When updating from v0.8, the settings will wipe the startup lines and
+build info locations so that it won’t use whatever is already there in
+the EEPROM. Parameters (coord offsets) are retained. They should be ok
+during an upgrade.
+
+
+----------------
+Date: 2014-08-13
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-13
+Author: Sonny Jeon
+Subject: G28/30 bug fix. Block '$$' during cycle. SO2 defaults.
+
+- A G28/30 bug would cause it to move to machine coordinate [0,0,0] if
+no axis words were sent. It was a typo in the new g-code parser. Fixed
+and slightly re-written to be more consistent with the program flow.
+
+- Updated the ShapeOko2 defaults based on testing on the real machine.
+A little conservative, but it might change again after some more
+testing.
+
+- Now blocks ‘$$’ command during a motion, because the printout takes
+too long and can starve the segment buffer.
+
+
+----------------
+Date: 2014-08-08
+Author: Sonny Jeon
+Subject: XON/XOFF flow control variable typo.
+
+
+----------------
+Date: 2014-08-07
+Author: Sonny Jeon
+Subject: Moved Grbl Sim to its own repo.
+
+
+----------------
+Date: 2014-08-07
+Author: Sonny Jeon
+Subject: Updated licensing
+
+
+----------------
+Date: 2014-08-05
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-05
+Author: Sonny Jeon
+Subject: Fixed bug related to very very low feed rates.
+
+- A very very low feed rate command like `G1 X100 F0.01`  would cause
+some floating-point round-off error and freeze Grbl into an infinite
+loop. To fix it, introduced a MINIMUM_FEED_RATE parameter in config.h
+to ensure motions always complete.
+
+- MINIMUM_FEED_RATE is set at 1.0 mm/min by default. It’s recommended
+that no rates are below this value, but 0.1mm/min may be ok in some
+situations.
+
+
+----------------
+Date: 2014-08-04
+Author: Sonny Jeon
+Subject: Allow '$$' in check mode.
+
+- Now allows the ‘$$’ view Grbl settings while in check mode
+
+- Updated the version build date
+
+
+----------------
+Date: 2014-08-04
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-04
+Author: Sonny Jeon
+Subject: Fixed probe position sync error.
+
+- Restored probe position syncing. Had removed a pull-off motion after
+a probe cycle completes, but ended up de-synchronizing the g-code
+parser and probing cycle positions. Putting the pull-off motion back
+fixed the problem.
+
+
+----------------
+Date: 2014-08-03
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-03
+Author: Sonny Jeon
+Subject: Probing cycle and view build info bug fixes.
+
+- Probing cycle would drop into a QUEUED state, if multiple G38.2 are
+sent. It would not honor the auto cycle start flags. To fix, the auto
+cycle start state is saved at the beginning of the probing cycle and
+restored at the end, since the feed hold it uses to stop a triggered
+probe will disable the auto start flag. For now it’s a patch, rather
+than a permanent fix.
+
+- protocol_buffer_synchronize() also has a failure case. Auto cycle
+start does not get executed when the system is waiting in here, so if
+it’s in a QUEUED state already, it won’t resume. Patched here, but not
+fully resolved.
+
+- Fixed a problem with the “view build info” command. The EEPROM write
+would do weird things and corrupt the EEPROM. Not sure exactly what
+caused it, but it’s likely a compiler problem with an improperly
+defined EEPROM address. It didn’t have enough room to store a full
+string. To fix, the build info EEPROM range was increased and the max
+number of STARTUP_BLOCKS was reduced to 2 from 3.
+
+- Lastly, when a $I view build info is used for the first time, it
+would normally show an EEPROM read error, since it wasn’t cleared or
+wasn’t therein the first place. It will now not show that error. A
+patch rather than a permanent fix again.
+
+
+----------------
+Date: 2014-08-01
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-08-01
+Author: Sonny Jeon
+Subject: Minor bug fixes.
+
+- Bug fix for step and direction invert masks not immediately being in
+effect. Now regenerates the masks when a user changes this setting.
+
+- Bug fix for probing cycle. G-code standard mandates that there is an
+error if the probe is already triggered when the cycle is commanded.
+However, Grbl may have motions to pull off a previous probing cycle in
+queue and can falsely lead to errors. To fix this, the triggered check
+is performed within the probing cycle itself, right after the planner
+buffer is synced. If there is an error, it will now alarm out as a
+probe fail.
+
+
+----------------
+Date: 2014-07-28
+Author: Sonny Jeon
+Subject: Compile in Atmel Studio fix.
+
+
+----------------
+Date: 2014-07-28
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-27
+Author: Sonny Jeon
+Subject: Added build info feedback in help
+
+- `$I` prints the Grbl build info and version number. NOTE: `$I=xxx`
+stores an additional 30 character string into EEPROM, which will be
+printed with the build info the next time it’s run. This is for
+identification purposes for users that have more than one system using
+Grbl.
+
+
+----------------
+Date: 2014-07-26
+Author: Sonny Jeon
+Subject: Updates to allow Arduino IDE direct compiling.
+
+- Only minor changes were required to make the Arduino IDE compile all
+of the Grbl’s source code (correctly using the C-compiler). Tested in
+Windows and Mac and with the normal USB upload and with a programmer.
+
+
+----------------
+Date: 2014-07-26
+Author: Sonny Jeon
+Subject: Settings refactoring. Bug fixes. Misc new features.
+
+This is likely the last major change to the v0.9 code base before push
+to master. Only two minor things remain on the agenda (CoreXY support,
+force clear EEPROM, and an extremely low federate bug).
+
+- NEW! Grbl is now compile-able and may be flashed directly through the
+Arduino IDE. Only minor changes were required for this compatibility.
+See the Wiki to learn how to do it.
+
+- New status reporting mask to turn on and off what Grbl sends back.
+This includes machine coordinates, work coordinates, serial RX buffer
+usage, and planner buffer usage. Expandable to more information on user
+request, but that’s it for now.
+
+- Settings have been completely renumbered to allow for future new
+settings to be installed without having to constantly reshuffle and
+renumber all of the settings every time.
+
+- All settings masks have been standardized to mean bit 0 = X, bit 1 =
+Y, and bit 2 = Z, to reduce confusion on how they work. The invert
+masks used by the internal Grbl system were updated to accommodate this
+change as well.
+
+- New invert probe pin setting, which does what it sounds like.
+
+- Fixed a probing cycle bug, where it would freeze intermittently, and
+removed some redundant code.
+
+- Homing may now be set to the origin wherever the limit switches are.
+Traditionally machine coordinates should always be in negative space,
+but when limit switches on are on the opposite side, the machine
+coordinate would be set to -max_travel for the axis. Now you can always
+make it [0,0,0] via a compile-time option in config.h. (Soft limits
+routine was updated to account for this as well.)
+
+ - Probe coordinate message immediately after a probing cycle may now
+be turned off via a compile-time option in config.h. By default the
+probing location is always reported.
+
+- Reduced the N_ARC_CORRECTION default value to reflect the changes in
+how circles are generated by an arc tolerance, rather than a fixed arc
+segment setting.
+
+- Increased the incoming line buffer limit from 70 to 80 characters.
+Had some extra memory space to invest into this.
+
+- Fixed a bug where tool number T was not being tracked and reported
+correctly.
+
+- Added a print free memory function for debugging purposes. Not used
+otherwise.
+
+- Realtime rate report should now work during feed holds, but it hasn’t
+been tested yet.
+
+- Updated the streaming scripts with MIT-license and added the simple
+streaming to the main stream.py script to allow for settings to be sent.
+
+- Some minor code refactoring to improve flash efficiency. Reduced the
+flash by several hundred KB, which was re-invested in some of these new
+features.
+
+
+----------------
+Date: 2014-07-17
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-12
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-12
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-12
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-12
+Author: Sonny Jeon
+Subject: Updated README
+
+
+----------------
+Date: 2014-07-11
+Author: Sonny Jeon
+Subject: Updated README
+
+
+----------------
+Date: 2014-07-11
+Author: Sonny Jeon
+Subject: Merge pull request #441 from ashelly/edge-simfix
+
+Fixes for simulator in alternate configurations.
+
+----------------
+Date: 2014-07-10
+Author: ashelly
+Subject: Restore changes made only for testing.
+
+
+----------------
+Date: 2014-07-10
+Author: ashelly
+Subject: Bug fixes for timers, added some wdt support for limit debounce.
+
+- Typo in timer def,
+- Handle 8 bit timers correctly,
+- Don't skip TOP count in CTC mode
+- added SREG for atomic bit operations
+
+
+----------------
+Date: 2014-07-09
+Author: Sonny Jeon
+Subject: Merge branch 'dev' into edge
+
+Conflicts:
+	sim/simulator.c
+	sim/simulator.h
+
+
+----------------
+Date: 2014-07-09
+Author: Sonny Jeon
+Subject: Added test g-code programs.
+
+
+----------------
+Date: 2014-07-06
+Author: Sonny Jeon
+Subject: Version and build update.
+
+- Incremented from v0.9e to v0.9f due to the new g-codes, velocity
+reporting option, decimal printing refactoring, grbl-sim updates, and
+G0/G1 bug fix.
+
+- Settings version was also incremented since settings.decimal_places
+is now gone.
+
+
+----------------
+Date: 2014-07-06
+Author: Sonny Jeon
+Subject: Isolate atomic bit flag for execution.
+
+- Denoted bit_true_atomic only for sys.execute bit settings. All other
+bit_true type calls are for local variables only and don’t need atomic
+access. Still looking into other ways of setting these flags without
+requiring atomic access, but this is a patch for now.
+
+
+----------------
+Date: 2014-07-06
+Author: Sonny Jeon
+Subject: Merge pull request #436 from kfoltman/dev
+
+Fixed atomic access to flags in sys.execute.
+
+----------------
+Date: 2014-07-06
+Author: Sonny Jeon
+Subject: Syntax fix for gcode.c
+
+- Whoops! Missed a bracket and it wasn’t compiling. Now fixed.
+
+- Updated the unsupported gcodes listed at the end of the gcode.c file.
+
+
+----------------
+Date: 2014-07-06
+Author: Sonny Jeon
+Subject: G43.1/G49 tool length offset installed. Minor bug fix.
+
+- Minor bug fix that caused G92.1 not to work. The mantissa of G92.1
+was not computed correctly due to floating point round-off errors and
+the use of trunc(). Fixed it by changing the computation with round().
+
+- Installed tool length offsets with G43.1 and G49! True tool length
+offsets via G43 are not supported, because these require us to store
+tool data that we don’t have space for. But we’ve come up with a good
+solution for users that need this. Instead we are strictly using the
+dynamic version G43.1 via linuxcnc.org. Visit their website for more
+details on the command.
+
+- G43.1 operates by requiring an axis word and value to offset the
+configured tool length axis, which can be configured for any axis
+(default Z-axis) in config.h. For example, ```G43.1 Z0.5``` will offset
+the work coordinates from Z0.0 to Z-0.5.
+
+- G49 will cancel the last tool length offset value and reset it to
+zero.
+
+- Tweaked the ‘$#’ parameters report. `Probe` is now `PRB` and a new
+value `TLO` states the tool length offset value.
+
+
+----------------
+Date: 2014-07-05
+Author: Sonny Jeon
+Subject: Merge branch 'ashelly-sim-update' into dev
+
+
+----------------
+Date: 2014-07-05
+Author: Sonny Jeon
+Subject: Merge grbl-sim updates for v0.9.
+
+- Removed some conflicting code in the main Grbl firmware source.
+
+- Temporary patch for coolant and spindle control with streaming
+applied.
+
+
+----------------
+Date: 2014-07-05
+Author: Sonny Jeon
+Subject: New G43.1/G49 gcodes. Not working yet!!
+
+- Pushed this uncompleted code to merge a conflicting pull request.
+
+- New G43.1 and G49 g-codes to be installed. The beginnings of it are
+in place. These g-codes are intended to be used in conjunction with
+probing and allow GUIs to set tool length offsets without Grbl needing
+to store a tool table.
+
+- G43.1 is defined as a dynamic tool length offset that is not stored
+in memory. Rather, when commanded, these are applied to the work
+coordinates until a reset or disabled by G49. This works much like G92.
+
+
+----------------
+Date: 2014-07-05
+Author: ashelly
+Subject: formatting
+
+----------------
+Date: 2014-07-05
+Author: ashelly
+Subject: Update readme.md
+
+----------------
+Date: 2014-07-04
+Author: ashelly
+Subject: Don't need kbhit.h
+
+----------------
+Date: 2014-07-04
+Author: Adam Shelly
+Subject: minor tweaks for mingw.
+
+
+----------------
+Date: 2014-07-04
+Author: Sonny Jeon
+Subject: Realtime rate reporting. Updated decimal places.
+
+- Added a new optional compile-time feature for ‘realtime’ (within
+50ms) feed rate reporting. When querying for a status report, a new
+data value will state the current operating rate. It’s only beta at the
+moment and has some kinks to work out.
+
+- Updated the code for printing floating point values to N decimal
+places. Generalized the main floating point print code to accept a new
+decimal places value and created a set of handler functions to print
+certain floating point value types used in Grbl, like position, rates,
+coordinate offsets, etc. All of these have different decimal
+requirements and change when printed in mm or inches mode.
+
+- Number of decimal places for the different value types can be
+re-defined in config.h, but there shouldn’t be a need for this, as
+these are physically limited.
+
+- Removed the decimal places settings, as this was now obsoleted by the
+new decimal places code.
+
+- The new decimal places code also saves almost 300kB in flash space,
+as it’s more efficient.
+
+
+----------------
+Date: 2014-07-04
+Author: ashelly
+Subject: reduce diffs with dev branch
+
+
+----------------
+Date: 2014-07-04
+Author: ashelly
+Subject: Total rework of simulator for dev branch.  Create separate thread for interrupt processes.  Tick-accurate simulation of timers.  Non-blocking character input for running in realtime mode. Decouple hardware sim from grbl code as much as possible. Expanded command line options. Provisions for cross-platform solution.
+
+
+----------------
+Date: 2014-07-03
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-07-03
+Author: Sonny Jeon
+Subject: G18 reporting bug fix.
+
+- G18 wasn’t getting reported back to the user correctly, even though
+it has been set internally. Fixed the reporting code to reflect this
+accurately.
+
+
+----------------
+Date: 2014-07-03
+Author: Sonny Jeon
+Subject: G-code parser G0/G1 bug fix.
+
+- Although stated as invalid in the NIST g-code standard, most g-code
+parsers, including linuxcnc, allow G0 and G1 to be commanded without
+axis words present. For example, something like ‘G1 F100.0’ to preset
+the motion mode and feed rate without a motion commanded. Older CNC
+controllers actually required this for feed rate settings. This update
+should now allow this type of behavior.
+
+
+----------------
+Date: 2014-07-02
+Author: Sonny Jeon
+Subject: Minor bug fixes and updates. Line number tracking.
+
+- Line number tracking was getting truncated at 255, since it was using
+wrong variable type. Fixed it with a trunc().
+
+- Increased the max number line allowed by Grbl to 9999999 from the
+g-code standard 99999. The latter seems to be an arbitrary number, so
+we are allowing larger ones for at least one known use case scenario.
+
+- Created a new test directory to contain some testing g-code to proof
+the firmware. Only got started with one test case so far. More will be
+inserted as needed.
+
+- Some other commenting updates to clarify certain aspects of the code.
+
+
+----------------
+Date: 2014-06-26
+Author: Krzysztof Foltman
+Subject: Fixed atomic access to flags in sys.execute.
+
+This seems to fix the bug that caused Grbl to hang during some operations,
+especially jogging.
+
+
+----------------
+Date: 2014-05-31
+Author: Sonny Jeon
+Subject: Arc error-checking update.
+
+- Updated offset-mode arc error-checking to EMC2’s version: The old
+NIST definition required the radii to the current location and target
+location to differ no more than 0.002mm. This proved to be problematic
+and probably why LinuxCNC(EMC2) updated it to be 0.005mm AND 0.1%
+radius OR 0.5mm.
+
+
+----------------
+Date: 2014-05-31
+Author: Sonny Jeon
+Subject: Various minor g-code parser fixes.
+
+- Updated the mantissa calculation that checks for non-integer values
+and GXX.X commands that aren’t supported. There was a potential uint8
+overflow issue.
+
+- Fixed g-code parser bug related to not using the correct modal
+struct. G10 P0 not selecting the current coordinate system when a
+G55-59 is issued in the same line.
+
+- Fixed g-code parser bug related to not using the correct modal
+struct. Target position locations were not computed correctly when
+G90/91 distance modes were changed in the same line. It was using the
+previous state, rather than the current block.
+
+
+----------------
+Date: 2014-05-29
+Author: Sonny Jeon
+Subject: Fixed spindle/coolant/dwell state check.
+
+
+----------------
+Date: 2014-05-25
+Author: Sonny Jeon
+Subject: Major g-code parser overhaul. 100%* compliant. Other related updates.
+
+- Completely overhauled the g-code parser. It’s now 100%* compliant. (*
+may have some bugs). Being compliant, here are some of the major
+differences.
+
+- SMALLER and JUST AS FAST! A number of optimizations were found that
+sped things up and allowed for the more thorough error-checking to be
+installed without a speed hit. Trimmed a lot of ‘fat’ in the parser and
+still was able to make it significantly smaller than it was.
+
+- No default feed rate setting! Removed completely! This doesn’t exist
+in the g-code standard. So, it now errors out whenever it’s undefined
+for motions that require it (G1/2/3/38.2).
+
+- Any g-code parser error expunges the ENTIRE block. This means all
+information is lost and not passed on to the running state. Before some
+of the states would remain, which could have led to some problems.
+
+- If the g-code block passes all of the error-checks, the g-code state
+is updated and all motions are executed according to the order of
+execution.
+
+- Changes in spindle speed, when already running, will update the
+output pin accordingly. This fixes a bug, where it wouldn’t update the
+speed.
+
+- Update g-code parser error reporting. Errors now return detailed
+information of what exact went wrong. The most common errors return a
+short text description. For less common errors, the parser reports
+‘Invalid gcode ID:20’, where 20 is a error ID. A list of error code IDs
+and their descriptions will be documented for user reference elsewhere
+to save flash space.
+
+- Other notable changes:
+
+- Added a print integer routine for uint8 variables. This saved
+significant flash space by switching from a heavier universal print
+integer routine.
+
+- Saved some flash space with our own short hypotenuse calculation
+
+- Some arc computation flash and memory optimizations.
+
+
+----------------
+Date: 2014-05-18
+Author: Jens Geisler
+Subject: Merge pull request #408 from chamnit/master
+
+MIT-Licensing change.
+
+----------------
+Date: 2014-05-18
+Author: Sonny Jeon
+Subject: MIT-licensing change.
+
+
+----------------
+Date: 2014-05-18
+Author: Sonny Jeon
+Subject: MIT-licensing change
+
+
+----------------
+Date: 2014-04-28
+Author: Sonny Jeon
+Subject: Merge pull request #391 from paulkaplan/master
+
+Update Shapeoko 2 defaults
+
+----------------
+Date: 2014-04-14
+Author: Paul Kaplan
+Subject: updated shapeoko2 defaults
+
+
+----------------
+Date: 2014-03-14
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-03-13
+Author: Sonny Jeon
+Subject: Comment corrections and function call update.
+
+
+----------------
+Date: 2014-03-13
+Author: Sonny Jeon
+Subject: Merge pull request #373 from EliteEng/dev
+
+Added Probing to Mega2560 and fixed Shapeoko2 compile error
+
+----------------
+Date: 2014-03-11
+Author: Rob Brown
+Subject: Added Probing to Mega2560 and fixed Shapeoko2 compile error
+
+
+----------------
+Date: 2014-03-07
+Author: henols
+Subject: Probing command gets stuck in hold if several g38.2 are submitted
+Ex.
+G0 X0 Y0 Z0
+G38.2 Z-10 F100
+G10 L20 P0 Z0
+G0 Z2
+G38.2 Z-1 F50
+G10 L20 P0 Z0
+G0 Z2
+G0 X0 Y0
+G38.2 Z-1 F100
+G0 Z2
+
+
+----------------
+Date: 2014-03-10
+Author: Sonny Jeon
+Subject: Merge pull request #372 from martinstingl/master
+
+Corrected units of default acceleration values
+
+----------------
+Date: 2014-03-10
+Author: Martin Stingl
+Subject: Corrected units of default acceleration values
+
+
+----------------
+Date: 2014-03-07
+Author: Sonny Jeon
+Subject: Merge pull request #368 from henols/dev
+
+Probing command gets stuck in hold if several g38.2 are submitted
+
+----------------
+Date: 2014-03-07
+Author: henols
+Subject: Probing command gets stuck in hold if several g38.2 are submitted
+Ex.
+G0 X0 Y0 Z0
+G38.2 Z-10 F100
+G10 L20 P0 Z0
+G0 Z2
+G38.2 Z-1 F50
+G10 L20 P0 Z0
+G0 Z2
+G0 X0 Y0
+G38.2 Z-1 F100
+G0 Z2
+
+
+----------------
+Date: 2014-02-28
+Author: Sonny Jeon
+Subject: G38.2 probe feature rough draft installed. Working but needs testing.
+
+- G38.2 straight probe now supported. Rough draft. May be tweaked more
+as testing ramps up.
+
+- G38.2 requires at least one axis word. Multiple axis words work too.
+When commanded, the probe cycle will move at the last ‘F’ feed rate
+specified in a straight line.
+
+- During a probe cycle: If the probe pin goes low (normal high), Grbl
+will record that immediate position and engage a feed hold. Meaning
+that the CNC machine will move a little past the probe switch point, so
+keep federates low to stop sooner. Once stopped, Grbl will issue a move
+to go back to the recorded probe trigger point.
+
+- During a probe cycle: If the probe switch does not engage by the time
+the machine has traveled to its target coordinates, Grbl will issue an
+ALARM and the user will be forced to reset Grbl. (Currently G38.3 probe
+without error isn’t supported, but would be easy to implement later.)
+
+- After a successful probe, Grbl will send a feedback message
+containing the recorded probe coordinates in the machine coordinate
+system. This is as the g-code standard on probe parameters specifies.
+
+- The recorded probe parameters are retained in Grbl memory and can be
+viewed with the ‘$#’ print parameters command. Upon a power-cycle, not
+a soft-reset, Grbl will re-zero these values.
+
+- Moved ‘$#’ command to require IDLE or ALARM mode, because it accesses
+EEPROM to fetch the coordinate system offsets.
+
+- Updated the Grbl version to v0.9d.
+
+- The probe cycle is subject to change upon testing or user-feedback.
+
+
+----------------
+Date: 2014-02-27
+Author: Sonny Jeon
+Subject: Probe cycle line numbers ifdef fixes to get it to compile.
+
+- Updated some of the ifdefs when disabling line numbers feature.
+Getting messy with this compile-time option. This will likely get
+cleaned up later.
+
+- This is just a push to get the new probing code to compile. Testing
+and optimization of the code will soon follow and be pushed next.
+
+
+----------------
+Date: 2014-02-27
+Author: Sonny Jeon
+Subject: Merge pull request #362 from robgrz/dev
+
+Minimal probing cycle working.  Supports both G38.2 for error and G38.3 ...
+
+----------------
+Date: 2014-02-26
+Author: Sonny Jeon
+Subject: Added grbl planner Matlab simulator for test reference. Updated line number compile-time option.
+
+- Added a grbl planner simulation tool that was written in Matlab and
+Python. It was used to visualize the inner workings of the planner as a
+program is streamed to it. The simulation assumes that the planner
+buffer is empty, then filled, and kept filled. This is mainly for users
+to see how the planner works.
+
+- Updated some of the compile-time ifdefs when enabling line numbers.
+The leaving the un-used line numbers in the function calls eats a
+non-neglible amount of flash memory. So the new if-defs remove them.
+
+
+----------------
+Date: 2014-02-25
+Author: Robert Grzesek
+Subject: Minimal probing cycle working.  Supports both G38.2 for error and G38.3 when no errors are desired.
+
+
+----------------
+Date: 2014-02-19
+Author: Sonny Jeon
+Subject: Minor updates to line number feature.
+
+- Changed line number integer types from unsigned to signed int32.
+G-code mandates values cannot exceed 99999. Negative values can be used
+to indicate certain modes.
+
+- Homing cycle line number changed to -1, as an indicator.
+
+- Fixed a reporting define for the spindle states that was broken by
+the last merge.
+
+
+----------------
+Date: 2014-02-19
+Author: Sonny Jeon
+Subject: Merge pull request #356 from robgrz/dev
+
+Line number reporting as compile-time option.
+
+----------------
+Date: 2014-02-19
+Author: Sonny Jeon
+Subject: Commenting updates. Minor bug fix with exit of soft limit event.
+
+
+----------------
+Date: 2014-02-18
+Author: Robert Grzesek
+Subject: Merge commit 'cd71a90ce8a770e0030ed6c9bac805b89724e275' into dev
+
+Conflicts:
+	limits.c
+	motion_control.c
+	report.c
+
+
+----------------
+Date: 2014-02-15
+Author: Sonny Jeon
+Subject: Homing and feed hold bug fixes.
+
+WARNING: Bugs may still exist. This branch is a work in progress and
+will be pushed to the edge branch when at beta stability. Use at your
+own risk.
+
+- Homing freezing issue fixed. Had to do with the cycle stop flag being
+set incorrectly after the homing cycles and before the pull-off
+maneuver. Now resets the stepper motors before this can happen.
+
+- Fixed an issue with a rare feed hold failure. Had to do with feed
+hold ending exactly at the end of a block. The runtime protocol now
+sets the QUEUED and IDLE states appropriately when this occurs. Still
+need to clean this code up however, as it’s patched rather than written
+well.
+
+- Updated version build via $I command.
+
+- Forgot to comment on a new feature for the last commit. Since steps
+are integers and millimeters traveled are floats, the old step segment
+generator ignored the step fraction differences in generating the
+segment velocities. Didn’t see like it would be much of a big deal, but
+there were instances that this would be a problem, especially for very
+slow feed rates. The stepper algorithm now micro-adjusts the segment
+velocities based on the step fractions not executed from the previous
+segment. This ensures that Grbl generates the velocity profiles EXACTLY
+and noticeably improves overall acceleration performance.
+
+
+----------------
+Date: 2014-02-09
+Author: Sonny Jeon
+Subject: Refactoring and lots of bug fixes. Updated homing cycle.
+
+WARNING: There are still some bugs to be worked out. Please use caution
+if you test this firmware.
+
+- Feed holds work much better, but there are still some failure
+conditions that need to be worked out. This is the being worked on
+currently and a fix is planned to be pushed next.
+
+- Homing cycle refactoring: Slight adjustment of the homing cycle to
+allow for limit pins to be shared by different axes, as long as the
+shared limit pins are not homed on the same cycle. Also, removed the
+LOCATE_CYCLE portion of the homing cycle configuration. It was
+redundant.
+
+- Limit pin sharing: (See above). To clear up one or two limit pins for
+other IO, limit pins can now be shared. For example, the Z-limit can be
+shared with either X or Y limit pins, because it’s on a separate homing
+cycle. Hard limit will still work exactly as before.
+
+- Spindle pin output fixed. The pins weren’t getting initialized
+correctly.
+
+- Fixed a cycle issue where streaming was working almost like a single
+block mode. This was caused by a problem with the spindle_run() and
+coolant_run() commands and issuing an unintended planner buffer sync.
+
+- Refactored the cycle_start, feed_hold, and other runtime routines
+into the runtime command module, where they should be handled here
+only. These were redundant.
+
+- Moved some function calls around into more appropriate source code
+modules.
+
+- Fixed the reporting of spindle state.
+
+
+----------------
+Date: 2014-02-06
+Author: Robert Grzesek
+Subject: Made line number reporting optional via config.h
+
+
+----------------
+Date: 2014-02-06
+Author: Robert Grzesek
+Subject: Initial line number reporting
+
+
+----------------
+Date: 2014-02-02
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-01-28
+Author: Jens Geisler
+Subject: Merge pull request #337 from michmerr/edge
+
+Make sure that cycle_start state is set before simulating steps.
+
+----------------
+Date: 2014-01-28
+Author: michmerr
+Subject: Simplify setting of STATE_CYCLE and ISR interval.
+
+Set sys.state to STATE_CYCLE directly instead of calling back to
+st_wakeup().
+
+Convert get_step_time() to a constant and rename it to ISR_INTERVAL.
+
+
+----------------
+Date: 2014-01-22
+Author: michmerr
+Subject: Make sure that cycle_start state is set before simulating steps.
+
+
+----------------
+Date: 2014-01-15
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-01-14
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-01-10
+Author: Sonny Jeon
+Subject: Lots of re-organization and cleaning-up. Some bug fixes.
+
+- Added a new source and header file called system. These files contain
+the system commands and variables, as well as all of the system headers
+and standard libraries Grbl uses. Centralizing some of the code.
+
+- Re-organized the include headers throughout the source code.
+
+- ENABLE_M7 define was missing from config.h. Now there.
+
+- SPINDLE_MAX_RPM and SPINDLE_MIN_RPM now defined in config.h. No
+uncommenting to prevent user issues. Minimum spindle RPM now provides
+the lower, near 0V, scale adjustment, i.e. some spindles can go really
+slow so why use up our 256 voltage bins for them?
+
+- Remove some persistent variables from coolant and spindle control.
+They were redundant.
+
+- Removed a VARIABLE_SPINDLE define in cpu_map.h that shouldn’t have
+been there.
+
+- Changed the DEFAULT_ARC_TOLERANCE to 0.002mm to improve arc tracing.
+Before we had issues with performance, no longer.
+
+- Fixed a bug with the hard limits and the software debounce feature
+enabled. The invert limit pin setting wasn’t honored.
+
+- Fixed a bug with the homing direction mask. Now is like it used to
+be. At least for now.
+
+- Re-organized main.c to serve as only as the reset/initialization
+routine. Makes things a little bit clearer in terms of execution
+procedures.
+
+- Re-organized protocol.c as the overall master control unit for
+execution procedures. Not quite there yet, but starting to make a
+little more sense in how things are run.
+
+- Removed updating of old settings records. So many new settings have
+been added that it’s not worth adding the code to migrate old user
+settings.
+
+- Tweaked spindle_control.c a bit and made it more clear and consistent
+with other parts of Grbl.
+
+- Tweaked the stepper disable bit code in stepper.c. Requires less
+flash memory.
+
+
+----------------
+Date: 2014-01-05
+Author: Sonny Jeon
+Subject: Updates to some stepper algorithm commenting
+
+
+----------------
+Date: 2014-01-05
+Author: Sonny Jeon
+Subject: New build info feature. (per @Analogreality request)
+
+- New build info feature. Hidden command ‘$I’ will print the build info
+for your Grbl firmware. Users may also write an identifying message
+within it via ‘$I=‘ with up to 32 characters. (no more, or else it will
+break).
+
+- Adjusted the max number of startup lines to 3. Majority of people
+will only need one.
+
+- Fixed a compile error with spindle_control.c. A rogue #endif was
+causing problems.
+
+
+----------------
+Date: 2014-01-04
+Author: Sonny Jeon
+Subject: Variable spindle output. Resolved conflicts in last push.
+
+Resolve conflicts.
+
+
+----------------
+Date: 2014-01-04
+Author: Sonny Jeon
+Subject: Cleaned up variable spindle output (PWM). Code and config comments.
+
+- Variable spindle speed output as a configuration option. Thanks
+@EliteEng! When enabled, the Z-limit (D11) and spindle enable(D12) pins
+switch to allow access to the hardware PWM output on pin D11.
+Otherwise, everything should work as it does.
+
+- Removed option for inverting the spindle and coolant enable pins.
+This is a safety hazard, especially for the spindle. When Grbl
+initializes, all pins are momentarily low until it finishes booting. If
+an invert is enabled, this means the spindles can be energized briefly
+during this time. If users need signal inversion, it’s recommended to
+just wire in an inversion circuit instead.
+
+- Cleared out references to spindle variable output in terms of step
+signal. This isn’t complete and requires more deliberation before
+installing.
+
+- Cleared up and cleaned up some code and config comments.
+
+
+----------------
+Date: 2014-01-03
+Author: Sonny Jeon
+Subject: Merge pull request #322 from EliteEng/dev
+
+Update to fix compile error
+
+----------------
+Date: 2014-01-03
+Author: Rob Brown
+Subject: Update to fix compile error
+
+Update to fix compile error
+
+
+----------------
+Date: 2014-01-02
+Author: Sonny Jeon
+Subject: Merge pull request #318 from EliteEng/dev
+
+PWM Spindle Control and Invert Spindle & Coolant Pins
+
+----------------
+Date: 2014-01-03
+Author: Rob Brown
+Subject: Update spindle_control.c
+
+Updated spindle_control.c due to compile error.
+
+----------------
+Date: 2014-01-02
+Author: Sonny Jeon
+Subject: Fix for M7/8/9 modal group checks. Updated AMASS frequency cutoffs and code cleaned.
+
+- Updated Grbl version to 0.9c and build number.
+
+- G-code parser was missing modal group violation checks for M7/8/9
+commands. Added them.
+
+- Updated the Adaptive Multi-Axis Step Smoothing (AMASS) cutoff
+frequencies so that the trade between the 16-bit Timer1 accuracy and
+the level step smoothing are somewhat better balanced. (Smoothing isn’t
+free, but a higher accuracy timer would provide high cutoff
+frequencies.)
+
+
+----------------
+Date: 2014-01-02
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-01-02
+Author: Rob Brown
+Subject: PWM Spindle Control and Invert Spindle & Coolant Pins
+
+PWM Spindle Control and Invert Spindle & Coolant Pins
+
+
+----------------
+Date: 2013-12-30
+Author: Sonny Jeon
+Subject: Minor bug fixes: Homing travel calculations. Cycle resuming after spindle and dwell commands.
+
+- Homing travel calculations fixed. It was computing the min travel
+rather than max.
+
+- Auto-start disable and pausing after spindle or dwell commands.
+Related to plan_synchronize() function call. Now fixed, but still need
+to work on the system state.
+
+- Pushed a fix to make this branch more Arduino IDE compatible. Removed
+extern call in nuts_bolts.c
+
+- Updated the stepper configuration option of enabling or disabling the
+new Adaptive Multi-Axis Step Smoothing Algorithm. Now works either way.
+
+- Updated some copyright info.
+
+
+----------------
+Date: 2013-12-30
+Author: Sonny Jeon
+Subject: Merge pull request #201 from Protoneer/master
+
+Made a few changes to make the code compatible with the Arduino IDE. Sorry about the tardiness!
+
+----------------
+Date: 2013-12-30
+Author: Sonny Jeon
+Subject: Incomplete push but working. Lots more stuff. More to come.
+
+- NEW! An active multi-axis step smoothing algorithm that automatically
+adjusts dependent on step frequency. This solves the long standing
+issue to aliasing when moving with multiple axes. Similar in scheme to
+Smoothieware, but more advanced in ensuring a more consistent CPU
+overhead throughout all frequencies while maintaining step exactness.
+
+- Switched from Timer2 to Timer0 for the Step Port Reset Interrupt.
+Mainly to free up hardware PWM pins.
+
+- Seperated the direction and step pin assignments, so we can now move
+them to seperate ports. This means that we can more easily support 4+
+axes in the future.
+
+- Added a setting for inverting the limit pins, as so many users have
+request. Better late than never.
+
+- Bug fix related to EEPROM calls when in cycle. The EEPROM would kill
+the stepper motion. Now protocol mandates that the system be either in
+IDLE or ALARM to access or change any settings.
+
+- Bug fix related to resuming the cycle after a spindle or dwell
+command if auto start has been disabled. This fix is somewhat temporary
+or more of a patch. Doesn’t work with a straight call-response
+streaming protocol, but works fine with serial buffer pre-filling
+streaming that most clients use.
+
+- Renamed the pin_map.h to cpu_map.h to more accurately describe what
+the file is.
+
+- Pushed an auto start bug fix upon re-initialization.
+
+- Much more polishing to do!
+
+
+----------------
+Date: 2013-12-29
+Author: Sonny Jeon
+Subject: Incomplete dev code push, but working. Lots of updates/fixes/improvements. Much still to polish.
+
+- Ugh. Github just erased my list of improvements and changes due to a
+conflict and forcing me to resolve it. Hope this goes through.
+
+- Major stepper algorithm change. Trashed the old v0.9 edge
+branch-style stepper algorithm. It’s fine, but it was susceptible to
+aliasing noise when moving very slow or very fast. It also had a bit of
+CPU overhead. It was written to solve a standing issue with v0.8
+master, where it couldn’t generate a smooth acceleration abocve
+10-15kHz. But, with new step segment buffer in v0.9c, it inadvertently
+fixed the acceleration problem with v0.8 stepper algorithm. So, what
+does it mean for you? Smoother stepper pulses and likely higher step
+frequencies.
+
+- Stepper algorithm now uses Timer1 and Timer2, instead of Timer0 and
+Timer2. Timers 0 and 2 can be swapped if there is an issue.
+
+- With the old v0.8 stepper algorithm, the STEP_DELAY_PULSE
+configuration option is also back.
+
+- NEW! Hard limit software debouncing. Grbl now employs the AVR’s
+watchdog timer as a way to monitor the hard limit pins and checking
+their states after a delay. This is a simple software debouncing
+technique and may help alleviate some of the false trigger some users
+have been complaining about. BUT, this won’t fix electric noise issues!
+
+- Fixed an issue with the new homing cycle routine where it wasn’t
+honoring the acceleration and axis speed limits depending on the homing
+cycle mask. Now does. Also, updated the homing direction mask code to
+be a little cleaner.
+
+- Moved the main part of the homing cycle control and execution to
+motion_control.c, where it fits better.
+
+- Removed the STATE_INIT system state as it was redundant. Made the
+system states into bitflags so multiple system states can be checked
+via one if statement.
+
+- Reorganized the power-up routine to work with the new system states.
+
+
+----------------
+Date: 2013-12-29
+Author: Sonny Jeon
+Subject: Merge branch 'dev' of https://github.com/grbl/grbl into dev
+
+Conflicts:
+	limits.c
+
+
+----------------
+Date: 2013-12-29
+Author: Sonny Jeon
+Subject: Merge branch 'dev' of https://github.com/grbl/grbl into dev
+
+Conflicts:
+	limits.c
+
+
+----------------
+Date: 2013-12-27
+Author: Sonny Jeon
+Subject: Merge pull request #312 from scottrcarlson/dev
+
+Fixed homing_dir_mask functionality in the re-written homing_cycle.
+
+----------------
+Date: 2013-12-27
+Author: Scott R Carlson
+Subject: Hard Limits configured for active high.
+
+Added the use of homing_dir_mask to homing_cycle
+
+
+----------------
+Date: 2013-12-10
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2013-12-10
+Author: Sonny Jeon
+Subject: Revamped homing cycle. Axis limits and max travel bug fixes. Build info. Refactored config.h.
+
+- Revamped and improved homing cycle. Now tied directly into the main
+planner and stepper code, which enables much faster homing seek rates.
+Also dropped the compiled flash size by almost 1KB, meaning 1KB more
+for other features.
+
+- Refactored config.h. Removed obsolete defines and configuration
+options. Moved lots of “advanced” options into the advanced area of the
+file.
+
+- Updated defaults.h with the new homing cycle. Also updated the
+Sherline 5400 defaults and added the ShapeOko2 defaults per user
+submissions.
+
+- Fixed a bug where the individual axes limits on velocity and
+acceleration were not working correctly. Caused by abs() returning a
+int, rather than a float. Corrected with fabs(). Duh.
+
+- Added build version/date to the Grbl welcome message to help indicate
+which version a user is operating on.
+
+- Max travel settings were not being defaulted into the settings EEPROM
+correctly. Fixed.
+
+- To stop a single axis during a multi-axes homing move, the stepper
+algorithm now has a simple axis lock mask which inhibits the desired
+axes from moving. Meaning, if one of the limit switches engages before
+the other, we stop that one axes and keep moving the other.
+
+
+----------------
+Date: 2013-12-10
+Author: Sonny Jeon
+Subject: Merge pull request #301 from shapeoko/master
+
+added shapeoko2 profile
+
+----------------
+Date: 2013-12-10
+Author: Edward
+Subject: added shapeoko2 profile
+
+shapeoko 2 uses 2mm GT2 belting and 20tooth pulleys
+
+
+----------------
+Date: 2013-12-07
+Author: Sonny Jeon
+Subject: Deceleration to zero speed improvements. Update defaults.
+
+- A minor issue with deceleration ramps when close to zero velocity.
+Should be virtually unnoticeable for most CNC systems, but fixed in
+this push and accurate to physics.
+
+- Updated some of the junction deviation defaults. Because the new
+stepper algorithm can easily maximize a CNC machine’s capabilities or
+simply go much faster, this means the speed in which it enters
+junctions has to be a little more constrained. Meaning that, we have to
+slow a little bit down more so that we don’t exceed the acceleration
+limits of the stepper motors.
+
+
+----------------
+Date: 2013-12-07
+Author: Sonny Jeon
+Subject: Pushed bug fixes. Updated readme.
+
+- G18 plane select fix from XZ-plane to ZX-plane per right hand rule.
+
+- Added volatile declaration for rx_buffer_tail in serial.c. No real
+effect to operation as avr-gcc adds this upon compilation. Helps with
+porting issues when using a different compiler.
+
+
+----------------
+Date: 2013-12-07
+Author: Sonny Jeon
+Subject: Pushed limits active high option. Updated defaults.h. Misc bug fixes. Cleaned up codebase.
+
+- Pushed limit switch active high option (i.e. NC switches).
+
+- Updated defaults.h to be in-line with the new settings.
+
+- Refactored feed hold handling and step segment buffer to be more
+generalized in effort to make adding feedrate overrides easier in the
+future. Also made it a little more clean.
+
+- Fixed G18 plane select issue. Now ZX-plane, rather than XZ-plane, per
+right hand rule.
+
+- Cleaned some of the system settings by more accurately renaming some
+of the variables and removing old obsolete ones.
+
+- Declared serial.c rx_buffer_tail to be volatile. No effect, since
+avr-gcc automatically does this during compilation. Helps with porting
+when using other compilers.
+
+- Updated version number to v0.9b.
+
+- Updates to README.md
+
+
+----------------
+Date: 2013-12-04
+Author: Sonny Jeon
+Subject: Reinstated feed holds into new stepper algorithm and planner. Rough draft, but working.
+
+- Reinstated the feed hold feature with the new stepper algorithm and
+new optimized planner. It works, but will be re-factored a bit soon to
+clean up the code.
+
+- At this point, feedrate overrides may need to be installed in the
+v1.0 version of grbl, while this version will likely be pushed to the
+edge branch soon and pushed to master after the bugs have been squashed.
+
+- Measured the overall performance of the new planner and stepper
+algorithm on an oscilloscope. The new planner is about 4x faster than
+before, where it is completing a plan in around 1ms. The stepper
+algorithm itself is minutely faster, as it is a little lighter. The
+trade-off in the increased planner performance comes from the new step
+segment buffer. However, even in the worse case scenario, the step
+segment buffer generates a new segment with a typical 0.2 ms, and the
+worse case is 1ms upon a new block or replanning the active block.
+Added altogether, it’s argubly still twice as efficient as the old one.
+
+
+----------------
+Date: 2013-11-23
+Author: Sonny Jeon
+Subject: Merge pull request #289 from Travis-Snoozy/master
+
+Add support for active-high limit switches
+
+----------------
+Date: 2013-11-22
+Author: Travis Snoozy
+Subject: Add support for active-high limit switches
+
+
+----------------
+Date: 2013-11-22
+Author: Sonny Jeon
+Subject: Yet another major stepper algorithm and planner overhaul.
+
+- Overhauled the stepper algorithm and planner again. This time
+concentrating on the decoupling of the stepper ISR completely. It is
+now dumb, relying on the segment generator to provide the number of
+steps to execute and how fast it needs to go. This freed up lots of
+memory as well because it made a lot tracked variables obsolete.
+
+- The segment generator now computes the velocity profile of the
+executing planner block on the fly in floating point math, instead of
+allowing the stepper algorithm to govern accelerations in the previous
+code. What this accomplishes is the ability and framework to (somewhat)
+easily install a different physics model for generating a velocity
+profile, i.e. s-curves.
+
+- Made some more planner enhancements and increased efficiency a bit.
+
+- The changes also did not increase the compiled size of Grbl, but
+decreased it slightly as well.
+
+- Cleaned up a lot of the commenting.
+
+- Still much to do, but this push works and still is missing feedholds
+(coming next.)
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Another merge fix.
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Merge fixes.
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Merge branch 'dev_2' into dev
+
+Conflicts:
+	README.md
+	gcode.c
+	motion_control.c
+	planner.c
+	planner.h
+	protocol.c
+	report.c
+	settings.c
+	settings.h
+	stepper.c
+	stepper.h
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Merge branch 'dev_2' into dev
+
+Conflicts:
+README.md
+gcode.c
+motion_control.c
+planner.c
+planner.h
+protocol.c
+report.c
+settings.c
+settings.h
+stepper.c
+stepper.h
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Planner function call fix. More clean up.
+
+
+----------------
+Date: 2013-10-29
+Author: Sonny Jeon
+Subject: Updated comments. Changed stepper variable names to be more understandable. Added step locking note.
+
+- Updated config comments and stepper code comments for the new changes.
+
+- Changed stepper algorithm variable names to be more understandable in
+what they actually do.
+
+- Added a stepper lock note in default.h per user request.
+
+- Started some code layout in handling feed holds and refactoring the
+homing routine to use the main stepper algorithm instead of a seperate
+version.
+
+
+----------------
+Date: 2013-10-24
+Author: Sonny Jeon
+Subject: Cleaned up stepper and planner code.
+
+- Added some compile-time error checking. Will add more in future
+pushes to ensure settings are correct and within parameters that won't
+break anything.
+
+- Pushed some master branch changes with MEGA pin settings.
+
+- Cleaned up planner code and comments to clarify some of the new
+changes. Still much to do here.
+
+- Cleaned up the new stepper code. May need to abstract some of the
+segment buffer more to fix the feed holds (and integrate homing into
+the main stepper routine). With what's planned, this should make the
+stepper algorithm easier to attach other types of processes to it,
+where it is now tightly integrated with the planner buffer and nothing
+else.
+
+
+----------------
+Date: 2013-10-21
+Author: Sonny Jeon
+Subject: Merge pull request #279 from EliteEng/master
+
+Changed Stepper Pins
+
+----------------
+Date: 2013-10-18
+Author: Rob Brown
+Subject: Changed Stepper Pins
+
+Changed Stepper Pins so the Step Port Invert Mask matches the UNO
+
+
+----------------
+Date: 2013-10-17
+Author: Sonny Jeon
+Subject: Merge pull request #278 from EliteEng/master
+
+Update Pin Change Interrupts on Mega 2560
+
+----------------
+Date: 2013-10-17
+Author: Rob Brown
+Subject: Update Pin Change Interrupts so it works
+
+PCIE1 - Interrupt 8 on the Mega is attached to USART0 RX so when any
+serial communication was transmitted it was triggering the Reset
+Interrupt
+
+
+----------------
+Date: 2013-10-14
+Author: Sonny Jeon
+Subject: Fine tuning of new stepper algorithm with protected planner. Adaptive step prediction for segment buffer.
+
+- Cleaned up the new stepper algorithm code with more commenting and
+better logic flow.
+
+- The new segment buffer now predicts the number of steps each segment
+should have to execute over about 8 milliseconds each (based on the
+ACCELERATION_TICKS_PER_SECOND setting). So, for when the whole segment
+buffer is full, the stepper algorithm has roughly 40 milliseconds of
+steps queued before it needs to refilled by the main program.
+
+- Readjusted the max supported step rate back to 30kHz from the lower
+development 20kHz. Everything still works amazing great and the test
+CNC machine still runs twice as fast with the new stepper algorithm and
+planner.
+
+- Upped the standard serial baudrate to 115200 baud, as it is clear
+that the bottleneck is the serial interface. Will now support this, as
+well as the old 9600 baud, in new firmware builds.
+
+
+----------------
+Date: 2013-10-12
+Author: Sonny Jeon
+Subject: New stepper subsystem bug fixes.
+
+- New stepper algorithm with the new optimized planner seems to be
+working nearly twice as fast as the previous algorithm.
+
+- For one, the planner computation overhead is probably a fraction of
+what it used to be with the worst case being about half still.
+
+- Secondly, anytime the planner plans back to the first executing
+block, it no longer overwrites the block conditions and allows it to
+complete without lost steps. So no matter if the streams slows, the
+protected planner should keep the steppers moving without risk of lost
+steps (although this still needs to be tested thoroughly and may
+audibly sound weird when this happens.)
+
+- It now seems that the bottleneck is the serial baudrate (which is
+good!)
+
+
+----------------
+Date: 2013-10-09
+Author: Sonny Jeon
+Subject: Protected buffer works! Vast improvements to planner efficiency.  Many things still broken with overhaul.
+
+Development push. Lots still broken.
+
+- Protected planner concept works! This is a critical precursor to
+enabling feedrate overrides in allowing the planner buffer and the
+stepper execution operate atomically. This is done through a
+intermediary segment buffer.
+
+- Still lots of work to be done, as this was a complete overhaul of the
+planner and stepper subsystems. The code can be cleaned up quite a bit,
+re-enabling some of the broken features like feed holds, and finishing
+up some of the concepts
+
+- Pushed some of the fixes from the master and edge branch to here, as
+this will likely replace the edge branch when done.
+
+
+----------------
+Date: 2013-08-25
+Author: Sonny Jeon
+Subject: Merge pull request #263 from 0xPIT/master
+
+remove mcu argument for avr-size in makefile as it is not present in GNU...
+
+----------------
+Date: 2013-08-25
+Author: 0xPIT
+Subject: remove mcu argument for avr-size in makefile as it is not present in GNU Binutils 2.22
+
+
+----------------
+Date: 2013-08-20
+Author: Sonny Jeon
+Subject: Pin map definition cleanup.
+
+
+----------------
+Date: 2013-08-19
+Author: Sonny Jeon
+Subject: Processor-independent pin mapping feature.
+
+- Cleaned up and organized pin mapping concept by @elmom.
+
+- pin_map.h allows for user-supplied pin mapping and port vector
+definitions in a centralized file. With more processor types, more
+definitions could be added.
+
+
+----------------
+Date: 2013-08-19
+Author: Sonny Jeon
+Subject: Merge pull request #260 from elmom/master
+
+Thanks for the contribution! Looks good. Will update some of the semantics shortly, but the idea is solid.
+
+----------------
+Date: 2013-08-19
+Author: Sonny Jeon
+Subject: Push old dev_2 draft to work on other things.
+
+- **NON-FUNCTIONAL**
+- Contains an old draft of separating the stepper driver direct access
+to the planner buffer. This is designed to keep the stepper and planner
+modules independent and prevent overwriting or other complications. In
+this way, feedrate override should be able to be installed as well.
+- A number of planner optimizations are installed too.
+- Not sure where the bugs are. Either in the new planner optimizations,
+new stepper module updates, or in both. Or it just could be that the
+Arduino AVR is choking with the new things it has to do.
+
+
+----------------
+Date: 2013-08-19
+Author: Sonny Jeon
+Subject: Merge pull request #229 from 0xPIT/patch-1
+
+fix command line parameter for avr-size
+
+----------------
+Date: 2013-07-21
+Author: Elmo Mäntynen
+Subject: Refactor config.h to allow defaults for chips/boards with different pin mappings
+
+
+----------------
+Date: 2013-07-21
+Author: Elmo Mäntynen
+Subject: Added pin mapping list to docs, useful for porting
+
+
+----------------
+Date: 2013-07-21
+Author: Elmo Mäntynen
+Subject: Make serial work with most chips by default
+
+
+----------------
+Date: 2013-05-16
+Author: 0xPIT
+Subject: fix command line parameter for avr-size
+
+----------------
+Date: 2013-04-05
+Author: Sonny Jeon
+Subject: Updated readme
+
+
+----------------
+Date: 2013-04-05
+Author: Sonny Jeon
+Subject: Increased g-code parser line buffer. Added line overflow feedback.
+
+- Increased g-code parser line buffer from 50 to 70 characters. Should
+fix most all issues with long arc statements, provided that they are 8
+digits(float) long only.
+
+- Added a line buffer overflow feedback error to let the user know when
+it encounters this problem. Resets the line whenever this occurs.
+(Thanks @BHSPitMonkey!)
+
+
+----------------
+Date: 2013-04-05
+Author: Sonny Jeon
+Subject: Updates to edge/dev. Line buffer increased/planner buffer decreased. Line overflow feedback.
+
+- Increased g-code parser line buffer to 70 characters (from 50) to
+prevent some long arc commands from getting truncated.
+
+- Decreased planner buffer from 18 to 17 blocks to free up memory for
+line buffer.
+
+- Added a line buffer overflow feedback error (Thanks @BHSPitMonkey!)
+
+
+----------------
+Date: 2013-03-28
+Author: Sonny Jeon
+Subject: Minor updates to code and commenting.
+
+
+----------------
+Date: 2013-03-22
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2013-03-21
+Author: Sonny Jeon
+Subject: Untested! Soft limits, max travel, homing changes, new settings.
+
+- WARNING: Completely untested. Will later when there is time. Settings
+WILL be overwritten, as there are new settings.
+
+- Soft limits installed. Homing must be enabled for soft limits to work
+correctly. Errors out much like a hard limit, locking out everything
+and bringing up the alarm mode. Only difference is it forces a feed
+hold before doing so. Position is not lost.
+
+- IMPORTANT: Homing had to be updated so that soft limits work better
+with less CPU overhead. When homing completes, all axes are assumed to
+exist in negative space. If your limit switch is other side, the homing
+cycle with set this axis location to the max travel value, rather than
+zero.
+
+- Update mc_line() to accept an array, rather than individual variables.
+
+- Added an mc_auto_cycle_start() function handle this feature.
+Organization only.
+
+-
+
+
+----------------
+Date: 2013-03-19
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2013-03-19
+Author: Sonny Jeon
+Subject: G-code updates for G10 L2 and L20
+
+- Updated g-codes G10 L2 and G10 L20 to the new descriptions on
+linuxcnc.org
+
+
+----------------
+Date: 2013-03-19
+Author: Sonny Jeon
+Subject: G-code updates for G10 L2 and L20.
+
+- LinuxCNC's g-code definitions changed for G10. Updated to their
+descriptions.
+
+
+----------------
+Date: 2013-03-13
+Author: Bertus Kruger
+Subject: Update planner.c
+
+Removed inline from all functions. 
+
+If this is really needed is there another way that we can get 
+around using it? (The Arduino IDE does not recognize it) 
+
+----------------
+Date: 2013-03-13
+Author: Bertus Kruger
+Subject: Update nuts_bolts.c
+
+Removed __floatunsisf and used normal casting on line 81. 
+This makes it compatible with the Arduino IDE.
+
+----------------
+Date: 2013-03-12
+Author: Sonny Jeon
+Subject: Pushed minor changes. Thanks @Protoneer!
+
+
+----------------
+Date: 2013-03-12
+Author: Sonny Jeon
+Subject: Merge pull request #200 from Protoneer/master
+
+Fixed small bug.
+
+----------------
+Date: 2013-03-13
+Author: Bertus Kruger
+Subject: Update gcode.c
+
+Removed the home_select variable.
+
+----------------
+Date: 2013-03-13
+Author: Bertus Kruger
+Subject: Update eeprom.h
+
+Fixed the function signature.
+
+----------------
+Date: 2013-03-13
+Author: Bertus Kruger
+Subject: Update eeprom.c
+
+Changed back
+
+----------------
+Date: 2013-03-12
+Author: Bertus Kruger
+Subject: Update gcode.c
+
+home_select defined out of scope. Moved it outside the switch 
+so the rest of the switch can see it properly. 
+
+----------------
+Date: 2013-03-12
+Author: Bertus Kruger
+Subject: Update eeprom.c
+
+Function eeprom_put_char's parameters did not align with the .h file.
+
+----------------
+Date: 2013-03-01
+Author: Sonny Jeon
+Subject: Bug fix to-do note on soft limit checks. Not yet completed.
+
+
+----------------
+Date: 2013-03-01
+Author: Sonny Jeon
+Subject: Minor changes and added notes to soft limits routines.
+
+- Changed up mc_line to accept an array rather than individual x,y,z
+coordinates. Makes some of the position data handling more effective,
+especially for a 4th-axis later on.
+
+- Changed up some soft limits variable names.
+
+
+----------------
+Date: 2013-02-26
+Author: Sonny Jeon
+Subject: Merge pull request #193 from bungao/soft_limts
+
+integrating soft limits
+
+----------------
+Date: 2013-02-26
+Author: Jens Geisler
+Subject: bugfix: uninitiallized curr_block->new_entry_speed_sqr lead to step loss
+in some cases
+
+----------------
+Date: 2013-02-26
+Author: bungao
+Subject: integrating soft limits
+
+
+----------------
+Date: 2013-02-22
+Author: Sonny Jeon
+Subject: Added some prelimary notes to new changes.
+
+
+----------------
+Date: 2013-02-22
+Author: Sonny Jeon
+Subject: Push additional updates from @jgeisler0303
+
+
+----------------
+Date: 2013-02-22
+Author: Jens Geisler
+Subject: changed atomic access for updating the acceleration profile
+the stepper interrupt is only halted when necessary and for the shortest
+time possible (8% cycle time)
+
+----------------
+Date: 2013-02-20
+Author: Sonny Jeon
+Subject: Merge pull request #188 from jgeisler0303/new_planner
+
+New planner commits merge into dev branch.
+
+----------------
+Date: 2013-02-20
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2013-02-20
+Author: Jens Geisler
+Subject: added counter for planner steps
+
+----------------
+Date: 2013-02-20
+Author: Jens Geisler
+Subject: implemented a mixture of Sonny's MATLAB and my previous grbl planner
+ontop of the edge planner
+examples run byte for byte identical old and new version
+
+----------------
+Date: 2013-01-18
+Author: Sonny Jeon
+Subject: Merge pull request #169 from silasb/fix-execute-bit-on-files
+
+Removing executable bit on the files
+
+----------------
+Date: 2013-01-18
+Author: Sonny Jeon
+Subject: Merge bug fixes from recent v0.8c push. Added readme for Grbl Sim.
+
+
+----------------
+Date: 2013-01-18
+Author: Sonny Jeon
+Subject: Merge pull request #167 from tmpvar/simulator-mac
+
+Fix sim makefile so it works on mac
+
+----------------
+Date: 2013-01-18
+Author: Elijah Insua
+Subject: Fix sim makefile so it works on mac
+
+These changes include a path separator fix and the removal of --gc-sections which causes ld failures, and is not needed on a pc.
+
+This patch also changes how a compiler is selected.  The makefile will now select the system compiler , which should work fine
+under mingw and linux.
+
+
+----------------
+Date: 2013-01-17
+Author: Silas Baronda
+Subject: Removing executable bit on the files
+
+
+----------------
+Date: 2013-01-17
+Author: Sonny Jeon
+Subject: Merge pull request #112 from jgeisler0303/simulator
+
+Grbl Simulator. Oh yeah. 
+
+----------------
+Date: 2013-01-17
+Author: Jens Geisler
+Subject: relaunch ontop of latest grbl edge
+code very messy but tested
+
+----------------
+Date: 2013-01-09
+Author: Sonny Jeon
+Subject: Merge pull request #160 from daapp/edge
+
+Replace some constants with N_AXIS.
+
+----------------
+Date: 2013-01-10
+Author: Alexander Danilov
+Subject: Replace some constants with N_AXIS.
+
+
+----------------
+Date: 2013-01-06
+Author: Sonny Jeon
+Subject: Fixed bug with homing and polling at the same time. Updated readme.
+
+
+----------------
+Date: 2013-01-06
+Author: Sonny Jeon
+Subject: Minor changes.
+
+- Changed some names up and removed a plan_reset() function that is
+never used.
+
+
+----------------
+Date: 2012-12-21
+Author: Sonny Jeon
+Subject: Readme link to edge build 2012-12-21
+
+
+----------------
+Date: 2012-12-21
+Author: Sonny Jeon
+Subject: Updated README. Max step rate back at 30kHz. Acceleration minor bug fix.
+
+- Returned the max step rate to 30kHz. The new arc algorithm works uses
+so much less CPU overhead, because the segments are longer, that the
+planner has no problem computing through them.
+
+- Fixed an issue with the acceleration independence scaling. Should now
+work with accelerations above 400mm/sec^2 or so.
+
+- Updated README
+
+
+----------------
+Date: 2012-12-19
+Author: Sonny Jeon
+Subject: Arc mm_per_segment removed, now in terms of tolerance. Stepper ramp counter variable type corrected.
+
+- Arc mm_per_segment parameter was removed and replaced with an
+arc_tolerance parameter, which scales all arc segments automatically to
+radius, such that the line segment error doesn't exceed the tolerance.
+Significantly improves arc performance through larger radius arc,
+because the segments are much longer and the planner buffer has more to
+work with.
+
+- Moved n_arc correction from the settings to config.h. Mathematically
+this doesn't need to be a setting anymore, as the default config value
+will work for all known CNC applications. The error does not accumulate
+as much anymore, since the small angle approximation used by the arc
+generation has been updated to a third-order approximation and how the
+line segment length scale with radius and tolerance now. Left in
+config.h for extraneous circumstances.
+
+- Corrected the st.ramp_count variable (acceleration tick counter) to a
+8-bit vs. 32-bit variable. Should make the stepper algorithm just a
+touch faster overall.
+
+
+----------------
+Date: 2012-12-16
+Author: Sonny Jeon
+Subject: Slow trailing steps fix. Added more defaults.
+
+- Fixed an issue (hopefully) with slow trailing steps after a
+triangular velocity profile move. Sets the trapezoid tick cycle counter
+to the correct value for an accurate reproduction of the deceleration
+curve. Keeps it from arriving too early to the target position, which
+causes the slow trailing steps.
+
+- Added Zen Toolworks 7x7 to default settings.
+
+- Updated readme with new edge build.
+
+
+----------------
+Date: 2012-12-16
+Author: Sonny Jeon
+Subject: Max velocity axes independence installed. Fixed intermittent slow trailing steps. Timer0 disable fix.
+
+- Maximum velocity for each axis is now configurable in settings. All
+rapids/seek move at these maximums. All feed rates(including rapids)
+may be limited and scaled down so that no axis does not exceed their
+limits.
+
+- Moved around auto-cycle start. May change later, but mainly to ensure
+the planner buffer is completely full before cycle starting a streaming
+program. Otherwise it should auto-start when there is a break in the
+serial stream.
+
+- Reverted old block->max_entry_speed_sqr calculations. Feedrate
+overrides not close to ready at all.
+
+- Fixed intermittent slow trailing steps for some triangle velocity
+profile moves. The acceleration tick counter updating was corrected to
+be exact for that particular transition. Should be ok for normal
+trapezoidal profiles.
+
+- Fixed the Timer0 disable after a step pulse falling edge. Thanks
+@blinkenlight!
+
+
+----------------
+Date: 2012-12-14
+Author: Sonny Jeon
+Subject: Acceleration independence installed. Initial re-work of planner for feedrate overrides.
+
+NOTE: This push is a work-in-progress and there are known bugs that
+need to be fixed, like homing acceleration being incompatible. Released
+for testing. Settings will definitely be overwritten, as new settings
+were needed.
+
+- Acceleration independence installed in planner. Each axis can now
+have different accelerations and Grbl will maximize the accelerations
+depending on the direction its moving. Very useful for users like on
+the ShapeOko with vastly different Z-axis properties.
+
+- More planner optimizations and re-factoring. Slightly improved some
+of the older calculations, but new acceleration calculations offset
+these improvements. Overall no change in processing speed.
+
+- Removed planner nominal length checks. It was arguable whether or not
+this improved planner efficiency, especially in the worst case scenario
+of arcs.
+
+- Updated readme and changed to markdown format.
+
+
+----------------
+Date: 2012-12-12
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2012-12-12
+Author: Sonny Jeon
+Subject: Changed README to markdown
+
+
+----------------
+Date: 2012-12-12
+Author: Sonny Jeon
+Subject: Added download links to README.
+
+
+----------------
+Date: 2012-12-12
+Author: Sonny Jeon
+Subject: Moved compiled builds to different repo.
+
+
+----------------
+Date: 2012-12-11
+Author: Sonny Jeon
+Subject: Added builds folder.
+
+Because the Downloads section has been removed, added a builds folder
+for users to download pre-compiled firmware without needing to compile
+it themselves.
+
+
+----------------
+Date: 2012-12-11
+Author: Sonny Jeon
+Subject: Added builds folder.
+
+In light of the downloads section in Github being removed, added a
+builds folder for all of the .hex files. Hopefully these won't be
+removed either.
+
+
+----------------
+Date: 2012-12-11
+Author: Sonny Jeon
+Subject: Planner optimizations.
+
+- Improved planner execution speed by 5% or more. Re-factored most of
+the calculations in terms of the square of velocity. This removed a lot
+of sqrt() calculations for every planner_recalculate.
+
+
+----------------
+Date: 2012-12-10
+Author: Sonny Jeon
+Subject: (Another) Planner bug fix.
+
+- Oops again. Thought the new planner changes made things much better,
+but there was a bug. Improvements we on the order of 20% execution time
+reduction, rather than half. The increase to 30kHz Ranade timer
+frequency also increased the overall overhead, so the total planner
+change? Zero. But, it's still better.
+
+
+----------------
+Date: 2012-12-10
+Author: Sonny Jeon
+Subject: Planner bug fix.
+
+- Oops! Misplace an if-then statement. Should work as advertised now.
+(Hopefully)
+
+
+----------------
+Date: 2012-12-10
+Author: Sonny Jeon
+Subject: Planner execution time halved and bug fixes. Increased step rate limit to 30kHz.
+
+- Planner execute speed has been more than halved from 4ms to 1.9ms
+when computing a plan for a single line segment during arc generation.
+This means that Grbl can now run through an arc (or complex curve)
+twice as fast as before without starving the buffer. For 0.1mm arc
+segments, this means about the theoretical feed rate limit is about
+3000mm/min for arcs now.
+
+- Increased the Ranade timer frequency to 30kHz, as there doesn't seem
+to be any problems with increasing the frequency. This means that the
+maximum step frequency is now back at 30kHz.
+
+- Added Zen Toolworks 7x7 defaults.
+
+
+----------------
+Date: 2012-12-08
+Author: Sonny Jeon
+Subject: New stepper algorithm. Optimized planner.
+
+- Brand-new stepper algorithm. Based on the Pramod Ranade inverse time
+algorithm, but modified to ensure step events are exact. Currently
+limited to about 15kHz step rates, much more to be done to enable 30kHz
+again.
+
+- Removed Timer1. Stepper algorithm now uses Timer0 and Timer2.
+
+- Much improved step generation during accelerations. Smoother. Allows
+much higher accelerations (and speeds) than before on the same machine.
+
+- Cleaner algorithm that is more easily portable to other CPU types.
+
+- Streamlined planner calculations. Removed accelerate_until and
+final_rate variables from block buffer since the new stepper algorithm
+is that much more accurate.
+
+- Improved planner efficiency by about 15-20% during worst case
+scenarios (arcs).
+
+- New config.h options to tune new stepper algorithm.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v0.9i.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,871 @@
+----------------
+Date: 2015-08-14
+Author: Sonny Jeon
+Subject: Individual control pin invert compile-option.
+
+- Control pins may be individually inverted through a
+CONTROL_INVERT_MASK macro. This mask is define in the cpu_map.h file.
+
+
+----------------
+Date: 2015-07-17
+Author: Sonny Jeon
+Subject: Version bump to v0.9j
+
+- Version bump requested by OEMs to easily determine whether the
+firmware supports the new EEPROM reset feature. Other than that, no
+significant changes.
+
+
+----------------
+Date: 2015-06-25
+Author: Sonny Jeon
+Subject: Restore parameters minor bug fix.
+
+- `$RST=#` was not wiping the G30 positions from EEPROM. Minor but now
+fixed.
+
+
+----------------
+Date: 2015-06-20
+Author: Sonny Jeon
+Subject: New EEPROM restore functions.
+
+- Tweaked the previous EEPROM restore implementation and added new
+functionality.
+
+- `$RST=$` restores the `$$` grbl settings back to firmware defaults,
+which are set when compiled.
+
+- `$RST=#` restores the `$#` parameters in EEPROM. At times it’s useful
+to clear these and start over, rather than manually writing each entry.
+
+-`$RST=*` wipe all of the data in EEPROM that Grbl uses and restores
+them to defaults. This includes `$$` settings, `$#` parameters, `$N`
+startup lines, and `$i` build info string.
+
+NOTE: This doesn’t write zeros throughout the EEPROM. It only writes
+where Grbl looks for data. For a complete wipe, please use the Arduino
+IDE’s EEPROM clear example.
+
+- Refactored the restore and wipe functions in settings.c to
+accommodate the new commands.
+
+
+----------------
+Date: 2015-06-18
+Author: Sonny Jeon
+Subject: Updated README
+
+
+----------------
+Date: 2015-06-18
+Author: Sonny Jeon
+Subject: Added restore settings defaults command.
+
+- New restore setting defaults command. Only wipes ‘$$’ setting in
+EEPROM and reloads them based on the defaults used when Grbl was
+compiled. Used with a `$RST` command
+
+NOTE: `$RST` is intentionally not listed in the Grbl ‘$’ help message.
+
+
+----------------
+Date: 2015-05-29
+Author: Sonny Jeon
+Subject: Added G61 exact path support.
+
+- G61 exact path is the Grbl default path control mode, so it’s now
+added as a supported g-code.
+
+
+----------------
+Date: 2015-05-27
+Author: Sonny Jeon
+Subject: Another git case-sensitive folder fix.
+
+- I’m now officially annoyed.
+
+
+----------------
+Date: 2015-05-27
+Author: Sonny Jeon
+Subject: Added X-Carve defaults.
+
+- Added X-Carve 500mm and 1000mm default files.
+
+- Tweaked all default files. Removed obsolete AUTO_START and updated
+some JUNCTION_DEVIATION defaults after testing showed these needed to
+be reduced slightly.
+
+
+----------------
+Date: 2015-05-27
+Author: Sonny Jeon
+Subject: Merge pull request #710 from buserror/fix-directory-case-sensitivity
+
+Rename Grbl to grbl
+
+----------------
+Date: 2015-05-27
+Author: Michel Pollet
+Subject: Rename Grbl to grbl
+
+Otherwise compilation fails on linux, or other case sensitive systems
+
+Signed-off-by: Michel Pollet <buserror@gmail.com>
+
+
+----------------
+Date: 2015-05-26
+Author: Sonny Jeon
+Subject: Updated README
+
+
+----------------
+Date: 2015-05-26
+Author: Sonny Jeon
+Subject: Merge pull request #706 from grbl/edge
+
+Merge edge branch.
+
+----------------
+Date: 2015-05-23
+Author: Sonny Jeon
+Subject: CoreXY planner bug fix.
+
+- CoreXY motions were moving to the negative value of the intended
+target. Now fixed.
+
+
+----------------
+Date: 2015-05-23
+Author: Sonny Jeon
+Subject: Moved cpu_map.
+
+- Moved cpu_map files to a cpu_map directory, like the defaults file
+organization.
+
+
+----------------
+Date: 2015-05-23
+Author: Sonny Jeon
+Subject: Homing and limit updates. Minor bug fixes.
+
+- Updated new homing cycle to error out when a pull-off motion detects
+the limit is still active.
+
+- Created a limits_get_state() function to centralize it. It reports
+state as a bit-wise booleans according to axis numbering.
+
+- Updated the print uint8 functions. Generalized it to allow both base2
+and base10 printouts, while allowing base2 prints with N_AXIS digits
+for limit state status reports. Doing this saved about 100bytes of
+flash as well.
+
+- Applied CoreXY status reporting bug fix by @phd0. Thanks!
+
+
+----------------
+Date: 2015-05-22
+Author: Sonny Jeon
+Subject: Merge pull request #702 from ashelly/default-split
+
+Moving defaults to individual files in subdirectory
+
+----------------
+Date: 2015-05-22
+Author: ashelly
+Subject: Moving defaults to individual files in subdirectory
+
+
+----------------
+Date: 2015-05-22
+Author: Sonny Jeon
+Subject: Merge pull request #700 from ashelly/header-split
+
+Header split
+
+----------------
+Date: 2015-05-22
+Author: ashelly
+Subject: Fixing up comment blocks in headers
+
+
+----------------
+Date: 2015-05-22
+Author: ashelly
+Subject: Splitting Cpu map into separate files.
+
+Makes comparison, addition of new ones easier
+
+
+----------------
+Date: 2015-05-17
+Author: Sonny Jeon
+Subject: Critical M0/2/30 fix. Homing updates.
+
+- Critical fix for M0 program pause. Due to its recent change, it would
+cause Grbl to suspend but wouldn’t notify the user of why Grbl was not
+doing anything. The state would show IDLE and a cycle start would
+resume it. Grbl now enters a HOLD state to better indicate the state
+change.
+
+- Critical fix for M2 and M30 program end. As with M0, the state
+previously would show IDLE while suspended. Grbl now does not suspend
+upon program end and leaves job control to the GUI. Grbl simply reports
+a `[Pgm End]` as a feedback message and resets certain g-code modes.
+
+- M2/30 g-code reseting fix. Previously Grbl would soft-reset after an
+M2/30, but this was not complaint to the (linuxcnc) g-code standard. It
+simply resets [G1,G17,G90,G94,G40,G54,M5,M9,M48] and keeps all other
+modes the same.
+
+- M0/M2/M30 check-mode fix. It now does not suspend the machine during
+check-mode.
+
+- Minor bug fix related to commands similar to G90.1, but not G90.1,
+not reporting an unsupported command.
+
+- Homing cycle refactoring. To help reduce the chance of users
+misunderstanding their limit switch wiring, Grbl only moves a short
+distance for the locate cycles only. In addition, the homing cycle
+pulls-off the limit switch by the pull-off distance to re-engage and
+locate home. This should improve its accuracy.
+
+- HOMING_FORCE_ORIGIN now sets the origin to the pull-off location,
+rather than where the limit switch was triggered.
+
+- Updated default junction deviation to 0.01mm. Recent tests showed
+that this improves Grbl’s cornering behavior a bit.
+
+- Added the ShapeOko3 defaults.
+
+- Added new feedback message `[Pgm End]` for M2/30 notification.
+
+- Limit pin reporting is now a $10 status report option. Requested by
+OEMs to help simplify support troubleshooting.
+
+
+----------------
+Date: 2015-03-29
+Author: Sonny Jeon
+Subject: Fix for limit pin reporting compile-option
+
+- The limit pin reporting wasn’t working correctly due to calling the
+wrong similarly-named function. Verified to be working now.
+
+
+----------------
+Date: 2015-03-29
+Author: Sonny Jeon
+Subject: Commit history, logo license, full-arc fix.
+
+- Commit history added to repo, as an easier way for people to see view
+the changes over time.
+
+- Grbl logo copyright license added. All rights reserved with regards
+to the Grbl logo.
+
+- G2/3 full circles would sometime not execute. The problem was due to
+numerical round-off of a trig calculation. Added a machine epsilon
+define to help detect and correct for this problem. Tested and should
+not effect general operation of arcs.
+
+
+----------------
+Date: 2015-03-27
+Author: Sungeun Jeon
+Subject: Compile-option for inverting spindle enable.
+
+- Installed a compile-option for inverting the spindle enable pin for
+certain electronics boards users have reported needing this.
+
+
+----------------
+Date: 2015-03-27
+Author: Sungeun Jeon
+Subject: New compile options and inverse time bug fix.
+
+- Apparently inverse time motion were not working for quite some time.
+Goes to show how many people actually use it. The calculation was bad
+and is now fixed in this update. It should now work correctly.
+
+- `;` comment type is now supported. This is standard on LinuxCNC and
+common on 3d printers. It was previously not supported due to not
+existing in the NIST standard, which is out-dated.
+
+- New compile-option to ECHO the line received. This should help users
+experiencing very weird problems and help diagnose if there is
+something amiss in the communication to Grbl.
+
+- New compile-option to use the spindle direction pin D13 as a spindle
+enable pin with PWM spindle speed on D11. This feature has been
+requested often from the laser cutter community. Since spindle
+direction isn’t really of much use, it seemed like good good trade.
+Note that M4 spindle enable counter-clock-wise support is removed for
+obvious reasons, while M3 and M5 still work.
+
+
+----------------
+Date: 2015-03-27
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2015-03-26
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2015-03-16
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2015-03-15
+Author: Sungeun Jeon
+Subject: Updated README
+
+
+----------------
+Date: 2015-03-15
+Author: Sonny Jeon
+Subject: Create README.md
+
+----------------
+Date: 2015-03-15
+Author: Sungeun Jeon
+Subject: Merge branch 'edge'
+
+
+----------------
+Date: 2015-03-15
+Author: Sungeun Jeon
+Subject: Updated README.
+
+- Also altered the G38.X reporting to save some bytes.
+
+
+----------------
+Date: 2015-03-14
+Author: Sungeun Jeon
+Subject: Cleaned-up limit pin reporting and comments.
+
+- Cleaned up the limit pin state reporting option to display only the
+state per axis, rather than the whole port. It’s organized by an XYZ
+order, 0(low)-1(high), and generally looks like `Lim:001`.
+
+- Separated the control pin state reporting from limit state reporting
+as a new compile option. This stayed the same in terms of showing the
+entire port in binary, since it’s not anticipated that this will be
+used much, if at all.
+
+- Updated some of the gcode source comments regarding supported g-codes.
+
+
+----------------
+Date: 2015-03-07
+Author: Sonny Jeon
+Subject: Another homing cycle fix.
+
+- The homing cycle should be working again. Reverted it back to how it
+was about a month ago before I started to fiddle with it. Turns out
+that my past self knew what he was doing.
+
+
+----------------
+Date: 2015-03-04
+Author: Sonny Jeon
+Subject: Arduino IDE compatibility and minor homing fixes
+
+- Added an include in the right spot, if a user tries to compile and
+upload Grbl through the Arduino IDE with the old way.
+
+- Fixed a minor bug with homing max travel calculations. It was causing
+simultaneous axes homing to move slow than it did before.
+
+
+----------------
+Date: 2015-02-25
+Author: Sonny Jeon
+Subject: G91.1 support. Fixed a config.h option.
+
+- G91.1 support added. This g-code sets the arc IJK distance mode to
+incremental, which is the default already. This simply  helps reduce
+parsing errors with certain CAM programs that output this command.
+
+- Max step rate checks weren’t being compiled in if the option was
+enabled. Fixed now.
+
+- Alarm codes were not displaying correctly when GUI reporting mode was
+enabled. Due to unsigned int problem. Changed codes to positive values
+since they aren’t shared with other codes.
+
+
+----------------
+Date: 2015-02-23
+Author: Sonny Jeon
+Subject: Fixed config.h to Grbl release defaults.
+
+- REPORT_GUI_MODE was accidentally enabled, when it shouldn’t have.
+
+
+----------------
+Date: 2015-02-23
+Author: Sonny Jeon
+Subject: New configuration options.
+
+- New configuration option at compile-time:
+ - Force alarm upon power-up or hard reset. When homing is enabled,
+this is already the default behavior. This simply forces this all of
+the time.
+ - GUI reporting mode. Removes most human-readable strings that GUIs
+don’t need. This saves nearly 2KB in flash space that can be used for
+other features.
+ - Hard limit force state check: In the hard limit pin change ISR, Grbl
+by default sets the hard limit alarm upon any pin change to guarantee
+the alarm is set. If this option is set, it’ll check the state within
+the ISR, but can’t guarantee the pin will be read correctly if the
+switch is bouncing. This option makes hard limit behavior a little less
+annoying if you have a good buffered switch circuit that removes
+bouncing and electronic noise.
+
+- Software debounce bug fix. It was reading the pin incorrectly for the
+setting.
+
+- Re-factored some of the ‘$’ settings code.
+
+
+----------------
+Date: 2015-02-15
+Author: Sonny Jeon
+Subject: Improved homing limit search handling.
+
+- Instead of a single overall max travel for a search distance for the
+homing limit switches. The homing cycle now applies the max travel of
+each axis to the search target. Generally makes more sense this way and
+saved more than a 100bytes of flash too.
+
+
+----------------
+Date: 2015-02-15
+Author: Sonny Jeon
+Subject: Homing alarm upon no switch. Licensing update.
+
+- Homing cycle failure reports alarm feedback when the homing cycle is
+exited via a reset, interrupted by a safety door switch, or does not
+find the limit switch.
+
+- Homing cycle bug fix when not finding the limit switch. It would just
+idle before, but now will exit with an alarm.
+
+- Licensing update. Corrected licensing according to lawyer
+recommendations. Removed references to other Grbl versions.
+
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Merge pull request #593 from poelstra/fix_makefile_deps
+
+Fix generating header dependencies, merge with 'normal' compile, force r...
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Updated README with new logo sized for github.
+
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Doc re-org. New Grbl Logos!
+
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Merge pull request #591 from EliteEng/edge
+
+Safety Door Update for Mega2560
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Merge pull request #592 from poelstra/fix_softlimit
+
+Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error.
+
+----------------
+Date: 2015-02-13
+Author: Sonny Jeon
+Subject: Merge pull request #594 from poelstra/fix_sim_build
+
+Fix function signature of print_uint32_base10(), necessary for compiling simulator.
+
+----------------
+Date: 2015-02-13
+Author: Martin Poelstra
+Subject: Fix function signature of print_uint32_base10(), necessary for compiling simulator.
+
+
+----------------
+Date: 2015-02-13
+Author: Martin Poelstra
+Subject: Fix generating header dependencies, merge with 'normal' compile, force recompile when files are removed.
+
+
+----------------
+Date: 2015-02-13
+Author: Martin Poelstra
+Subject: Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error.
+
+
+----------------
+Date: 2015-02-13
+Author: Rob Brown
+Subject: Safety Door Update for Mega2560
+
+
+----------------
+Date: 2015-02-11
+Author: Sonny Jeon
+Subject: Overhauled state machine. New safety door feature.
+
+- Overhauled the state machine and cleaned up its overall operation.
+This involved creating a new ‘suspend’ state for what all external
+commands, except real-time commands, are ignored. All hold type states
+enter this suspend state.
+
+- Removed ‘auto cycle start’ setting from Grbl. This was not used by
+users in its intended way and is somewhat redundant, as GUI manage the
+cycle start by streaming. It also muddled up how Grbl should interpret
+how and when to execute a g-code block. Removing it made everything
+much much simpler.
+
+- Fixed a program pause bug when used with other buffer_sync commands.
+
+- New safety door feature for OEMs. Immediately forces a feed hold and
+then de-energizes the machine. Resuming is blocked until the door is
+closed. When it is, it re-energizes the system and then resumes on the
+normal toolpath.
+
+- Safety door input pin is optional and uses the feed hold pin on A1.
+Enabled by config.h define.
+
+- Spindle and coolant re-energizing upon a safety door resume has a
+programmable delay time to allow for complete spin up to rpm and
+turning on the coolant before resuming motion.
+
+- Safety door-style feed holds can be used instead of regular feed hold
+(doesn’t de-energize the machine) with a ‘@‘ character. If the safety
+door input pin is not enabled, the system can be resumed at any time.
+
+
+----------------
+Date: 2015-02-10
+Author: Sonny Jeon
+Subject: Git fix for empty directory. Makefile updated.
+
+- ‘build’ directory was not being synced by git because it was empty.
+Added a .gitignore file in the ‘build’ directory to force git to sync
+it but keep it empty.
+
+- Updated the Makefile to not erase the .gitignore.
+
+
+----------------
+Date: 2015-02-10
+Author: Sonny Jeon
+Subject: File re-organization. New Makefile.
+
+- Re-organized source code files into a ‘grbl’ directory to lessen one
+step in compiling Grbl through the Arduino IDE.
+
+- Added an ‘examples’ directory with an upload .INO sketch to further
+simplify compiling and uploading Grbl via the Arduino IDE.
+
+- Updated the Makefile with regard to the source code no longer being
+in the root directory. All files generated by compiling is placed in a
+separate ‘build’ directory to keep things tidy. The makefile should
+operate in the same way as it did before.
+
+
+----------------
+Date: 2015-02-10
+Author: Sonny Jeon
+Subject: Bug fix for certain motions. Re-org of includes.
+
+- Critical bug fix for diagonal motions that continue on the same
+direction or return in the exact opposite direction. This issue could
+cause Grbl to crash intermittently due to a numerical round-off error.
+Grbl versions prior to v0.9g shouldn’t have this issue.
+
+- Reorganized all of the includes used by Grbl. Centralized it into a
+single “grbl.h” include. This will help simplify the compiling and
+uploading process through the Arduino IDE.
+
+- Added an example .INO file for users to simply open and run when
+compiling and uploading through the IDE. More to come later.
+
+
+----------------
+Date: 2015-02-06
+Author: Sonny Jeon
+Subject: Limit/control pin state reporting option
+
+- As a setup feature, users can compile-in input pin status reporting.
+Doesn’t do anything special, just prints the binary for the port. 0’s
+and 1’s indicate low and high signals on the pins. It’s a bit cryptic
+right now, but it’s just a start.
+
+- Added a max step rate check when writing step/mm and max rate
+settings. Should help avoid people misdiagnosing problems associated
+with going over the 30kHz step rate limit. Right now not enabled. Takes
+up over 100k of flash. Need that room for other things right now.
+
+
+----------------
+Date: 2015-02-04
+Author: Sonny Jeon
+Subject: Rare planner bug fix and added simulator defaults.
+
+- Planner bug when moving along a diagonal back and forth on the same
+path. Rare for the fact that most CAM programs don’t program this type
+of motion, neither does jogging. Fixed in this update.
+
+- Added grbl_sim defaults for testing purposes.
+
+
+----------------
+Date: 2015-01-17
+Author: Sonny Jeon
+Subject: Fully configurable pins for NO or NC switches.
+
+- All pins, which include limits, control command, and probe pins, can
+now all be configured to trigger as active-low or active-high and
+whether the pin has its internal pull-up resistor enabled. This should
+allow for just about all types of NO and NC switch configurations.
+
+- The probe pin invert setting hasn’t been added to the Grbl settings,
+like the others, and will have to wait until v1.0. But for now, it’s
+available as a compile-time option in config.h.
+
+- Fixed a variable spindle bug.
+
+
+----------------
+Date: 2015-01-14
+Author: Sonny Jeon
+Subject: Lot of refactoring for the future. CoreXY support.
+
+- Rudimentary CoreXY kinematics support. Didn’t test, but homing and
+feed holds should work. See config.h. Please report successes and
+issues as we find bugs.
+
+- G40 (disable cutter comp) is now “supported”. Meaning that Grbl will
+no longer issue an error when typically sent in g-code program header.
+
+- Refactored coolant and spindle state setting into separate functions
+for future features.
+
+- Configuration option for fixing homing behavior when there are two
+limit switches on the same axis sharing an input pin.
+
+- Created a new “grbl.h” that will eventually be used as the main
+include file for Grbl. Also will help simply uploading through the
+Arduino IDE
+
+- Separated out the alarms execution flags from the realtime (used be
+called runtime) execution flag variable. Now reports exactly what
+caused the alarm. Expandable for new alarms later on.
+
+- Refactored the homing cycle to support CoreXY.
+
+- Applied @EliteEng updates to Mega2560 support. Some pins were
+reconfigured.
+
+- Created a central step to position and vice versa function. Needed
+for non-traditional cartesian machines. Should make it easier later.
+
+- Removed the new CPU map for the Uno. No longer going to used. There
+will be only one configuration to keep things uniform.
+
+
+----------------
+Date: 2014-11-05
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-10-29
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-10-28
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-10-28
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2014-10-01
+Author: Sonny Jeon
+Subject: Updated variable spindle and new probing. Minor bug fixes.
+
+- Minor bug fix for variable spindle PWM output. Values smaller than
+the minimum RPM for the spindle would overflow the PWM value. Thanks
+Rob!
+
+- Created an optional minimum spindle PWM low-mark value as a
+compile-time option. This is for special circumstances when the PWM has
+to be at a certain level to be read by the spindle controller.
+
+- Refactored the new probing commands (G38.3, G38.4, G38.5) code to
+work better with the rest of Grbl’s systems.
+
+- Refactored mc_probe() and mc_arc() to accept the mode of the command,
+i.e. clockwise vs counter, toward vs away, etc. This is to make these
+functions independent of gcode state variables.
+
+- Removed the pull off motion in the probing cycle. This is not an
+official operation and was added for user simplicity, but wrongly did
+so. So bye bye.
+
+- Created a configure probe invert mask function to handle the
+different probe pin setting and probing cycle modes with a single mask.
+
+ - Minor bug fix with reporting motion modes via $G. G38.2 wasn’t
+showing up. It now does, along with the other new probing commands.
+
+- Refactored some of the new pin configurations for the future of Grbl.
+
+-
+
+
+----------------
+Date: 2014-09-25
+Author: Sonny Jeon
+Subject: Merge pull request #491 from tmpvar/G38.2+
+
+G38.2+
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: report probe_succeeded with probe status
+
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: add probe_finalize to keep things DRY
+
+this allows the PRB report to be valid when in "no errors" mode and the probe fails
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: hop over probe pull-off sequence after probe miss
+
+and while "no errors" is enabled (G38.3, G38.5)
+
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: add/install probe_errors_enabled in mc_probe_cycle
+
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: bump mantissa to uint16_t to enable G38.5
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: test only for & PROBE_ACTIVE
+
+
+----------------
+Date: 2014-09-22
+Author: Elijah Insua
+Subject: cleanup global var and push probe mode into probe_get_state
+
+
+----------------
+Date: 2014-09-20
+Author: Sonny Jeon
+Subject: Edit hard limit check at start of homing cycle
+
+
+----------------
+Date: 2014-09-20
+Author: Sonny Jeon
+Subject: Merge pull request #494 from ashelly/homing-alarm
+
+Alarm if limits engaged on homing start.
+
+----------------
+Date: 2014-09-20
+Author: Sonny Jeon
+Subject: Merge pull request #493 from alpharesearch/edge
+
+If variable spindle is defined print S value via $G command.
+
+----------------
+Date: 2014-09-20
+Author: Sonny Jeon
+Subject: Minor settings number overflow bug fix.
+
+- The `x` in `$x=val` would overflow when a value larger than 255 was
+entered and passed to Grbl. This resulted with unintended parameters
+being set by the overflow value. To fix, simply check for values larger
+than 255 and error out.
+
+
+----------------
+Date: 2014-09-17
+Author: ashelly
+Subject: No false alarm if other bits in port are set.
+
+----------------
+Date: 2014-09-17
+Author: Markus Schulz
+Subject: If variable spindle is defined print S value via $G command.
+
+
+----------------
+Date: 2014-09-14
+Author: Elijah Insua
+Subject: utilize MOTION_MODE_PROBE_NO_ERROR
+
+
+----------------
+Date: 2014-09-14
+Author: Elijah Insua
+Subject: install G38.{3,4,5}
+
+
+----------------
+Date: 2014-09-14
+Author: Elijah Insua
+Subject: add MOTION_MODE_PROBE_NO_ERROR
+
+
+----------------
+Date: 2014-09-08
+Author: ashelly
+Subject: Alarm if limits engaged on homing
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v0.9j.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,17 @@
+----------------
+Date: 2015-08-14
+Author: Sonny Jeon
+Subject: Individual control pin invert compile-option.
+
+- Control pins may be individually inverted through a
+CONTROL_INVERT_MASK macro. This mask is define in the cpu_map.h file.
+
+
+----------------
+Date: 2015-07-17
+Author: Sonny Jeon
+Subject: Version bump to v0.9j
+
+- Version bump requested by OEMs to easily determine whether the
+firmware supports the new EEPROM reset feature. Other than that, no
+significant changes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v1.0b.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,140 @@
+----------------
+Date: 2015-09-30
+Author: Sonny Jeon
+Subject: Bug fixes.
+
+- G38.x was not printing correctly in the $G g-code state reports. Now
+fixed.
+
+- When investigating the above issue, it was noticed that G38.x
+wouldn’t show at all, but instead a G0 would be printed. This was
+unlike the v0.9j master build. It turned out volatile variables do not
+like to be defined inside a C struct. These are undefined on how to be
+handled. Once pulled out, all weird issues went away.
+
+- Also changed two ‘sizeof()’ statements in the mc_probe() and
+probe_state_monitor() functions to be more robust later on.
+
+- Updated the commit logs to individual files for each minor release.
+Forgot to update the generating script to account for this.
+
+
+----------------
+Date: 2015-09-30
+Author: Sonny Jeon
+Subject: Minor bug fixes.
+
+- G38.x was not printing correctly in the $G g-code state reports. Now
+fixed.
+
+- Potential bug regarding volatile variables inside a struct. It has
+never been a problem in v0.9, but ran into this during v1.0
+development. Just to be safe, the fixes are applied here.
+
+- Updated pre-built firmwares with these two bug fixes.
+
+
+----------------
+Date: 2015-09-24
+Author: Sonny Jeon
+Subject: Updated G28/G30 intermediate motion behavior.
+
+- G28 and G30’s behavior has been updated from the old NIST g-code
+standard to LinuxCNC’s. Previously when an intermediate motion was
+programmed, the NIST standard would move all axes to the final G28/30
+stored coordinates. LinuxCNC states it only moves the axes specified in
+the command.
+
+  For example, suppose G28’s stored position is (x,y,z) = (1,2,3) for
+simplicity, and we want to do an automated z-axis tool retraction and
+then park at the x,y location. `G28 G91 Z5` will first move the Z axis
+5mm(or inches) up, then move Z to position 3 in machine coordinates.
+Next, the command `G28 G91 X0 Y0` would skip the intermediate move
+since distance is zero, but then move only the x and y axes to machine
+coordinates 1 and 2, respectively. The z-axis wouldn’t move in this
+case, since it wasn’t specified.
+
+This change is intended to make Grbl more LinuxCNC compatible while
+making commands, like the shown tool retraction, much easier to
+implement.
+
+
+----------------
+Date: 2015-09-05
+Author: Sonny Jeon
+Subject: Parking motion bug fix.
+
+- Parking motion would intermittently complete the queued tool path
+upon resuming in certain scenarios. Now fixed.
+
+
+----------------
+Date: 2015-08-29
+Author: Sonny Jeon
+Subject: Optional line number reporting bug fix.
+
+- Fixed a bug where it would not compile when USE_LINE_NUMBERS was
+enabled.
+
+
+----------------
+Date: 2015-08-27
+Author: Sonny Jeon
+Subject: Update README
+
+
+----------------
+Date: 2015-08-27
+Author: Sonny Jeon
+Subject: v1.0 Beta Release.
+
+- Tons of new stuff in this release, which is fairly stable and well
+tested. However, much more is coming soon!
+
+- Real-time parking motion with safety door. When this compile option
+is enabled, an opened safety door will cause Grbl to automatically feed
+hold, retract, de-energize the spindle/coolant, and parks near Z max.
+After the door is closed and resume is commanded, this reverses and the
+program continues as if nothing happened. This is also highly
+configurable. See config.h for details.
+
+- New spindle max and min rpm ‘$’ settings! This has been requested
+often. Grbl will output 5V when commanded to turn on the spindle at its
+max rpm, and 0.02V with min rpm. The voltage and the rpm range are
+linear to each other. This should help users tweak their settings to
+get close to true rpm’s.
+
+- If the new max rpm ‘$’ setting is set = 0 or less than min rpm, the
+spindle speed PWM pin will act like a regular on/off spindle enable
+pin. On pin D11.
+
+- BEWARE: Your old EEPROM settings will be wiped! The new spindle rpm
+settings require a new settings version, so Grbl will automatically
+wipe and restore the EEPROM with the new defaults.
+
+- Control pin can now be inverted individually with a
+CONTROL_INVERT_MASK in the cpu_map header file. Not typical for users
+to need this, but handy to have.
+
+- Fixed bug when Grbl receive too many characters in a line and
+overflows. Previously it would respond with an error per overflow
+character and another acknowledge upon an EOL character. This broke the
+streaming protocol. Now fixed to only respond with an error after an
+EOL character.
+
+- Fixed a bug with the safety door during an ALARM mode. You now can’t
+home or unlock the axes until the safety door has been closed. This is
+for safety reasons (obviously.)
+
+- Tweaked some the Mega2560 cpu_map settings . Increased segment buffer
+size and fixed the spindle PWM settings to output at a higher PWM
+frequency.
+
+- Generalized the delay function used by G4 delay for use by parking
+motion. Allows non-blocking status reports and real-time control during
+re-energizing of the spindle and coolant.
+
+- Added spindle rpm max and min defaults to default.h files.
+
+- Added a new print float for rpm values.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v1.0c.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,67 @@
+----------------
+Date: 2016-03-19
+Author: Sonny Jeon
+Subject: No variable spindle and spindle speed fix.
+
+- Soft limit errors were stuck in a feed hold without notifying the
+user why it was in a hold. When resumed, the soft limit error would
+kick in. Issue should be fixed to behave as intended to automatically
+hold and issue a soft limit alarm once the machine has come to a stop.
+
+
+----------------
+Date: 2016-03-11
+Author: Sonny Jeon
+Subject: Soft limit error bug fix.
+
+- Soft limit errors were stuck in a feed hold without notifying the
+user why it was in a hold. When resumed, the soft limit error would
+kick in. Issue should be fixed to behave as intended. To automatically
+hold and issue a soft limit alarm once the machine has come to a stop.
+
+
+----------------
+Date: 2016-03-04
+Author: Sonny Jeon
+Subject: Applied master branch bug fixes.
+
+- Planner was under-estimating maximum speeds through straight
+junctions in certain cases. The calculations have been updated to be
+more accurate.
+
+- Strange sizeof() bug in the most recent releases. Manifested as an
+alarm upon a power up even when homing was disabled. Fixed by declaring
+sizeof() with struct types, rather than variable names, even though
+they were validated to give the same value.
+
+- Spindle speed zero should disable the spindle. Now fixed.
+
+- New configuration option for inverting certain limit pins. Handy for
+mixed NO and NC switch machines. See config.h for details.
+
+
+----------------
+Date: 2015-11-09
+Author: Sonny Jeon
+Subject: Pin state reporting of all pins. Flash optimization.
+
+- New pin state realtime reporting feature. Instead of `Lim:000` for
+limit state reports, the new feature shows `Pin:000|0|0000`, or
+something similar. The `|` delimited fields indicate xyz limits, probe,
+and control pin states, where 0 is always not triggered, and 1 is
+triggered. Invert masks ARE accounted for.
+  Each field may be enabled or disabled via the `$10` status report
+setting. The probe and control pin flags are bits 5 and 6, respectively.
+
+- Remove the now deprecated `REPORT_CONTROL_PIN_STATE` option in
+config.h
+
+- The old limit pin reports `Lim:000` may be re-enabled by commenting
+out `REPORT_ALL_PIN_STATES` in config.h.
+
+- Incremented the version letter (v1.0c) to indicate the change in
+reporting style.
+
+- Replaced all bit_true_atomic and bit_false_atomic macros with
+function calls. This saved a couple hundred bytes of flash.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/log/commit_log_v1.1.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1035 @@
+----------------
+Date: 2017-03-19
+Author: Sonny Jeon
+Subject: Housekeeping.
+
+- Moved Grbl logo files to a separate repo.
+
+- Added PocketNC FR4 defaults. Needs some additional work though to be
+compatible.
+
+- Updated README image links.
+
+
+----------------
+Date: 2017-03-19
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2017-03-02
+Author: Sonny Jeon
+Subject: Fixed $G report issue with M7 and M8 both enabled.
+
+[fix] When M7 and M8 are both enabled, $G report would show `M78`,
+rather than `M7 M8`. This only effects systems that enable M7 mist
+coolant in config.h. Not the default build.
+
+
+----------------
+Date: 2017-02-27
+Author: Sonny Jeon
+Subject: Fixed shared build info code.
+
+- The build info options of “two switches on an axis” and “homing init
+lock” shared the same letter ‘L’. The former is now ’T’.
+
+
+----------------
+Date: 2017-02-23
+Author: Sonny Jeon
+Subject: Restrict coincident target updates to M3 constant laser only.
+
+- Restrict M3 forced updates when there is a motion block with a
+coincident target. Force syncing of the spindle state can lead to some
+pauses during a job that has coincident targets. That’s not
+particularly desirable. This ensures M4 dynamic mode is not effected by
+this force-sync.
+
+
+----------------
+Date: 2017-02-23
+Author: Sonny Jeon
+Subject: Fixed issue with M3 laser state changes and coincident targets.
+
+[fix] When in M3 constant laser power mode, a change from G0 to G1
+would not set the laser on, if G1 was passed with a coincident target.
+Motion controller now checks for a coincident target situation and will
+force a spindle sync when detected.
+
+
+----------------
+Date: 2017-01-31
+Author: Sonny Jeon
+Subject: Additional build info in the $I printout.
+
+- [new] Added total available planner buffer blocks (15 shown, but
+there are 16. one is used by the ring buffer and to execute system
+motions) and serial RX buffer bytes. This information is useful for
+GUIs to setup and optimize their streaming protocols easily.
+
+[doc] Updated the interface document to reflect the change.
+
+
+----------------
+Date: 2017-01-29
+Author: Sonny Jeon
+Subject: Tidying up parking override control implementation
+
+[new] Added a default configuration for the parking override control
+upon a reset or power-up. By default, parking is enabled, but this may
+be disabled via a config.h option.
+
+[fix] Parking override control should be checking if the command word
+is passed, rather than the value.
+
+
+----------------
+Date: 2017-01-28
+Author: chamnit
+Subject: v1.1f. Parking override control. Spindle enable pin option.
+
+[ver] v1.1f update due to tweaks to interface from new parking override
+control.
+
+[new] Parking motion override control via new `M56 P0` and `M56 P1`
+command, which disables and enables the parking motion, respectively.
+Requires ENABLE_PARKING_OVERRIDE_CONTROL and PARKING_ENABLE enabled in
+config.h. Primarily for OEMs.
+
+[new] `M56` appears in the $G report when enabled.
+
+[new] Five new build info identification letters. Some were missing and
+a couple are new. Updated the CSV and documentation to reflect these
+new items.
+
+[new] Spindle enable pin configuration option to alter its behavior
+based on how certain lasers work. By default, Grbl treats the enable
+pin separately and leaves it on when S is 0. The new option turns the
+enable pin on and off with S>0 and S=0. This only is in effect when a
+user enables the USE_SPINDLE_DIR_AS_ENABLE_PIN option.
+
+[fix] M4 is now allowed to work when USE_SPINDLE_DIR_AS_ENABLE_PIN is
+enabled. Previously this was blocked and was problematic for laser
+folks using M4.
+
+[fix] Properly declared system variables as extern. Not sure how that
+went unnoticed or why it worked up until now but it has.
+
+[fix] EXTREMELY RARE. When AMASS is intentionally disabled and sent a
+motion command that is _one step_ in length, Grbl would not actuate the
+step due to numerical round-off. Applied a fix to prevent the round-off
+issue.
+
+[fix] Added a compile-time check for AMASS settings to make sure that
+the numerical round-off issue doesn’t effect it. This would only happen
+if someone set AMASS max levels to zero. It does not effect AMASS with
+its current defaults.
+
+[fix] Wrapped the mc_parking_motion() function in an ifdef for porting
+purposes.
+
+[fix] Fixed an issue when in inverse time mode and G0’s would require a
+F word. This was not correct.
+
+[fix] Added a note in the defaults.h file that MAX_TRAVEL values must
+be positive. Some users were setting this negative and it was causing
+issues.
+
+
+----------------
+Date: 2017-01-14
+Author: Sonny Jeon
+Subject: Tool number bug fix. Updated documentation.
+
+- [fix] Tool numbers were not being tracked and reported correctly. Now
+shows tool number values in $G when programmed.
+
+- [fix] Added a max tool number value check to the g-code parser.
+
+- [doc] Added a new error code for invalid tool number. Updated CSV and
+interface documents.
+
+- [doc] Added a implementation note for buffer state in status reports.
+Don’t rely on this data for streaming.
+
+
+----------------
+Date: 2017-01-03
+Author: Sonny Jeon
+Subject: Spindle enable pin with variable spindle option fix.
+
+- [fix] When USE_SPINDLE_DIR_AS_ENABLE_PIN is enabled in config.h, the
+enable pin was not being set when spindle speed is zero. This behavior
+should now be fixed.
+
+
+----------------
+Date: 2016-12-19
+Author: Sonny Jeon
+Subject: Fixed homing fail alarm handling. Re-integrated software debouncing.
+
+- [bug] Fixed a homing fail issue, where the alarm was not being set
+right, not cleared correctly. It would report the wrong code and enter
+an infinite alarm loop. This was due to how alarm codes were altered a
+while back. Now updated and fixed to show the right codes.
+
+- [feature] Re-installed optional software debouncing for hard limit
+switches. By request.
+
+
+----------------
+Date: 2016-12-18
+Author: Sonny Jeon
+Subject: Addressed optional PWM min value issue. Updated docs.
+
+- [fix] Spindle PWM minimum value had some typos. Fixed the macros to
+compile correctly. Only effects users that enable SPINDLE_MINIMUM_PWM.
+The name changed to SPINDLE_PWM_MIN_VALUE for consistency sake.
+
+- Updated the laser documentation.
+
+
+----------------
+Date: 2016-12-12
+Author: Sonny Jeon
+Subject: Updating steam.py streaming script
+
+- Added push message capability to the stream.py streaming script. It
+prints out as a `Debug:` string in the output.
+
+
+----------------
+Date: 2016-12-11
+Author: Sonny Jeon
+Subject: Updated documentation.
+
+
+----------------
+Date: 2016-12-10
+Author: Sonny Jeon
+Subject: Updated documentation. Cleaned up a bit.
+
+- [doc] Updated the markdown documents for the v1.1 release.
+
+- [doc] Removed references to classic GUI mode.
+
+
+----------------
+Date: 2016-12-09
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2016-12-09
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2016-12-09
+Author: Sonny Jeon
+Subject: Update README.md
+
+----------------
+Date: 2016-12-08
+Author: Sonny Jeon
+Subject: Removed classic GUI interface. Fixed typo with line number support.
+
+- [config] Permanently removed classic GUI interface support. This
+unintentionally created a problem where some users/GUI devs used this
+compatibility mode and did not update to the new interface. So, there
+were two interfaces in use, rather than just one like it was intended.
+This removal should help everyone by forcing all GUIs to update and
+updated GUI not having to support yet another interface.
+
+- Fixed typo with line number support in jog mode.
+
+
+----------------
+Date: 2016-12-04
+Author: chamnit
+Subject: Fixed unintended laser mode pausing. Updated documentation. Min SS OVR lowered to 10%.
+
+- [laser] Tested a working version and pushed the wrong one for the
+last! 20161203 was pausing upon every spindle speed change. That’s not
+right. Fixed so nearly all motions are passed through and does not stop.
+
+- Minimum spindle speed override lower from 50% to 10%. Lasers could
+use the lower speeds.
+
+- Fixed a very minor bug related to G80 error checking. Allowed no
+error with non-modal motions with axis words. Not correct and fixed.
+
+- Fixed a compile error when disabling VARIABLE_SPINDLE
+
+- [doc] Updated some obsolete documentation.
+
+- [doc] Started a “Laser Mode” document that summarizes how Grbl’s new
+laser mode works.
+
+
+----------------
+Date: 2016-12-03
+Author: Sonny Jeon
+Subject: v1.1e: New laser features. G-code parser refactoring. CoreXY homing fix.
+
+- Increment to v1.1e due to new laser features.
+
+- After several discussions with some prominent laser people, a few
+tweaks to the new laser mode has been installed.
+
+- LASER: M3 behaves in a constant power mode.
+
+- LASER: M4 behaves in a dynamic power mode, where the laser power is
+automatically adjusted based on how fast Grbl is moving relative to the
+programmed feed rate. This is the same as the  CONSTANT_POWER_PER_RATE
+config.h option in the last version. NOTE: When not in motion in M4,
+Grbl automatically turns off the laser. Again, it only operates while
+moving!
+
+- LASER: Only G1, G2, and G3 motion modes will turn on the laser. So,
+this means that G0, G80 motion modes will always keep the laser
+disabled. No matter if M3/M4 are active!
+
+- LASER: A spindle stop override is automatically invoked when a laser
+is put in a feed hold. This behavior may be disabled by a config.h
+option.
+
+- Lots of little tweaks to the g-code parser to help streamline it a
+bit. It should no effect how it operates. Generally just added a parser
+flag to track and execute certain scenarios a little more clearly.
+
+- Jog motions now allow line numbers to be passed to it and will be
+displayed in the status reports.
+
+- Fixed a CoreXY homing bug.
+
+- Fixed an issue when $13 is changed, WCO isn’t sent immediately.
+
+- Altered how spindle PWM is set in the stepper ISR. Updated on a step
+segment basis now. May need to change this back if there are any
+oddities from doing this.
+
+- Updated some documentation. Clarified why M0 no longer showing up in
+$G and why a `1.` floating point values are shown with no decimals,
+like so `1`.
+
+
+----------------
+Date: 2016-11-12
+Author: Sonny Jeon
+Subject: PWM calculation correction.
+
+- The PWM calculation was a little bit off and has been corrected.
+
+- Edited the unused settings strings to be smaller and just show what
+the settings are, rather than include units. May include this in the
+master build, if it fits.
+
+- The minimum spindle PWM define in config.h needed to be update for
+cpu map compatibilty.
+
+
+----------------
+Date: 2016-11-04
+Author: Sonny Jeon
+Subject: Fixed a g-code parser issue caused by last commit.
+
+- G-code parser refactoring in the last commit wasn’t tested. Found and
+fixed issues with G28.1/30.1 and G38.x probe commands. They were not
+being accepted due to a borked mantissa check.
+
+
+----------------
+Date: 2016-11-04
+Author: Sonny Jeon
+Subject: Improved constant laser power per rate mode. Re-factored for flash size. Minor bug fixes.
+
+- NOTE: This commit has largely been untested.
+
+- Constant laser power per rate mode has been improved. Altered its
+implementation to be more responsive and accurate.
+
+- Based on LaserWeb dev feedback, only G1, G2, and G3 moves operate
+with constant laser power mode. Meaning that G0, G38.x, and $J jogging
+motions operate without it and will keep a constant power output. This
+was specifically requested as a way to focus the laser by keeping the
+laser on when not moving. Operationally, this shouldn’t alter how the
+laser mode operates.
+
+- Re-factored parts of the g-code parser and g-code state reports to
+save a few hundred bytes of flash. What was done makes the code a bit
+more unreadable (bad), but the flash space was in dire need. So, I’m
+willing to live with it for now.
+
+- Fixed a problem with $G g-code state reports. Showed `M0` program
+pause during a run state. Now fixed to show nothing during a run state.
+Also, `M30` program end was shown as `M2`. This was also corrected.
+
+- Improved spindle stop override responsiveness by removing the
+enforced spindle restoring delay. It’s not needed for a feature that is
+user controlled.
+
+- Fixed a bug with G2/3 arcs in inverse time mode.
+
+- Updated the interface.md document to make it more clear how WPos: or
+MPos: can be calculated from WCO:. Some GUI devs have failed to catch
+this in the documentation.
+
+
+----------------
+Date: 2016-10-27
+Author: Sonny Jeon
+Subject: Spindle speed overrides behavior tweak. New experimental laser dynamic power mode.
+
+- Spindle speed overrides now update immediately if they are changed
+while in a HOLD state. Previously, they would update after exiting the
+HOLD, which isn’t correct.
+
+- New experimental dynamic laser power mode that adjusts laser power
+based on current machine speed. Enabled by uncommenting
+LASER_CONSTANT_POWER_PER_RATE in config.h
+
+  - It assumes the programmed rate is the intended power/rate for the
+motion.
+  - Feed rate overrides (FRO) do not effect the power/rate. Meaning
+that spindle PWM will automatically lower with lower FRO and increase
+with higher FRO to keep it the same.
+  - Spindle speed overrides (SSO) will directly increase and decrease
+the power/rate. So 150% SSO will increase the PWM output by 150% for
+the same speed.
+  - The combination of FRO and SSO behaviors should allow for subtle
+and highly flexible tuning of how the laser cutter is operating in
+real-time and during the job.
+
+- Re-factored planner block rapid rate handling for the dynamic laser
+power feature. Should have had no effect on how Grbl operates.
+
+
+----------------
+Date: 2016-10-26
+Author: Sonny Jeon
+Subject: Add high-frequency spindle output option. Minor parking motion re-factoring.
+
+- Some laser controllers were reported to need a very high PWM
+frequency. Added a line to enable this in cpu_map.h, if needed.
+
+- Cleaned up some of the parking code. Mostly just editing the comments.
+
+- Moved the accessory state resetting after the initial parking
+retract. Should ensure the accessory state is properly handled upon an
+aborted parking restore. Not certain if this was a problem before
+though. Just to be sure.
+
+
+----------------
+Date: 2016-10-25
+Author: chamnit
+Subject: Mandate all probe cycles ignore feed overrides.
+
+- For repeatability reasons, all G38.x probe cycles ignore feed rate
+overrides and move at their programmed speed.
+
+- The mandate can be removed with a new config.h option.
+
+- Updated the documentation to reflect the change.
+
+
+----------------
+Date: 2016-10-25
+Author: chamnit
+Subject: Resolved parking accessory handling issue.
+
+- Yikes. Totally borked the last parking “fix”. Testing shows that all
+accessories are now properly handled when retracting and restoring. It
+was caused by not accounting for the planner re-factoring correctly in
+the parking code.
+
+
+----------------
+Date: 2016-10-24
+Author: Sonny Jeon
+Subject: Minor re-factoring. Fix an issue with parking and spindle restore.
+
+- Altered the report counters to be count down, rather than count up.
+Simplified some of the logic.
+
+- Fixed an issue with parking restore. The spindle state would disable
+then reenable.
+
+- Clarified some of the config.h descriptions.
+
+- Moved the compile-time checks from config.h to grbl.h. They don’t
+belong in the config.h file.
+
+- Refactored the initialization of the system variables in main.c.
+System position and probe position were undefined when power cycled,
+but were zero anyway. Added clear vector code to make it explicit.
+
+
+----------------
+Date: 2016-10-23
+Author: Sonny Jeon
+Subject: Spindle speed close to minimum fix.
+
+- When spindle speed is close to the minimum rpm, the PWM value would
+be zero or lower than allowed. The computation error was caused by
+setting the minimum PWM value to zero, when it should have been 1.
+
+- Added a compiler check for minimum PWM to be greater than zero.
+
+- Moved some of the spindle PWM macros to a more appropriate place in
+the cpu_map.h.
+
+
+----------------
+Date: 2016-10-22
+Author: Will Winder
+Subject: Minor VARIABLE_SPINDLE feature toggle refactoring (#16)
+
+* Modify code CSV format.
+
+- Wrap value in quotes to avoid issue with embedded commas. This occurs
+  in one of the alarm codes.
+
+- Change header row format to allow same parsing code as data rows.
+
+* VARIABLE_SPINDLE feature flag experiment.
+
+- Use a macro for 'spindle_set_speed' and 'spindle_sync' to reduce the
+  number of required VARIABLE_SPINDLE checks.
+
+
+----------------
+Date: 2016-10-18
+Author: Sonny Jeon
+Subject: Improved option for v0.9 GUI compatibility.
+
+- Addressed an issue with backward compatibility with Grbl v0.9-style
+GUIs.
+
+- It still may not work due to new data and states coming back from
+Grbl v1.1. Regardless, DO NOT TRY TO USE THE COMPATIBILITY MODE UNTIL
+THERE IS A REALLY GOOD REASON TO.
+
+- v0.9 GUI compatibility mode will be removed in future versions.
+You’ve been warned. It’s highly recommended for GUIs to update to the
+new v1.1 interface.
+
+- Compability mode will only fit on an Arduino Uno due to size
+increases.
+
+- Removed the REPORT_GUI_MODE compile option since it’s part of the
+v1.1 interface standard.
+
+- Updated the documentation to better describe the compatibility mode
+build option.
+
+
+----------------
+Date: 2016-10-17
+Author: Sonny Jeon
+Subject: v1.1d: Tweaked interface a bit. Added realtime spindle speed and build option data. Minor bug fixes.
+
+- Increment to v1.1d due to interface tweaks.
+
+- Based on GUI dev feedback, the toggle overrides report was removed
+and replace with showing “accessory state”. This shows a character if a
+particular accessory is enabled, like the spindle or flood coolant.
+These can be directly altered by the toggle overrides, so when they
+execute, a GUI will be able to observe the state altering as feedback.
+
+- Altered the real-time feed rate to show real-time spindle speed as
+well. It was an over-sight on my part. It’s needed because it’s hard to
+know what the current spindle speed is when overrides are altering it.
+Especially during something like a laser cutting job when its important
+to know how spindle speed overrides are effecting things.
+
+- Real-time spindle speed is not shown if VARIABLE_SPINDLE is disabled.
+The old real-time feed rate data field will show instead.
+
+- Compile-time option data is now included in another message
+immediately following the build info version string, starting with
+`[OPT:`. A character code follows the data type name with each
+indicating a particular option enabled or disabled. This will help
+immensely with debugging Grbl as well as help GUIs know exactly how
+Grbl was compiled.
+
+- These interface changes are detailed in the updated documentation.
+
+- Reduced the default planner buffer size from 17 to 16. Needed to free
+up some memory…
+
+- For increasing the serial TX buffer size from 90 to 104 bytes. The
+addition of real-time spindle speeds and accessory enable data required
+a bigger buffer. This is to ensure Grbl is performing at optimal levels.
+
+- Refactored parts of the spindle and coolant control code to make it
+more consistent to each other and how it was called. It was a little
+messy. The changes made it easier to track what each function call was
+doing based on what was calling it.
+
+- Created a couple of new get_state functions for the spindle and
+coolant. These are called by the accessory state report to look
+directly at the pin state, rather than track how it was set. This
+guarantees that the state is reported correctly.
+
+- Updated the g-code parser, parking motion, sleep mode, and spindle
+stop calls to refactored spindle and coolant code.
+
+- Added a compile-time option to enable homing individual axes, rather
+than having only the main homing cycle. The actual use case for this is
+pretty rare. It’s not recommended you enable this, unless you have a
+specific application for it. Otherwise, just alter the homing cycle
+itself.
+
+- Refactored the printFloat() function to not show a decimal point if
+there are no trailing values after it. For example, `1.` now shows `1`.
+
+- Fixed an issue regarding spindle speed overrides no being applied to
+blocks without motions.
+
+- Removed the toggle_ovr_mask system variable and replaced with
+spindle_stop_ovr system variable. Coolant toggles don’t need to be
+tracked.
+
+- Updated README
+
+
+----------------
+Date: 2016-10-17
+Author: Will Winder
+Subject: Modify code CSV format. (#10)
+
+- Wrap value in quotes to avoid issue with embedded commas. This occurs
+  in one of the alarm codes.
+
+- Change header row format to allow same parsing code as data rows.
+
+----------------
+Date: 2016-10-12
+Author: chamnit
+Subject: Merge branch 'dev' into edge
+
+
+----------------
+Date: 2016-10-12
+Author: chamnit
+Subject: Added settings documentation. Very minor bug fix to step direction handling.
+
+- Added v1.1 settings documentation to the markdown folder.
+
+- Fixed a very minor bug in the step direction handling upon wakeup.
+The direction mask would temporarily go back to default mask for about
+a millisecond when moving in the same non-default direction. It did not
+effect Grbl behavior before, but fixed for consistency.
+
+
+----------------
+Date: 2016-10-12
+Author: Sonny Jeon
+Subject: Spindle speed bug fix.
+
+- Spindle speed updating wasn’t working in the g-code parser due to
+some borked up logic on my part. Fixed it and should be operating as
+intended for both normal and laser spindle modes.
+
+- Elaborated a little more on the new sleep mode in the documentation.
+
+
+----------------
+Date: 2016-10-11
+Author: Sonny Jeon
+Subject: v1.1c: New sleep mode. Laser mode and other bug fixes.
+
+- New $SLP sleep mode that will disable spindle, coolant, and stepper
+enable pins. Allows users to disable their steppers without having to
+alter their settings. A reset is required to exit and re-initializes in
+alarm state.
+
+- Laser mode wasn’t updating the spindle PWM correctly (effected
+spindle speed overrides) and not checking for modal states either.
+Fixed both issues.
+
+- While in laser mode, parking motions are ignored, since the power off
+delay with the retract motion would burn the material. It will just
+turn off and not move. A restore immediately powers up and resumes. No
+delays.
+
+- Changing rpm max and min settings did not update the spindle PWM
+calculations. Now fixed.
+
+- Increased default planner buffer from 16 to 17 block. It seems to be
+stable, but need to monitor this carefully.
+
+- Removed software debounce routine for limit pins. Obsolete.
+
+- Fixed a couple parking motion bugs. One related to restoring
+incorrectly and the other the parking rate wasn’t compatible with the
+planner structs.
+
+- Fixed a bug caused by refactoring the critical alarms in a recent
+push. Soft limits weren’t invoking a critical alarm.
+
+- Updated the documentation with the new sleep feature and added some
+more details to the change summary.
+
+
+----------------
+Date: 2016-09-28
+Author: Sonny Jeon
+Subject: New jog cancel real-time command. Parser typo fix from last push.
+
+- Added a new jog cancel real-time command. Rather than depending on a
+feed hold to cancel a jogging motion, this realtime command can be used
+instead. The main advantage is if a feed hold is used, you can
+accidentally hold the machine right when Grbl returns to IDLE after
+completing a jog. And the GUI doesn’t have to worry about tracking this
+either.
+
+- Fixed a typo in the g-code parser edits from the last push. Was
+causing the G10 set coordinate system command to not work correctly.
+
+- Updated the documentation with the jog cancel command.
+
+
+----------------
+Date: 2016-09-27
+Author: Sonny Jeon
+Subject: Refactored g-code parser. Saved 60bytes flash and some ram. Edited Readme.
+
+- Freed up another 60 bytes of flash and 12-24 bytes of stack RAM by
+using the pre-allocated IJK arc offset vector that is guaranteed to be
+not in use. Only G10 and G28/30 require fetching from EEPROM and
+retaining extra data. Both commands use axis words, which rules out
+G2/3 arcs using IJK offsets existing in same block. Not ideal, but
+every byte helps.
+
+- Edited README.
+
+
+----------------
+Date: 2016-09-27
+Author: Sonny Jeon
+Subject: Update README and clarifications in jogging document.
+
+
+----------------
+Date: 2016-09-26
+Author: Sonny Jeon
+Subject: v1.1b: Tweaked Bf reports, jogging doc, saved another 160 bytes, minor bug fixes
+
+- Increment to v1.1b due to status report tweak.
+
+- Tweaked the buffer state status reports to show bytes and blocks
+available, rather than in use. This does not require knowing the buffer
+sizes beforehand. It’s implicit.
+
+- Also, since buffer states are not used by most devs (after
+inquiries), it is no longer enabled by default and a status mask option
+was added for this.
+
+- Fixed some typos and updated for the report tweak in the
+documentation.
+
+- Wrote a joystick implementation concept in the jogging markdown
+document. Outlines how to get a low-latency feel to a joystick (and
+other input devices).
+
+- Removed XON/XOFF support. It’s not used by anyone because of its
+inherent problems. Remains in older versions for reference.
+
+- Added a compile option on how to handle the probe position during a
+check mode.
+
+- Fixed a jogging bug. If G93 is the modal state before a jogging
+motion, the feed rate did not get calculated correctly. Fixed the issue.
+
+- Refactored some code to save another 160+ bytes. Included an improved
+float vector comparison macro and reducing a few large and repetitive
+function calls.
+
+- Fixed a probing bug (existing in v0.9 too) where the target positions
+were not set correct and error handling was improper.
+
+
+----------------
+Date: 2016-09-25
+Author: Sonny Jeon
+Subject: Addressed much larger flash size with avr-gcc v4.9.2. Refactored reports to save 160KB.
+
+- The newest Arduino IDE 1.6.12 has recently updated to avr-gcc v4.9.2.
+Unfortunately, it produces a compiled size almost 0.7KB to 1KB larger
+than prior versions! This can easily cause the base build to exceed the
+Arduino Duemilanove/Nano flash limit of 30.5KB. The Arduino Uno seems
+to be ok still with its 31.5KB flash limit.
+
+- Makefile `-flto` compile flag added to cut down on the horrible flash
+size when using the new avr-gcc. (Edit Makefile and remove comment on
+COMPILE definition). This brings it in-line with what the IDE produces.
+
+- Functionalized repetitive tasks in report.c to try to reduce overall
+flash size. Successfully cut down about 160bytes.
+
+- Removed printFloat_SettingValue() and printFloat_RPMValue()
+functions. These aren’t required and can be replaced with a direct call
+to printFloat() because they don’t require a unit conversion check.
+
+
+----------------
+Date: 2016-09-24
+Author: Sonny Jeon
+Subject: Serial RX count bug fix. Settings codes CSV. More documentation.
+
+- Reverted back the serial RX count function to how it was. The
+variable type was unsigned and cause an integer underflow whenever the
+calculation produced a negative number. The old way was the correct way.
+
+- Lots of minor edits to the code CSVs and markdown documents.
+
+- Expanded on explaining feedback messages and startup line execution
+feedback.
+
+- Created a new settings codes CSV to help GUIs import the values and
+meanings.
+
+
+----------------
+Date: 2016-09-22
+Author: Sonny Jeon
+Subject: Increment to v1.1a, minor compile bug fix, tweaked communication protocol, more docs.
+
+- Incremented to v1.1a, rather than keep 1.0e. This is because there
+are existing v1.0 installations. Don’t want to confuse people further.
+
+- Certain version of the Arduino IDE did not like the `inline` in the
+function header. Removed from spindle_control files to fix the problem.
+
+- Tweaked the communication protocol slightly. Added message type
+indicators for all `[]`bracketed feedback messages. It’s been
+problematic for GUI dev to try to determine the context of a message
+and how it should be handled. These indictors should help tremendously
+to remove context all together.
+
+- Also altered how `$N` startup lines are presented when executed. They
+now start with an open chevron ‘>’ followed by the line and an ‘:ok’ to
+indicate it executed. The ‘ok’ is on the same line intentionally so it
+doesn’t mess up a streaming protocol counter.
+
+- Managed to save a 100+KB from refactoring parts of report.c. (Thanks
+Vasilis!) Freed up room to alter the protocol a little.
+
+- Wrote a markdown document on interface messaging to make it clear how
+it’s intended to work. See interface.md in /doc/markdown
+
+- Started to pull in some Wiki pages from the old grbl site and
+beginning to update them for v1.1.
+
+- Created new commit log for v1.1.
+
+
+----------------
+Date: 2016-09-22
+Author: Sonny Jeon
+Subject: Merge pull request #1 from winder/dev
+
+Add locale to code CSVs.
+
+----------------
+Date: 2016-09-22
+Author: winder
+Subject: Add locale to code CSVs.
+
+
+----------------
+Date: 2016-09-21
+Author: chamnit
+Subject: Grbl v1.0e huge beta release. Overrides and new reporting.
+
+- Feature: Realtime feed, rapid, and spindle speed overrides. These
+alter the running machine state within tens of milliseconds!
+    - Feed override: 100%, +/-10%, +/-1% commands with values 1-200% of
+programmed feed
+    - Rapid override: 100%, 50%, 25% rapid rate commands
+    - Spindle speed override: 100%, +/-10%, +/-1% commands with values
+50-200% of programmed speed
+    - Override values have configurable limits and increments in
+config.h.
+- Feature: Realtime toggle overrides for spindle stop, flood coolant,
+and optionally mist coolant
+    - Spindle stop: Enables and disables spindle during a feed hold.
+Automatically restores last spindles state.
+    - Flood and mist coolant: Immediately toggles coolant state until
+next toggle or g-code coolant command.
+- Feature: Jogging mode! Incremental and absolute modes supported.
+    - Grbl accepts jogging-specific commands like $J=X100F50. An axis
+word and feed rate are required. G20/21 and G90/G91 commands are
+accepted.
+    - Jog motions can be canceled at any time by a feed hold `!`
+command. The buffer is automatically flushed. (No resetting required).
+    - Jog motions do not alter the g-code parser state so GUIs don’t
+have to track what they changed and correct it.
+- Feature: Laser mode setting. Allows Grbl to execute continuous
+motions with spindle speed and state changes.
+- Feature: Significantly improved status reports. Overhauled to cram in
+more meaningful data and still make it smaller on average.
+    - All available data is now sent by default, but does not appear if
+it doesn’t change or is not active.
+    - Machine position(MPos) or work position(WPos) is reported but not
+both at the same time. Instead, the work coordinate offsets (WCO)are
+sent intermittently whenever it changes or refreshes after 10-30 status
+reports. Position vectors are easily computed by WPos  = MPos - WCO.
+    - All data has changed in some way. Details of changes are in the
+markdown documents and wiki.
+- Feature: 16 new realtime commands to control overrides. All in
+extended-ASCII character space.
+    - While they are not easily typeable and requires a GUI, they can’t
+be accidentally triggered by some latent character in the g-code
+program and have tons of room for expansion.
+- Feature: New substates for HOLD and SAFETY DOOR. A `:x` is appended
+to the state, where `x` is an integer and indicates a substate.
+    - For example, each integer of a door state describes in what phase
+the machine is in during parking. Substates are detailed in the
+documentation.
+- Feature: With the alarm codes, homing and probe alarms have been
+expanded with more codes to provide more exact feedback on what caused
+the alarm.
+- Feature: New hard limit check upon power-up or reset. If detected, a
+feedback message to check the limit switches sent immediately after the
+welcome message.
+    - May be disabled in config.h.
+
+- OEM feature: Enable/disable `$RST=` individual commands based on
+desired behavior in config.h.
+- OEM feature: Configurable EEPROM wipe to prevent certain data from
+being deleted during firmware upgrade to a new settings version or
+`RST=*` command.
+- OEM feature: Enable/disable the `$I=` build info write string with
+external EEPROM write example sketch.
+    - This prevents a user from altering the build info string in
+EEPROM. This requires the vendor to write the string to EEPROM via
+external means. An Arduino example sketch is provided to accomplish
+this. This would be useful for contain product data that is
+retrievable.
+
+- Tweak: All feedback has been drastically trimmed to free up flash
+space for the v1.0 release.
+    - The `$` help message is just one string, listing available
+commands.
+    - The `$$` settings printout no longer includes descriptions. Only
+the setting values. (Sorry it’s this or remove overrides!)
+    - Grbl `error:` and `ALARM:` responses now only contain codes. No
+descriptions. All codes are explained in documentation.
+    - Grbl’s old feedback style may be restored via a config.h, but
+keep in mind that it will likely not fit into the Arduino’s flash space.
+- Tweak: Grbl now forces a buffer sync or stop motion whenever a g-code
+command needs to update and write a value to EEPROM or changes the work
+coordinate offset.
+    - This addresses two old issues in all prior Grbl versions. First,
+an EEPROM write requires interrupts to be disabled, including stepper
+and serial comm. Steps can be lost and data can be corrupted. Second,
+the work position may not be correlated to the actual machine position,
+since machine position is derived from the actual current execution
+state, while work position is based on the g-code parser offset state.
+They are usually not in sync and the parser state is several motions
+behind. This forced sync ensures work and machine positions are always
+correct.
+    - This behavior can be disabled through a config.h option, but it’s
+not recommended to do so.
+- Tweak: To make status reports standardized, users can no longer
+change what is reported via status report mask, except for only
+toggling machine or work positions.
+    - All other data fields are included in the report and can only be
+disabled through the config.h file. It’s not recommended to alter this,
+because GUIs will be expecting this data to be present and may not be
+compatible.
+- Tweak: Homing cycle and parking motion no longer report a negative
+line number in a status report. These will now not report a line number
+at all.
+- Tweak: New `[Restoring spindle]` message when restoring from a
+spindle stop override. Provides feedback what Grbl is doing while the
+spindle is powering up and a 4.0 second delay is enforced.
+- Tweak: Override values are reset to 100% upon M2/30. This behavior
+can be disabled in config.h
+- Tweak: The planner buffer size has been reduced from 18 to 16 to free
+up RAM for tracking and controlling overrides.
+- Tweak: TX buffer size has been increased from 64 to 90 bytes to
+improve status reporting and overall performance.
+- Tweak: Removed the MOTION CANCEL state. It was redundant and didn’t
+affect Grbl’s overall operation by doing so.
+- Tweak: Grbl’s serial buffer increased by +1 internally, such that 128
+bytes means 128, not 127 due to the ring buffer implementation. Long
+overdue.
+- Tweak: Altered sys.alarm variable to be set by alarm codes, rather
+than bit flags. Simplified how it worked overall.
+- Tweak: Planner buffer and serial RX buffer usage has been combined in
+the status reports.
+- Tweak: Pin state reporting has been refactored to report only the
+pins “triggered” and nothing when not “triggered”.
+- Tweak: Current machine rate or speed is now included in every report.
+- Tweak: The work coordinate offset (WCO) and override states only need
+to be refreshed intermittently or reported when they change. The
+refresh rates may be altered for each in the config.h file with
+different idle and busy rates to lessen Grbl’s load during a job.
+- Tweak: For temporary compatibility to existing GUIs until they are
+updated, an option to revert back to the old style status reports is
+available in config.h, but not recommended for long term use.
+- Tweak: Removed old limit pin state reporting option from config.h in
+lieu of new status report that includes them.
+- Tweak: Updated the defaults.h file to include laser mode, altered
+status report mask, and fix an issue with a missing invert probe pin
+default.
+
+- Refactor: Changed how planner line data is generated and passed to
+the planner and onto the step generator. By making it a struct
+variable, this saved significant flash space.
+- Refactor: Major re-factoring of the planner to incorporate override
+values and allow for re-calculations fast enough to immediately take
+effect during operation. No small feat.
+- Refactor: Re-factored the step segment generator for re-computing new
+override states.
+- Refactor: Re-factored spindle_control.c to accommodate the spindle
+speed overrides and laser mode.
+- Refactor: Re-factored parts of the codebase for a new jogging mode.
+Still under development though and slated to be part of the official
+v1.0 release. Hang tight.
+- Refactor: Created functions for computing a unit vector and value
+limiting based on axis maximums to free up more flash.
+- Refactor: The spindle PWM is now set directly inside of the stepper
+ISR as it loads new step segments.
+- Refactor: Moved machine travel checks out of soft limits function
+into its own since jogging uses this too.
+- Refactor: Removed coolant_stop() and combined with
+coolant_set_state().
+- Refactor: The serial RX ISR forks off extended ASCII values to
+quickly assess the new override realtime commands.
+- Refactor: Altered some names of the step control flags.
+- Refactor: Improved efficiency of the serial RX get buffer count
+function.
+- Refactor: Saved significant flash by removing and combining print
+functions. Namely the uint8 base10 and base2 functions.
+- Refactor: Moved the probe state check in the main stepper ISR to
+improve its efficiency.
+- Refactor: Single character printPgmStrings() went converted to direct
+serial_write() commands to save significant flash space.
+
+- Documentation: Detailed Markdown documents on error codes, alarm
+codes, messages, new real-time commands, new status reports, and how
+jogging works. More to come later and will be posted on the Wiki as
+well.
+- Documentation: CSV files for quick importing of Grbl error and alarm
+codes.
+
+- Bug Fix: Applied v0.9 master fixes to CoreXY homing.
+- Bug Fix: The print float function would cause Grbl to crash if a
+value was 1e6 or greater. Increased the buffer by 3 bytes to help
+prevent this in the future.
+- Bug Fix: Build info and startup string EEPROM restoring was not
+writing the checksum value.
+- Bug Fix: Corrected an issue with safety door restoring the proper
+spindle and coolant state. It worked before, but breaks with laser mode
+that can continually change spindle state per planner block.
+- Bug Fix: Move system position and probe position arrays out of the
+system_t struct. Ran into some compiling errors that were hard to track
+down as to why. Moving them out fixed it.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/change_summary.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,114 @@
+### _Grbl v1.1  - Change Summary_
+
+--------
+
+### _Specific details are available in the other markdown documents._
+--------
+
+#### GUI Interface Tweaks from Grbl v0.9
+
+Grbl v1.1's interface protocol has been tweaked in the attempt to make GUI development cleaner, clearer, and hopefully easier. All messages are designed to be deterministic without needing to know the context of the message. Each can be inferred to a much greater degree than before just by the message type, which are all listed below.
+
+- `ok` / `error:x` : Normal send command and execution response acknowledgement. Used for streaming.
+
+- `< >` : Enclosed chevrons contains status report data.
+
+- `Grbl X.Xx ['$' for help]` : Welcome message indicates initialization.
+
+- `ALARM:x` : Indicates an alarm has been thrown. Grbl is now in an alarm state.
+
+- `$x=val` and `$Nx=line` indicate a settings printout from a `$` and `$N` user query, respectively.
+
+- `[MSG:]` : Indicates a non-queried feedback message.
+
+- `[GC:]` : Indicates a queried `$G` g-code state message.
+
+- `[HLP:]` : Indicates the help message.
+
+- `[G54:]`, `[G55:]`, `[G56:]`, `[G57:]`, `[G58:]`, `[G59:]`, `[G28:]`, `[G30:]`, `[G92:]`, `[TLO:]`, and `[PRB:]` messages indicate the parameter data printout from a `$#` user query.
+
+- `[VER:]` : Indicates build info and string from a `$I` user query.
+
+- `[OPT:]` : Indicates compile-time option info from a `$I` user query.
+
+- `[echo:]` : Indicates an automated line echo from a pre-parsed string prior to g-code parsing. Enabled by config.h option.
+
+- `>G54G20:ok` : The open chevron indicates startup line execution. The `:ok` suffix shows it executed correctly without adding an unmatched `ok` response on a new line.
+
+In addition, all `$x=val` settings, `error:`, and `ALARM:` messages no longer contain human-readable strings, but rather codes that are defined in other documents. The `$` help message is also reduced to just showing the available commands. Doing this saves incredible amounts of flash space. Otherwise, the new overrides features would not have fit.
+
+Other minor changes and bug fixes that may effect GUI parsing include:
+
+- Floating point values printed with zero precision do not show a decimal, or look like an integer. This includes spindle speed RPM and feed rate in mm mode.
+- `$G` reports fixed a long time bug with program modal state. It always showed `M0` program pause when running. Now during a normal program run, no program modal state is given until an `M0`, `M2`, or `M30` is active and then the appropriate state will be shown.
+
+On a final note, these interface tweaks came about out of necessity, because more data is being sent back from Grbl, it is capable of doing many more things, and flash space is at a premium. It's not intended to be altered again in the near future, if at all. This is likely the only and last major change to this. If you have any comments or suggestions before Grbl v1.1 goes to master, please do immediately so we can all vet the new alteration before its installed.
+
+----
+
+#### Realtime Status Reports Changes from Grbl v0.9
+
+- Intent of changes is to make parsing cleaner, reduce transmitting overhead without effecting overall Grbl performance, and add more feedback data, which includes three new override values and real-time velocity.
+
+- Data fields are separated by `|` pipe delimiters, rather than `,` commas that were used to separate data values. This should help with parsing.
+
+- The ability to mask and add/remove data fields from status reports via the `$10` status report mask setting has been disabled. Only selecting `MPos:` or `WPos:` coordinates is allowed.
+  - All available data is always sent to standardize the reports across all GUIs.
+  - For unique situations, data fields can be removed by config.h macros, but it is highly recommended to not alter these.
+
+
+- `MPos:` OR `WPos:` are always included in a report, but not BOTH at the same time.
+
+  - This reduces transmit overhead tremendously by removing upwards to 40 characters.
+  - `WCO:0.000,10.000,2.500` A current work coordinate offset is now sent to easily convert between position vectors, where `WPos = MPos - WCO` for each axis.
+    - `WCO:` is included immediately whenever a `WCO:` value changes or intermittently after every **X** status reports as a refresh. Refresh rates can dynamically vary from 10 to 30 (configurable) reports depending on what Grbl is doing.
+    - `WCO:` is simply the sum of the work coordinate system, G92, and G43.1 tool length offsets.
+    - Basically, a GUI just needs to retain the last `WCO:` and apply the equation to get the other position vector.
+    - `WCO:` messages may only be disabled via a config.h compile-option, if a GUI wants to handle the work position calculations on its own to free up more transmit bandwidth.
+  - Be aware of the following issue regarding `WPos:`.
+    - In Grbl v0.9 and prior, there is an old outstanding bug where the `WPos:` work position reported may not correlate to what is executing, because `WPos:` is based on the g-code parser state, which can be several motions behind. Grbl v1.1 now forces the planner buffer to empty, sync, and stops motion whenever there is a command that alters the work coordinate offsets `G10,G43.1,G92,G54-59`. This is the simplest way to ensure `WPos:` is always correct. Fortunately, it's exceedingly rare that any of these commands are used need continuous motions through them.
+    - A compile-time option is available to disable the planner sync and forced stop, but, if used, it's up to the GUI to handle this position correlation issue.
+
+
+- The `Hold` and `Door` states includes useful sub-state info via a `:` colon delimiter and an integer value. See descriptions for details.
+
+- Limit and other input pin reports have significantly changed to reduce transmit overhead.
+  - The data type description is now just `Pn:`, rather than `Lim:000` or `Pin:000|0|0000`
+  - It does not appear if no inputs are detected as triggered.
+  - If an input is triggered, ```Pn:``` will be followed by a letter or set of letters of every triggered input pin. `XYZPDHRS` for the XYZ-axes limits, Probe, Door, Hold, soft-Reset, cycle Start pins, respectively.
+  - For example, a triggered Z-limit and probe pin would report `Pn:ZP`.
+
+
+- Buffer data (planner and serial RX) reports have been tweaked and combined.
+
+  - `Bf:15,128`. The first value is the available blocks in the planner buffer and the second is available bytes in the serial RX buffer.
+  - Note that this is different than before, where it reported blocks/bytes "in-use", rather than "available". This change does not require a GUI to know how many blocks/bytes Grbl has been compiled with, which can be substantially different on a Grbl-Mega build.
+
+
+- Override reports are intermittent since they don't change often once set.
+
+  - Overrides are included in every 10 or 20 status reports (configurable) depending on what Grbl is doing or, if an override value or toggle state changes, automatically in the next report.
+  - There are two override fields:
+    - `Ov:100,100,100` Organized as feed, rapid, and spindle speed overrides in percent.
+    
+- Accessory states are shown alongside override reports when they are active. Like pin states, an accessory state report `A:SFM` contains a letter indicating an active accessory. Letters `S`, `C`, `F`, and `M` are defined as spindle CW, spindle CCW, flood coolant, and mist coolant, respectively. The pins are directly polled and shown here.
+
+- Line numbers, when enabled in config.h, are omitted when:
+
+  - No line number is passed to Grbl in a block.
+  - Grbl is performing a system motion like homing, jogging, or parking.
+  - Grbl is executing g-code block that does not contain a motion, like `G20G54` or `G4P1` dwell. (NOTE: Looking to fixing this later.)
+
+-------
+
+#### New Commands
+
+- `$SLP` - Grbl v1.1 now has a sleep mode that can be invoked by this command. It requires Grbl to be in either an IDLE or ALARM state. Once invoked, Grbl will de-energize all connected systems, including the spindle, coolant, and stepper drivers. It'll enter a suspend state that can only be exited by a reset. When reset, Grbl will re-initiatize in an ALARM state because the steppers were disabled and position can not be guaranteed.
+	-  NOTE: Grbl-Mega can invoke the sleep mode at any time, when the sleep timeout feature is enabled in config.h. It does so when Grbl has not received any external input after a timeout period.
+
+- 	`$J=line` New jogging commands. This command behaves much like a normal G1 command, but there are some key differences. Jog commands don't alter the g-code parser state, meaning a GUI doesn't have to manage it anymore. Jog commands may be queued and cancelled at any time, where they are automatically flushed from the planner buffer without requiring a reset. See the jogging documentation on how they work and how they may be used to implement a low-latency joystick or rotary dial.
+
+- Laser mode `$` setting - When enabled, laser mode will move through consecutive G1, G2, and G3 motion commands that have different spindle speed values without stopping. A spindle speed of zero will disable the laser without stopping as well. However, when spindle states change, like M3 or M5, stops are still enforced.
+	- NOTE: Parking motions are automatically disabled when laser mode is enabled to prevent burning.
+	
+- `G56 P1` and `G56 P0` - When enabled in config.h with Grbl's parking motion, these commands enable and disable, respectively, the parking motion. Like all override control commands, these commands are modal and are part of the g-code stream.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/commands.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,345 @@
+# Grbl v1.1 Commands
+
+In general, Grbl assumes all characters and streaming data sent to it is g-code and will parse and try to execute it as soon as it can. However, Grbl also has two separate system command types that are outside of the normal g-code streaming. One system command type is streamed to Grbl like g-code, but starts with a `$` character to tell Grbl it's not g-code. The other is composed of a special set of characters that will immediately command Grbl to do a task in real-time. It's not part of the g-code stream. Grbl's system commands do things like control machine state, report saved parameters or what Grbl is doing, save or print machine settings, run a homing cycle, or make the machine move faster or slower than programmed. This document describes these "internal" system Grbl commands, what they do, how they work, and how to use them.
+
+## Getting Started
+
+First, connect to Grbl using the serial terminal of your choice.
+
+Set the baud rate  to **115200** as 8-N-1 (8-bits, no parity, and 1-stop bit.)
+
+Once connected
+ you should get the Grbl-prompt, which looks like this:
+
+```
+Grbl 1.1e ['$' for help]
+```
+
+Type $ and press enter to have Grbl print a help message. You should not see any local echo of the $ and enter. Grbl should respond with:
+
+```
+[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]
+```
+
+The ‘$’-commands are Grbl system commands used to tweak the settings, view or change Grbl's states and running modes, and start a homing cycle. The last four **non**-'$' commands are realtime control commands that can be sent at anytime, no matter what Grbl is doing. These either immediately change Grbl's running behavior or immediately print a report of the important realtime data like current position (aka DRO). There are over a dozen more realtime control commands, but they are not user type-able. See realtime command section for details.
+
+***
+
+## Grbl '$' Commands
+
+The `$` system commands provide additional controls for the user, such as printing feedback on the current G-code parser modal state or running the homing cycle. This section explains what these commands are and how to use them.
+
+#### `$$`and `$x=val` - View and write Grbl settings
+See [Grbl v1.1 Configuration](https://github.com/gnea/grbl/wiki/Grbl-v1.1-Configuration#grbl-settings) for more details on how to view and write setting and learn what they are.
+
+#### `$#` - View gcode parameters
+
+G-code parameters store the coordinate offset values for G54-G59 work coordinates, G28/G30 pre-defined positions, G92 coordinate offset, tool length offsets, and probing (not officially, but we added here anyway). Most of these parameters are directly written to EEPROM anytime they are changed and are persistent. Meaning that they will remain the same, regardless of power-down, until they are explicitly changed. The non-persistent parameters, which will are not retained when reset or power-cycled, are G92, G43.1 tool length offsets, and the G38.2 probing data.
+
+G54-G59 work coordinates can be changed via the `G10 L2 Px` or `G10 L20 Px` command defined by the NIST gcode standard and the EMC2 (linuxcnc.org) standard. G28/G30 pre-defined positions can be changed via the `G28.1` and the `G30.1` commands, respectively.
+
+When `$#` is called, Grbl will respond with the stored offsets from machine coordinates for each system as follows. `TLO` denotes tool length offset (for the default z-axis), and `PRB` denotes the coordinates of the last probing cycle, where the suffix `:1` denotes if the last probe was successful and `:0` as not successful.
+
+```
+[G54:4.000,0.000,0.000]
+[G55:4.000,6.000,7.000]
+[G56:0.000,0.000,0.000]
+[G57:0.000,0.000,0.000]
+[G58:0.000,0.000,0.000]
+[G59:0.000,0.000,0.000]
+[G28:1.000,2.000,0.000]
+[G30:4.000,6.000,0.000]
+[G92:0.000,0.000,0.000]
+[TLO:0.000]
+[PRB:0.000,0.000,0.000:0]
+```
+
+#### `$G` - View gcode parser state
+
+This command prints all of the active gcode modes in Grbl's G-code parser. When sending this command to Grbl, it will reply with a message starting with an `[GC:` indicator like: 
+
+```
+[GC:G0 G54 G17 G21 G90 G94 M0 M5 M9 T0 S0.0 F500.0]
+```
+
+These active modes determine how the next G-code block or command will be interpreted by Grbl's G-code parser. For those new to G-code and CNC machining, modes sets the parser into a particular state so you don't have to constantly tell the parser how to parse it. These modes are organized into sets called "modal groups" that cannot be logically active at the same time. For example, the units modal group sets whether your G-code program is interpreted in inches or in millimeters.
+
+A short list of the modal groups, supported by Grbl, is shown below, but more complete and detailed descriptions can be found at LinuxCNC's [website](http://www.linuxcnc.org/docs/2.4/html/gcode_overview.html#sec:Modal-Groups). The G-code commands in **bold** indicate the default modes upon powering-up Grbl or resetting it. The commands in _italics_ indicate a special Grbl-only command.
+
+| Modal Group Meaning	|  Member Words |
+|:----:|:----:|
+| Motion Mode | **G0**, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80 |
+|Coordinate System Select	| **G54**, G55, G56, G57, G58, G59|
+|Plane Select	| **G17**, G18, G19|
+|Distance Mode	| **G90**, G91|
+|Arc IJK Distance Mode | **G91.1** |
+|Feed Rate Mode	| G93, **G94**|
+|Units Mode	| G20, **G21**|
+|Cutter Radius Compensation | **G40** |
+|Tool Length Offset |G43.1, **G49**|
+|Program Mode | **M0**, M1, M2, M30|
+|Spindle State |M3, M4, **M5**|
+|Coolant State	| M7, M8, **M9** |
+|Override Control | _M56_ |
+
+Grbl supports a special _M56_ override control command, where this enables and disables Grbl's parking motion when a `P1` or a `P0` is passed with `M56`, respectively. This command is only available when both parking and this particular option is enabled.
+
+In addition to the G-code parser modes, Grbl will report the active `T` tool number, `S` spindle speed, and `F` feed rate, which all default to 0 upon a reset. For those that are curious, these don't quite fit into nice modal groups, but are just as important for determining the parser state.
+
+#### `$I` - View build info
+This prints feedback to the user the Grbl version and source code build date. Optionally, `$I` can also store a short string to help identify which CNC machine you are communicating with, if you have more than machine using Grbl. To set this string, send Grbl `$I=xxx`, where `xxx` is your customization string that is less than 80 characters. The next time you query Grbl with a `$I` view build info, Grbl will print this string after the version and build date.
+
+NOTE: Some OEMs may block access to over-writing the build info string so they can store product information and codes there.
+
+#### $N - View startup blocks
+
+`$Nx` are the startup blocks that Grbl runs every time you power on Grbl or reset Grbl. In other words, a startup block is a line of G-code that you can have Grbl auto-magically run to set your G-code modal defaults, or anything else you need Grbl to do everytime you start up your machine. Grbl can store two blocks of G-code as a system default.
+
+So, when connected to Grbl, type `$N` and then enter. Grbl should respond with something short like:
+```
+$N0=
+$N1=
+ok
+```
+Not much to go on, but this just means that there is no G-code block stored in line `$N0` for Grbl to run upon startup. `$N1` is the next line to be run.
+
+#### $Nx=line - Save startup block
+
+**IMPORTANT: Be very careful when storing any motion (G0/1,G2/3,G28/30) commands in the startup blocks. These motion commands will run everytime you reset or power up Grbl, so if you have an emergency situation and have to e-stop and reset, a startup block move can and will likely make things worse quickly. Also, do not place any commands that save data to EEPROM, such as G10/G28.1/G30.1. This will cause Grbl to constantly re-write this data upon every startup and reset, which will eventually wear out your Arduino's EEPROM.**
+
+**Typical usage for a startup block is simply to set your preferred modal states, such as G20 inches mode, always default to a different work coordinate system, or, to provide a way for a user to run some user-written unique feature that they need for their crazy project.**
+
+To set a startup block, type `$N0=` followed by a valid G-code block and an enter. Grbl will run the block to check if it's valid and then reply with an `ok` or an `error:` to tell you if it's successful or something went wrong. If there is an error, Grbl will not save it.
+
+For example, say that you want to use your first startup block `$N0` to set your G-code parser modes like G54 work coordinate, G20 inches mode, G17 XY-plane. You would type `$N0=G20 G54 G17` with an enter and you should see an `ok` response. You can then check if it got stored by typing `$N` and you should now see a response like `$N0=G20G54G17`.
+
+Once you have a startup block stored in Grbl's EEPROM, everytime you startup or reset you will see your startup block printed back to you, starting with an open-chevron `>`, and a `:ok` response from Grbl to indicate if it ran okay. So for the previous example, you'll see:
+
+```
+Grbl 1.1d ['$' for help]
+>G20G54G17:ok
+
+```
+If you have multiple G-code startup blocks, they will print back to you in order upon every startup. And if you'd like to clear one of the startup blocks, (e.g., block 0) type `$N0=` without anything following the equal sign.
+
+NOTE: There are two variations on when startup blocks with run. First, it will not run if Grbl initializes up in an ALARM state or exits an ALARM state via an `$X` unlock for safety reasons. Always address and cancel the ALARM and then finish by a reset, where the startup blocks will run at initialization. Second, if you have homing enabled, the startup blocks will execute immediately after a successful homing cycle, not at startup.
+
+#### `$C` - Check gcode mode
+This toggles the Grbl's gcode parser to take all incoming blocks and process them completely, as it would in normal operation, but it does not move any of the axes, ignores dwells, and powers off the spindle and coolant. This is intended as a way to provide the user a way to check how their new G-code program fares with Grbl's parser and monitor for any errors (and checks for soft limit violations, if enabled).
+
+When toggled off, Grbl will perform an automatic soft-reset (^X). This is for two purposes. It simplifies the code management a bit. But, it also prevents users from starting a job when their G-code modes are not what they think they are. A system reset always gives the user a fresh, consistent start.
+
+#### `$X` - Kill alarm lock
+Grbl's alarm mode is a state when something has gone critically wrong, such as a hard limit or an abort during a cycle, or if Grbl doesn't know its position. By default, if you have homing enabled and power-up the Arduino, Grbl enters the alarm state, because it does not know its position. The alarm mode will lock all G-code commands until the '$H' homing cycle has been performed. Or if a user needs to override the alarm lock to move their axes off their limit switches, for example, '$X' kill alarm lock will override the locks and allow G-code functions to work again.
+
+But, tread carefully!! This should only be used in emergency situations. The position has likely been lost, and Grbl may not be where you think it is. So, it's advised to use G91 incremental mode to make short moves. Then, perform a homing cycle or reset immediately afterwards.
+
+As noted earlier, startup lines do not execute after a `$X` command. Always reset when you have cleared the alarm and fixed the scenario that caused it. When Grbl resets to idle, the startup lines will then run as normal.
+
+#### `$H` - Run homing cycle
+This command is the only way to perform the homing cycle in Grbl. Some other motion controllers designate a special G-code command to run a homing cycle, but this is incorrect according to the G-code standards. Homing is a completely separate command handled by the controller.
+
+TIP: After running a homing cycle, rather jogging manually all the time to a position in the middle of your workspace volume. You can set a G28 or G30 pre-defined position to be your post-homing position, closer to where you'll be machining. To set these, you'll first need to jog your machine to where you would want it to move to after homing. Type G28.1 (or G30.1) to have Grbl store that position. So then after '$H' homing, you could just enter 'G28' (or 'G30') and it'll move there auto-magically. In general, I would just move the XY axis to the center and leave the Z-axis up. This ensures that there isn't a chance the tool in the spindle will interfere and that it doesn't catch on anything.
+
+#### `$Jx=line` - Run jogging motion
+
+New to Grbl v1.1, this command will execute a special jogging motion. There are three main differences between a jogging motion and a motion commanded by a g-code line. 
+
+- Like normal g-code commands, several jog motions may be queued into the planner buffer, but the jogging can be easily canceled by a jog-cancel or feed-hold real-time command. Grbl will immediately hold the current jog and then automatically purge the buffers of any remaining commands. 
+- Jog commands are completely independent of the g-code parser state. It will not change any modes like `G91` incremental distance mode. So, you no longer have to make sure that you change it back to `G90` absolute distance mode afterwards. This helps reduce the chance of starting with the wrong g-code modes enabled.
+- If soft-limits are enabled, any jog command that exceeds a soft-limit will simply return an error. It will not throw an alarm as it would with a normal g-code command. This allows for a much more enjoyable and fluid GUI or joystick interaction.
+
+Executing a jog requires a specific command structure, as described below:
+
+ - The first three characters must be '$J=' to indicate the jog.
+ - The jog command follows immediate after the '=' and works like a normal G1 command.
+ - Feed rate is only interpreted in G94 units per minute. A prior G93 state is ignored during jog.
+ - Required words:
+   - XYZ: One or more axis words with target value.
+   - F - Feed rate value. NOTE: Each jog requires this value and is not treated as modal.
+ - Optional words: Jog executes based on current G20/G21 and G90/G91 g-code parser state. If one of the following optional words is passed, that state is overridden for one command only.
+   - G20 or G21 - Inch and millimeter mode
+   - G90 or G91 - Absolute and incremental distances
+   - G53 - Move in machine coordinates
+ - All other g-codes, m-codes, and value words are not accepted in the jog command.
+ - Spaces and comments are allowed in the command. These are removed by the pre-parser.
+
+ - Example: G21 and G90 are active modal states prior to jogging. These are sequential commands.
+    - `$J=X10.0 Y-1.5` will move to X=10.0mm and Y=-1.5mm in work coordinate frame (WPos).
+    - `$J=G91 G20 X0.5` will move +0.5 inches (12.7mm) to X=22.7mm (WPos). Note that G91 and G20 are only applied to this jog command.
+    - `$J=G53 Y5.0` will move the machine to Y=5.0mm in the machine coordinate frame (MPos). If the work coordinate offset for the y-axis is 2.0mm, then Y is 3.0mm in (WPos).
+
+Jog commands behave almost identically to normal g-code streaming. Every jog command will
+return an 'ok' when the jogging motion has been parsed and is setup for execution. If a
+command is not valid or exceeds a soft-limit, Grbl will return an 'error:'. Multiple jogging commands may be queued in sequence.
+
+NOTE: See additional jogging documentation for details on using this command to create a low-latency joystick or rotary dial interface.
+
+
+#### `$RST=$`, `$RST=#`, and `$RST=*`- Restore Grbl settings and data to defaults
+These commands are not listed in the main Grbl `$` help message, but are available to allow users to restore parts of or all of Grbl's EEPROM data. Note: Grbl will automatically reset after executing one of these commands to ensure the system is initialized correctly.
+
+- `$RST=$` : Erases and restores the `$$` Grbl settings back to defaults, which is defined by the default settings file used when compiling Grbl. Often OEMs will build their Grbl firmwares with their machine-specific recommended settings. This provides users and OEMs a quick way to get back to square-one, if something went awry or if a user wants to start over.
+- `$RST=#` : Erases and zeros all G54-G59 work coordinate offsets and G28/30 positions stored in EEPROM. These are generally the values seen in the `$#` parameters printout. This provides an easy way to clear these without having to do it manually for each set with a `G20 L2/20` or `G28.1/30.1` command.
+- `$RST=*` : This clears and restores all of the EEPROM data used by Grbl. This includes `$$` settings, `$#` parameters, `$N` startup lines, and `$I` build info string. Note that this doesn't wipe the entire EEPROM, only the data areas Grbl uses. To do a complete wipe, please use the Arduino IDE's EEPROM clear example project.
+
+NOTE: Some OEMs may restrict some or all of these commands to prevent certain data they use from being wiped. 
+
+#### `$SLP` - Enable Sleep Mode
+
+This command will place Grbl into a de-powered sleep state, shutting down the spindle, coolant, and stepper enable pins and block any commands. It may only be exited by a soft-reset or power-cycle. Once re-initialized, Grbl will automatically enter an ALARM state, because it's not sure where it is due to the steppers being disabled.
+
+This feature is useful if you need to automatically de-power everything at the end of a job by adding this command at the end of your g-code program, BUT, it is highly recommended that you add commands to first move your machine to a safe parking location prior to this sleep command. It also should be emphasized that you should have a reliable CNC machine that will disable everything when its supposed to, like your spindle. Grbl is not responsible for any damage it may cause. It's never a good idea to leave your machine unattended. So, use this command with the utmost caution!
+
+
+***
+
+## Grbl v1.1 Realtime commands
+
+Realtime commands are single control characters that may be sent to Grbl to command and perform an action in real-time. This means that they can be sent at anytime, anywhere, and Grbl will immediately respond, regardless of what it is doing at the time. These commands include a reset, feed hold, resume, status report query, and overrides (in v1.1).
+
+A realtime command:
+
+- Will execute within tens of milliseconds.
+
+- Is a single character that may be sent to Grbl at any time.
+
+- Does not require a line feed or carriage return after them.
+
+- Is not considered a part of the streaming protocol. 
+
+- Are intercepted when they are received and never placed in a buffer to be parsed by Grbl.
+
+- Will ignore multiple commands until it has executed the first received command.
+
+- May be tied to an input pin and may be operated with a button or switch.
+
+- Actions depends on state or what Grbl is doing. It may not do anything.
+
+- Descriptions explain how they work and what to expect.
+
+#### ASCII Realtime Command Descriptions
+Four realtime commands are type-able by users on a keyboard and shown in the `$` Grbl help message. These realtime command characters control some of Grbl's basic functions.
+
+- `0x18` (ctrl-x) : Soft-Reset
+
+  - Immediately halts and safely resets Grbl without a power-cycle.
+  - Accepts and executes this command at any time.
+  - If reset while in motion, Grbl will throw an alarm to indicate position may be lost from the motion halt.
+  - If reset while in not motion, position is retained and re-homing is not required.
+  - An input pin is available to connect a button or switch.
+
+
+- `?` : Status Report Query
+
+  - Immediately generates and sends back runtime data with a status report.
+  - Accepts and executes this command at any time, except during a homing cycle and when critical alarm (hard/soft limit error) is thrown.
+
+
+- `~` : Cycle Start / Resume
+
+  - Resumes a feed hold, a safety door/parking state when the door is closed, and the M0 program pause states.
+  - Command is otherwise ignored.
+  - If the parking compile-time option is enabled and the safety door state is ready to resume, Grbl will re-enable the spindle and coolant, move back into position, and then resume.
+  - An input pin is available to connect a button or switch.
+
+
+- `!` : Feed Hold
+
+  - Places Grbl into a suspend or HOLD state. If in motion, the machine will decelerate to a stop and then be suspended.
+  - Command executes when Grbl is in an IDLE, RUN, or JOG state. It is otherwise ignored.
+  - If jogging, a feed hold will cancel the jog motion and flush all remaining jog motions in the planner buffer. The state will return from JOG to IDLE or DOOR, if was detected as ajar during the active hold.
+  - By machine control definition, a feed hold does not disable the spindle or coolant. Only motion.
+  - An input pin is available to connect a button or switch.
+
+
+#### Extended-ASCII Realtime Command Descriptions
+
+Grbl v1.1 installed more than a dozen new realtime commands to control feed, rapid, and spindle overrides. To help prevent users from inadvertently altering overrides with a keystroke and allow for more commands later on, all of the new control characters have been moved to the extended ASCII character set. These are not easily type-able on a keyboard, but, depending on the OS, they may be entered using specific keystroke and code. GUI developers will need to be able to send extended ASCII characters, values `128 (0x80)` to `255 (0xFF)`, to Grbl to take advantage of these new features.
+
+- `0x84` : Safety Door
+
+  - Although typically connected to an input pin to detect the opening of a safety door, this command allows a GUI to enact the safety door behavior with this command.
+  - Immediately suspends into a DOOR state and disables the spindle and coolant. If in motion, the machine will decelerate to a stop and then be suspended.
+  - If executed during homing, Grbl will instead halt motion and throw a homing alarm.
+  - If already in a suspend state or HOLD, the DOOR state supersedes it.
+  - If the parking compile-time option is enabled, Grbl will park the spindle to a specified location.
+  - Command executes when Grbl is in an IDLE, HOLD, RUN, HOMING, or JOG state. It is otherwise ignored.
+  - If jogging, a safety door will cancel the jog and all queued motions in the planner buffer. When the safety door is closed and resumed, Grbl will return to an IDLE state.
+  - An input pin is available to connect a button or switch, if enabled with a compile-time option.
+  - Some builds of Grbl v0.9 used the `@` character for this command, but it was undocumented. Moved to extended-ASCII to prevent accidental commanding.
+
+
+- `0x85` : Jog Cancel
+
+  - Immediately cancels the current jog state by a feed hold and automatically flushing any remaining jog commands in the buffer.
+  - Command is ignored, if not in a JOG state or if jog cancel is already invoked and in-process.
+  - Grbl will return to the IDLE state or the DOOR state, if the safety door was detected as ajar during the cancel.
+  
+
+- Feed Overrides
+
+  - Immediately alters the feed override value. An active feed motion is altered within tens of milliseconds.
+  - Does not alter rapid rates, which include G0, G28, and G30, or jog motions.
+  - Feed override value can not be 10% or greater than 200%.
+  - If feed override value does not change, the command is ignored.
+  - Feed override range and increments may be changed in config.h.
+  - The commands are:
+    - `0x90` : Set 100% of programmed rate.
+    - `0x91` : Increase 10%
+    - `0x92` : Decrease 10%
+    - `0x93` : Increase 1%
+    - `0x94` : Decrease 1%
+
+
+- Rapid Overrides
+
+  - Immediately alters the rapid override value. An active rapid motion is altered within tens of milliseconds.
+  - Only effects rapid motions, which include G0, G28, and G30.
+  - If rapid override value does not change, the command is ignored.
+  - Rapid override set values may be changed in config.h.
+  - The commands are:
+    - `0x95` : Set to 100% full rapid rate.
+    - `0x96` : Set to 50% of rapid rate.
+    - `0x97` : Set to 25% of rapid rate.
+
+
+- Spindle Speed Overrides
+
+  - Immediately alters the spindle speed override value. An active spindle speed is altered within tens of milliseconds.
+  - Override values may be changed at any time, regardless of if the spindle is enabled or disabled.
+  - Spindle override value can not be 10% or greater than 200%
+  - If spindle override value does not change, the command is ignored.
+  - Spindle override range and increments may be altered in config.h.
+  - The commands are:
+    - `0x99` : Set 100% of programmed spindle speed
+    - `0x9A` : Increase 10%
+    - `0x9B` : Decrease 10%
+    - `0x9C` : Increase 1%
+    - `0x9D` : Decrease 1%
+
+
+- `0x9E` : Toggle Spindle Stop
+
+  - Toggles spindle enable or disable state immediately, but only while in the HOLD state.
+  - The command is otherwise ignored, especially while in motion. This prevents accidental disabling during a job that can either destroy the part/machine or cause personal injury. Industrial machines handle the spindle stop override similarly.
+  - When motion restarts via cycle start, the last spindle state will be restored and wait 4.0 seconds (configurable) before resuming the tool path. This ensures the user doesn't forget to turn it back on.
+  - While disabled, spindle speed override values may still be altered and will be in effect once the spindle is re-enabled.
+  - If a safety door is opened, the DOOR state will supersede the spindle stop override, where it will manage the spindle re-energizing itself upon closing the door and resuming. The prior spindle stop override state is cleared and reset.
+
+
+- `0xA0` : Toggle Flood Coolant
+
+  - Toggles flood coolant state and output pin until the next toggle or g-code command alters it.
+  - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.
+  - This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M8` or `M9` g-code command.
+  - When `$G` g-code parser state is queried, the toggle override change will be reflected by an `M8` enabled or disabled with an `M9` or not appearing when `M7` is present.
+
+
+- `0xA1` : Toggle Mist Coolant
+
+  - Enabled by `ENABLE_M7` compile-time option. Default is disabled.
+  - Toggles mist coolant state and output pin until the next toggle or g-code command alters it.
+  - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.
+  - This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M7` or `M9` g-code command.
+  - When `$G` g-code parser state is queried, the toggle override change will be reflected by an `M7` enabled or disabled with an `M9` or not appearing when `M8` is present.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/interface.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,683 @@
+# Grbl Interface Basics
+
+The interface for Grbl is fairly simple and straightforward. With Grbl v1.1, steps have been taken to try to make it even easier for new users to get started, and for GUI developers to write their own custom interfaces to Grbl.
+
+Grbl communicates through the serial interface on the Arduino. You just need to connect your Arduino to your computer with a USB cable. Use any standard serial terminal program to connect to Grbl, such as: the Arduino IDE serial monitor, Coolterm, puTTY, etc. Or use one of the many great Grbl GUIs out there in the Internet wild.
+
+The primary way to talk to Grbl is performed by sending it a string of characters, followed by a carriage return. Grbl will then process the string, set it up for execution, and then reply back with a **response message**, also terminated by a return, to tell you how it went. These command strings include sending Grbl: a G-code block to execute, commands to configure Grbl's system settings, to view how Grbl is doing, etc. 
+
+To stream a g-code program to Grbl, the basic interface is to send Grbl a line of g-code, then wait for the proper **response message** starting with an `ok` or `error`. This signals Grbl has completed the parsing and executing the command. At times, Grbl may not respond immediately. This happens when Grbl is busy doing something else or waiting to place a commanded motion into the look-ahead planner buffer. Other times, usually at the start of a program, Grbl may quickly respond to several lines, but nothing happens. This occurs when Grbl places a series of commanded motions directly in the planner queue and will try to fill it up completely before starting.
+
+Along with **response messages**, Grbl has **push messages** to provide more feedback on what Grbl is doing and are also strings terminated by a return. These messages may be "pushed" from Grbl to the user in response to a query or to let the user know something important just happened. These can come at any time, but usually from something like a settings print out when asked to. **Push messages** are easily identified because they don't start with an `ok` or `error` like **response messages** do. They are typically placed in `[]` brackets, `<>` chevrons, start with a `$`, or a specific string of text. These are all defined and described later in this document.
+
+Finally, Grbl has **real-time commands** that are invoked by a set of special characters that may be sent at any time and are not part of the basic streaming send-response interface. These cause Grbl to immediately execute the command and typically don't generate a response. These include pausing the current motion, speed up/down everything, toggle the spindle during a job, reset Grbl, or query Grbl for a real-time status report. See the `Commands` document to see what they are and how they work.
+
+-------
+
+# Writing an Interface for Grbl
+
+The general interface for Grbl has been described above, but what's missing is how to run an entire G-code program on Grbl, when it doesn't seem to have an upload feature. This is where this section fits in. Early on, users fiercely requested for flash drive, external RAM, LCD support, joysticks, or network support so they can upload a g-code program and run it directly on Grbl. The general answer to that is, good ideas, but Grbl doesn't need them. Grbl already has nearly all of the tools and features to reliably communicate with a graphical user interface (GUI) or a seperate host interface that provides all those extra bells and whistles. Grbl's base philosophy is to minimize what Grbl should be doing, because, in the end, Grbl needs to be concentrating on producing clean, reliable motion. That's it.
+
+
+## Streaming a G-Code Program to Grbl
+
+Here we will describe two different streaming methods for Grbl GUIs. One of the main problems with streaming to Grbl is the USB port itself. Arduinos and most all micro controllers use a USB-to-serial converter chip that, at times, behaves strangely and not typically how you'd expect, like USB packet buffering and delays that can wreak havoc to a streaming protocol. Another problem is how to deal with some of the latency and oddities of the PCs themselves, because none of them are truly real-time and always create micro-delays when executing other tasks. Regardless, we've come up with ways to ensure the G-code stream is reliable and simple. 
+
+The following streaming protocols require tracking the **response messages** to determine when to send the next g-code line. All **push messages** are not counted toward the streaming protocol and should be handled separately. All real-time command characters can be sent at any time and are never placed in Grbl's RX serial buffer. They are intercepted as they come in and simply sets  flags for Grbl to execute them.
+
+#### Streaming Protocol: Simple Send-Response _[Recommended]_
+The send-response streaming protocol is the most fool-proof and simplest method to stream a G-code program to Grbl. The host PC interface simply sends a line of G-code to Grbl and waits for an `ok` or `error:` **response message** before sending the next line of G-code. So, no matter if Grbl needs to wait for room in the look-ahead planner buffer to finish parsing and executing the last line of G-code or if the the host computer is busy doing something, this guarantees both to the host PC and Grbl, the programmed G-code has been sent and received properly. An example of this protocol is published in our `simple_stream.py` script in our repository.
+
+However, it's also the slowest of three outlined streaming protocols. Grbl essentially has two buffers between the execution of steps and the host PC interface. One of them is the serial receive buffer. This briefly stores up to 127 characters of data received from the host PC until Grbl has time to fetch and parse the line of G-code. The other buffer is the look-ahead planner buffer. This buffer stores up to 16 line motions that are acceleration-planned and optimized for step execution. Since the send-response protocol receives a line of G-code while the host PC waits for a response, Grbl's serial receive buffer is usually empty and under-utilized. If Grbl is actively running and executing steps, Grbl will immediately begin to execute and empty the look-ahead planner buffer, while it sends the response to the host PC, waits for the next line from the host PC, upon receiving it, parse and plan it, and add it to the end of the look-ahead buffer.
+
+Although this communication lag may take only a fraction of a second, there is a cumulative effect, because there is a lag with every G-code block sent to Grbl. In certain scenarios, like a G-code program containing lots of sequential, very short, line segments with high feed rates, the cumulative lag can be large enough to empty and starve the look-ahead planner buffer within this time. This could lead to start-stop motion when the streaming can't keep up with G-code program execution. Also, since Grbl can only plan and optimize what's in the look-ahead planner buffer, the performance through these types of motions will never be full-speed, because look-ahead buffer will always be partially full when using this streaming method. If your expected application doesn't contain a lot of these short line segments with high feed rates, this streaming protocol should be more than adequate for a vast majority of applications, is very robust, and is a quick way to get started.
+
+#### Streaming Protocol: Character-Counting _[**Recommended with Reservation**]_
+
+To get the best of both worlds, the simplicity and reliability of the send-response method and assurance of maximum performance with software flow control, we came up with a simple character-counting protocol for streaming a G-code program to Grbl. It works like the send-response method, where the host PC sends a line of G-code for Grbl to execute and waits for a `response message`, but, rather than needing special XON/XOFF characters for flow control, this protocol simply uses Grbl's responses as a way to reliably track how much room there is in Grbl's serial receive buffer. An example of this protocol is outlined in the `stream.py` streaming script in our repo. This protocol is particular useful for very fast machines like laser cutters. 
+
+The main difference between this protocol and the others is the host PC needs to maintain a standing count of how many characters it has sent to Grbl and then subtract the number of characters corresponding to the line executed with each Grbl response. Suppose there is a short G-code program that has 5 lines with 25, 40, 31, 58, and 20 characters (counting the line feed and carriage return characters too). We know Grbl has a 128 character serial receive buffer, and the host PC can send up to 128 characters without overflowing the buffer. If we let the host PC send as many complete lines as we can without over flowing Grbl's serial receive buffer, the first three lines of 25, 40, and 31 characters can be sent for a total of 96 characters. When Grbl sends a **response message**, we know the first line has been processed and is no longer in the serial read buffer. As it stands, the serial read buffer now has the 40 and 31 character lines in it for a total of 71 characters. The host PC needs to then determine if it's safe to send the next line without overflowing the buffer. With the next line at 58 characters and the serial buffer at 71 for a total of 129 characters, the host PC will need to wait until more room has cleared from the serial buffer. When the next Grbl **response message** comes in, the second line has been processed and only the third 31 character line remains in the serial buffer. At this point, it's safe to send the remaining last two 58 and 20 character lines of the g-code program for a total of 110.
+
+While seemingly complicated, this character-counting streaming protocol is extremely effective in practice. It always ensures Grbl's serial read buffer is filled, while never overflowing it. It maximizes Grbl's performance by keeping the look-ahead planner buffer full by better utilizing the bi-directional data flow of the serial port, and it's fairly simple to implement as our `stream.py` script illustrates. We have stress-tested this character-counting protocol to extremes and it has not yet failed. Seemingly, only the speed of the serial connection is the limit.
+
+_RESERVATION:_
+
+- _If a g-code line is parsed and generates an error **response message**, a GUI should stop the stream immediately. However, since the character-counting method stuffs Grbl's RX buffer, Grbl will continue reading from the RX buffer and parse and execute the commands inside it. A GUI won't be able to control this. The interim solution is to check all of the g-code via the $C check mode, so all errors are vetted prior to streaming. This will get resolved in later versions of Grbl._
+
+
+## Interacting with Grbl's Systems
+
+Along with streaming a G-code program, there a few more things to consider when writing a GUI for Grbl, such as how to use status reporting, real-time control commands, dealing with EEPROM, and general message handling.
+
+#### Status Reporting
+When a `?` character is sent to Grbl (no additional line feed or carriage return character required), it will immediately respond with something like `<Idle|MPos:0.000,0.000,0.000|FS:0.0,0>` to report its state and current position. The `?` is always picked-off and removed from the serial receive buffer whenever Grbl detects one. So, these can be sent at any time. Also, to make it a little easier for GUIs to pick up on status reports, they are always encased by `<>` chevrons.
+
+Developers can use this data to provide an on-screen position digital-read-out (DRO) for the user and/or to show the user a 3D position in a virtual workspace. We recommend querying Grbl for a `?` real-time status report at no more than 5Hz. 10Hz may be possible, but at some point, there are diminishing returns and you are taxing Grbl's CPU more by asking it to generate and send a lot of position data.
+
+Grbl's status report is fairly simply in organization. It always starts with a word describing the machine state like `IDLE` (descriptions of these are available elsewhere in the Wiki). The following data values are usually in the order listed below and separated by `|` pipe characters, but may not be in the exact order or printed at all. For a complete description of status report formatting, read the _Real-time Status Reports_ section below.
+
+#### Real-Time Control Commands
+The real-time control commands, `~` cycle start/resume, `!` feed hold,  `^X` soft-reset, and all of the override commands, all immediately signal Grbl to change its running state. Just like `?` status reports, these control characters are picked-off and removed from the serial buffer when they are detected and do not require an additional line-feed or carriage-return character to operate.
+
+One important note are the override command characters. These are defined in the extended-ASCII character space and are generally not type-able on a keyboard. A GUI must be able to send these 8-bit values to support overrides. 
+
+#### EEPROM Issues
+EEPROM access on the Arduino AVR CPUs turns off all of the interrupts while the CPU _writes_ to EEPROM. This poses a problem for certain features in Grbl, particularly if a user is streaming and running a g-code program, since it can pause the main step generator interrupt from executing on time. Most of the EEPROM access is restricted by Grbl when it's in certain states, but there are some things that developers need to know.
+
+* Settings should not be streamed with the character-counting streaming protocols. Only the simple send-response protocol works. This is because during the EEPROM write, the AVR CPU also shuts-down the serial RX interrupt, which means data can get corrupted or lost. This is safe with the send-response protocol, because it's not sending data after commanding Grbl to save data.
+
+For reference:
+* Grbl's EEPROM write commands: `G10 L2`, `G10 L20`, `G28.1`, `G30.1`, `$x=`, `$I=`, `$Nx=`, `$RST=`
+* Grbl's EEPROM read commands: `G54-G59`, `G28`, `G30`, `$$`, `$I`, `$N`, `$#`
+
+#### G-code Error Handling
+
+Grbl's g-code parser is fully standards-compilant with complete error-checking. When a G-code parser detects an error in a G-code block/line, the parser will dump everything in the block from memory and report an `error:` back to the user or GUI. This dump is absolutely the right thing to do, because a g-code line with an error can be interpreted in multiple ways. However, this dump can be problematic, because the bad G-code block may have contained some valuable positioning commands or feed rate settings that the following g-code depends on.
+
+It's highly recommended to do what all professional CNC controllers do when they detect an error in the G-code program, _**halt**_. Don't do anything further until the user has modified the G-code and fixed the error in their program. Otherwise, bad things could happen.
+
+As a service to GUIs, Grbl has a "check G-code" mode, enabled by the `$C` system command. GUIs can stream a G-code program to Grbl, where it will parse it, error-check it, and report `ok`'s and `errors:`'s without powering on anything or moving. So GUIs can pre-check the programs before streaming them for real. To disable the "check G-code" mode, send another `$C` system command and Grbl will automatically soft-reset to flush and re-initialize the G-code parser and the rest of the system. This perhaps should be run in the background when a user first loads a program, before a user sets up his machine. This flushing and re-initialization clears `G92`'s by G-code standard, which some users still incorrectly use to set their part zero.
+
+#### Jogging
+
+As of Grbl v1.1, a new jogging feature is available that accepts incremental, absolute, or absolute override motions, along with a jog cancel real-time command that will automatically feed hold and purge the planner buffer. The most important aspect of the new jogging motion is that it is completely independent from the g-code parser, so GUIs no longer have to ensure the g-code modal states are set back correctly after jogging is complete. See the jogging document for more details on how it works and how you can use it with an analog joystick or rotary dial.
+
+#### Synchronization
+
+For situations when a GUI needs to run a special set of commands for tool changes, auto-leveling, etc, there often needs to be a way to know when Grbl has completed a task and the planner buffer is empty. The absolute simplest way to do this is to insert a `G4 P0.01` dwell command, where P is in seconds and must be greater than 0.0. This acts as a quick force-synchronization and ensures the planner buffer is completely empty before the GUI sends the next task to execute.
+
+-----
+# Message Summary
+
+In v1.1, Grbl's interface protocol has been tweaked in the attempt to make GUI development cleaner, clearer, and hopefully easier. All messages are designed to be deterministic without needing to know the context of the message. Each can be inferred to a much greater degree than before just by the message type, which are all listed below.
+
+- **Response Messages:** Normal send command and execution response acknowledgement. Used for streaming.
+
+	- `ok` : Indicates the command line received was parsed and executed (or set to be executed).
+	- `error:x` : Indicated the command line received contained an error, with an error code `x`, and was purged. See error code section below for definitions.
+
+- **Push Messages:**
+	
+	- `< >` : Enclosed chevrons contains status report data.
+	- `Grbl X.Xx ['$' for help]` : Welcome message indicates initialization.
+	- `ALARM:x` : Indicates an alarm has been thrown. Grbl is now in an alarm state.	
+	- `$x=val` and `$Nx=line` indicate a settings printout from a `$` and `$N` user query, respectively.
+	- `[MSG:]` : Indicates a non-queried feedback message.
+	- `[GC:]` : Indicates a queried `$G` g-code state message.
+	- `[HLP:]` : Indicates the help message.
+	- `[G54:]`, `[G55:]`, `[G56:]`, `[G57:]`, `[G58:]`, `[G59:]`, `[G28:]`, `[G30:]`, `[G92:]`, `[TLO:]`, and `[PRB:]` messages indicate the parameter data printout from a `$#` user query.
+	- `[VER:]` : Indicates build info and string from a `$I` user query.
+	- `[echo:]` : Indicates an automated line echo from a pre-parsed string prior to g-code parsing. Enabled by config.h option.
+	- `>G54G20:ok` : The open chevron indicates startup line execution. The `:ok` suffix shows it executed correctly without adding an unmatched `ok` response on a new line.
+
+In addition, all `$x=val` settings, `error:`, and `ALARM:` messages no longer contain human-readable strings, but rather codes that are defined in other documents. The `$` help message is also reduced to just showing the available commands. Doing this saves incredible amounts of flash space. Otherwise, the new overrides features would not have fit.
+
+Other minor changes and bug fixes that may effect GUI parsing include:
+
+- Floating point values printed with zero precision do not show a decimal, or look like an integer. This includes spindle speed RPM and feed rate in mm mode.
+- `$G` reports fixed a long time bug with program modal state. It always showed `M0` program pause when running. Now during a normal program run, no program modal state is given until an `M0`, `M2`, or `M30` is active and then the appropriate state will be shown.
+
+On a final note, this interface tweak came about out of necessity, as more data is being sent back from Grbl and it is capable of doing many more things. It's not intended to be altered again in the near future, if at all. This is likely the only and last major change to this. If you have any comments or suggestions before Grbl v1.1 goes to master, please do immediately so we can all vet the new alteration before its installed.
+
+
+
+
+
+---------
+
+# Grbl Response Messages
+
+Every G-code block sent to Grbl and Grbl `$` system command that is terminated with a return will be parsed and processed by Grbl. Grbl will then respond either if it recognized the command with an `ok` line or if there was a problem with an `error` line.
+
+* **`ok`**: All is good! Everything in the last line was understood by Grbl and was successfully processed and executed.
+
+  - If an empty line with only a return is sent to Grbl, it considers it a valid line and will return an `ok` too, except it didn't do anything.
+
+
+* **`error:X`**: Something went wrong! Grbl did not recognize the command and did not execute anything inside that message. The `X` is given as a numeric error code to tell you exactly what happened. The table below decribes every one of them.
+
+	| ID | Error Code Description |
+|:-------------:|----|
+| **`1`** | G-code words consist of a letter and a value. Letter was not found. |
+| **`2`** | Numeric value format is not valid or missing an expected value. |
+| **`3`** | Grbl '$' system command was not recognized or supported. |
+| **`4`** | Negative value received for an expected positive value. |
+| **`5`** | Homing cycle is not enabled via settings. |
+| **`6`** | Minimum step pulse time must be greater than 3usec |
+| **`7`** | EEPROM read failed. Reset and restored to default values. |
+| **`8`** | Grbl '$' command cannot be used unless Grbl is IDLE. Ensures smooth operation during a job. |
+| **`9`** | G-code locked out during alarm or jog state |
+| **`10`** | Soft limits cannot be enabled without homing also enabled. |
+| **`11`** | Max characters per line exceeded. Line was not processed and executed. |
+| **`12`** | (Compile Option) Grbl '$' setting value exceeds the maximum step rate supported. |
+| **`13`** | Safety door detected as opened and door state initiated. |
+| **`14`** | (Grbl-Mega Only) Build info or startup line exceeded EEPROM line length limit. |
+| **`15`** | Jog target exceeds machine travel. Command ignored. |
+| **`16`** | Jog command with no '=' or contains prohibited g-code. |
+| **`17`** | Laser mode disabled. Requires PWM output. |
+| **`20`** | Unsupported or invalid g-code command found in block. |
+| **`21`** | More than one g-code command from same modal group found in block.|
+| **`22`** | Feed rate has not yet been set or is undefined. |
+| **`23`** | G-code command in block requires an integer value. |
+| **`24`** | Two G-code commands that both require the use of the `XYZ` axis words were detected in the block.|
+| **`25`** | A G-code word was repeated in the block.|
+| **`26`** | A G-code command implicitly or explicitly requires `XYZ` axis words in the block, but none were detected.|
+| **`27`**| `N` line number value is not within the valid range of `1` - `9,999,999`. |
+| **`28`** | A G-code command was sent, but is missing some required `P` or `L` value words in the line. |
+| **`29`** | Grbl supports six work coordinate systems `G54-G59`. `G59.1`, `G59.2`, and `G59.3` are not supported.|
+| **`30`**| The `G53` G-code command requires either a `G0` seek or `G1` feed motion mode to be active. A different motion was active.|
+| **`31`** | There are unused axis words in the block and `G80` motion mode cancel is active.|
+| **`32`** | A `G2` or `G3` arc was commanded but there are no `XYZ` axis words in the selected plane to trace the arc.|
+| **`33`** | The motion command has an invalid target. `G2`, `G3`, and `G38.2` generates this error, if the arc is impossible to generate or if the probe target is the current position.|
+| **`34`** | A `G2` or `G3` arc, traced with the radius definition, had a mathematical error when computing the arc geometry. Try either breaking up the arc into semi-circles or quadrants, or redefine them with the arc offset definition.|
+| **`35`** | A `G2` or `G3` arc, traced with the offset definition, is missing the `IJK` offset word in the selected plane to trace the arc.|
+| **`36`** | There are unused, leftover G-code words that aren't used by any command in the block.|
+| **`37`** | The `G43.1` dynamic tool length offset command cannot apply an offset to an axis other than its configured axis. The Grbl default axis is the Z-axis.|
+| **`38`** | Tool number greater than max supported value.|
+
+
+----------------------
+
+# Grbl Push Messages
+
+Along with the response message to indicate successfully executing a line command sent to Grbl, Grbl provides additional push messages for important feedback of its current state or if something went horribly wrong. These messages are "pushed" from Grbl and may appear at anytime. They are usually in response to a user query or some system event that Grbl needs to tell you about immediately. These push messages are organized into six general classes:
+
+- **_Welcome message_** - A unique message to indicate Grbl has initialized.
+
+- **_ALARM messages_** - Means an emergency mode has been enacted and shut down normal use.
+
+- **_'$' settings messages_** - Contains the type and data value for a Grbl setting.
+
+- **_Feedback messages_** - Contains general feedback and can provide useful data.
+
+- **_Startup line execution_** - Indicates a startup line as executed with the line itself and how it went.
+
+- **_Real-time status reports_** - Contains current run data like state, position, and speed.
+
+
+------
+
+#### Welcome Message
+
+**`Grbl X.Xx ['$' for help]`**
+
+The start up message always prints upon startup and after a reset. Whenever you see this message, this also means that Grbl has completed re-initializing all its systems, so everything starts out the same every time you use Grbl.
+
+* `X.Xx` indicates the major version number, followed by a minor version letter. The major version number indicates the general release, while the letter simply indicates a feature update or addition from the preceding minor version letter.
+* Bug fix revisions are tracked by the build info version number, printed when an `$I` command is sent. These revisions don't update the version number and are given by date revised in year, month, and day, like so `20161014`.
+
+-----
+
+#### Alarm Message
+
+Alarm is an emergency state. Something has gone terribly wrong when these occur. Typically, they are caused by limit error when the machine has moved or wants to move outside the machine travel and crash into the ends. They also report problems if Grbl is lost and can't guarantee positioning or a probe command has failed. Once in alarm-mode, Grbl will lock out all g-code functionality and accept only a small set of commands. It may even stop everything and force you to acknowledge the problem until you issue Grbl a reset. While in alarm-mode, the user can override the alarm manually with a specific command, which then re-enables g-code so you can move the machine again. This ensures the user knows about the problem and has taken steps to fix or account for it.
+
+Similar to error messages, all alarm messages are sent as  **`ALARM:X`**, where `X` is an alarm code to tell you exacly what caused the alarm. The table below describes the meaning of each alarm code.
+
+| ID | Alarm Code Description |
+|:-------------:|----|
+| **`1`** | Hard limit triggered. Machine position is likely lost due to sudden and immediate halt. Re-homing is highly recommended. |
+| **`2`** | G-code motion target exceeds machine travel. Machine position safely retained. Alarm may be unlocked. |
+| **`3`** | Reset while in motion. Grbl cannot guarantee position. Lost steps are likely. Re-homing is highly recommended. |
+| **`4`** | Probe fail. The probe is not in the expected initial state before starting probe cycle, where G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered. |
+| **`5`** | Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4. |
+| **`6`** | Homing fail. Reset during active homing cycle. |
+| **`7`** | Homing fail. Safety door was opened during active homing cycle. |
+| **`8`** | Homing fail. Cycle failed to clear limit switch when pulling off. Try increasing pull-off setting or check wiring. |
+| **`9`** | Homing fail. Could not find limit switch within search distance. Defined as `1.5 * max_travel` on search and `5 * pulloff` on locate phases. |
+
+-------
+
+#### Grbl `$` Settings Message
+
+When a push message starts with a `$`, this indicates Grbl is sending a setting and its configured value. There are only two types of settings messages: a single setting and value `$x=val` and a startup string setting `$Nx=line`. See [Configuring Grbl v1.x] document if you'd like to learn how to write these values for your machine.
+
+- `$x=val` will only appear when the user queries to print all of Grbl's settings via the `$$` print settings command. It does so sequentially and completes with an `ok`.
+
+  - In prior versions of Grbl, the `$` settings included a short description of the setting immediately after the value. However, due to flash restrictions, most human-readable strings were removed to free up flash for the new override features in Grbl v1.1. In short, it was these strings or overrides, and overrides won. Keep in mind that once these values are set, they usually don't change, and GUIs will likely provide the assistance of translating these codes for users.
+
+  - _**NOTE for GUI developers:**_ _As with the error and alarm codes, settings codes are available in an easy to parse CSV file in the `/doc/csv` folder. These are continually updated._
+
+  - The `$$` settings print out is shown below and the following describes each setting.
+
+    ```
+$0=10
+$1=25
+$2=0
+$3=0
+$4=0
+$5=0
+$6=0
+$10=255
+$11=0.010
+$12=0.002
+$13=0
+$20=0
+$21=0
+$22=0
+$23=0
+$24=25.000
+$25=500.000
+$26=250
+$27=1.000
+$30=1000
+$31=0
+$32=0
+$100=250.000
+$101=250.000
+$102=250.000
+$110=500.000
+$111=500.000
+$112=500.000
+$120=10.000
+$121=10.000
+$122=10.000
+$130=200.000
+$131=200.000
+$132=200.000
+ok
+```
+
+	| `$x` Code | Setting Description, Units |
+|:-------------:|----|
+| **`0`** | Step pulse time, microseconds |
+| **`1`** | Step idle delay, milliseconds |
+| **`2`** | Step pulse invert, mask |
+| **`3`** | Step direction invert, mask |
+| **`4`** | Invert step enable pin, boolean |
+| **`5`** | Invert limit pins, boolean |
+| **`6`** | Invert probe pin, boolean |
+| **`10`** | Status report options, mask |
+| **`11`** | Junction deviation, millimeters |
+| **`12`** | Arc tolerance, millimeters |
+| **`13`** | Report in inches, boolean |
+| **`20`** | Soft limits enable, boolean |
+| **`21`** | Hard limits enable, boolean |
+| **`22`** | Homing cycle enable, boolean |
+| **`23`** | Homing direction invert, mask |
+| **`24`** | Homing locate feed rate, mm/min |
+| **`25`** | Homing search seek rate, mm/min  |
+| **`26`** | Homing switch debounce delay, milliseconds |
+| **`27`** | Homing switch pull-off distance, millimeters |
+| **`30`** | Maximum spindle speed, RPM |
+| **`31`** | Minimum spindle speed, RPM |
+| **`32`** | Laser-mode enable, boolean |
+| **`100`** | X-axis steps per millimeter |
+| **`101`** | Y-axis steps per millimeter |
+| **`102`** | Z-axis steps per millimeter |
+| **`110`** | X-axis maximum rate, mm/min |
+| **`111`** | Y-axis maximum rate, mm/min |
+| **`112`** | Z-axis maximum rate, mm/min |
+| **`120`** | X-axis acceleration, mm/sec^2 |
+| **`121`** | Y-axis acceleration, mm/sec^2 |
+| **`122`** | Z-axis acceleration, mm/sec^2 |
+| **`130`** | X-axis maximum travel, millimeters |
+| **`131`** | Y-axis maximum travel, millimeters |
+| **`132`** | Z-axis maximum travel, millimeters |
+
+
+- The other `$Nx=line` message is the print-out of a user-defined startup line, where `x` denotes the startup line order and ranges from `0` to `1` by default. The `line` denotes the startup line to be executed by Grbl upon reset or power-up, except during an ALARM.
+
+  - When a user queries for the startup lines via a `$N` command, the following is sent by Grbl and completed by an `ok` response. The first line sets the initial startup work coordinate system to `G54`, while the second line is empty and does not execute.
+  ```
+  $N0=G54
+  $N1=
+  ok
+  ```
+
+
+------
+
+#### Feedback Messages
+
+Feedback messages provide non-critical information on what Grbl is doing, what it needs, and/or provide some non-real-time data for the user when queried. Not too complicated. Feedback message are always enclosed in `[]` brackets, except for the startup line execution message which begins with an open chevron character `>`.
+
+- **Non-Queried Feedback Messages:** These feedback messages that may appear at any time and is not part of a query are listed and described below. They are usually sent as an additional helpful acknowledgement of some event or command executed. These always start with a `[MSG:` to denote their type.
+
+  - `[MSG:Reset to continue]` - Critical event message. Reset is required before Grbl accepts any other commands. This prevents ongoing command streaming and risking a motion before the alarm is acknowledged. Only hard or soft limit errors send this message immediately after the ALARM:x code.
+
+  - `[MSG:‘$H’|’$X’ to unlock]`- Alarm state is active at initialization. This message serves as a reminder note on how to cancel the alarm state. All g-code commands and some ‘$’ are blocked until the alarm state is cancelled via homing `$H` or unlocking `$X`. Only appears immediately after the `Grbl` welcome message when initialized with an alarm. Startup lines are not executed at initialization if this message is present and the alarm is active.
+
+  - `[MSG:Caution: Unlocked]` - Appears as an alarm unlock `$X` acknowledgement. An 'ok' still appears immediately after to denote the `$X` was parsed and executed. This message reminds the user that Grbl is operating under an unlock state, where startup lines have still not be executed and should be cautious and mindful of what they do. Grbl may not have retained machine position due to an alarm suddenly halting the machine.  A reset or re-homing Grbl is highly recommended as soon as possible, where any startup lines will be properly executed.
+
+  - `[MSG:Enabled]` - Appears as a check-mode `$C` enabled acknowledgement. An 'ok' still appears immediately after to denote the `$C` was parsed and executed.
+
+  - `[MSG:Disabled]` - Appears as a check-mode `$C` disabled acknowledgement. An 'ok' still appears immediately after to denote the `$C` was parsed and executed. Grbl is automatically reset afterwards to restore all default g-code parser states changed by the check-mode.
+
+  - `[MSG:Check Door]` - This message appears whenever the safety door detected as open. This includes immediately upon a safety door switch detects a pin change or appearing after the welcome message, if the safety door is ajar when Grbl initializes after a power-up/reset.
+
+    - If in motion and the safety door switch is triggered, Grbl will immediately send this message, start a feed hold, and place Grbl into a suspend with the DOOR state.
+    - If not in motion and not at startup, the same process occurs without the feed hold.
+    - If Grbl is in a DOOR state and already suspended, any detected door switch pin detected will generate this message, including a door close.
+    - If this message appears at startup, Grbl will suspended into immediately into the DOOR state. The startup lines are executed immediately after the DOOR state is exited by closing the door and sending Grbl a resume command.
+
+  - `[MSG:Check Limits]` - If Grbl detects a limit switch as triggered after a power-up/reset and hard limits are enabled, this will appear as a courtesy message immediately after the Grbl welcome message.
+
+  - `[MSG:Pgm End]` - M2/30 program end message to denote g-code modes have been restored to defaults according to the M2/30 g-code description.
+
+  - `[MSG:Restoring defaults]` - Appears as an acknowledgement message when restoring EEPROM defaults via a `$RST=` command. An 'ok' still appears immediately after to denote the `$RST=` was parsed and executed.
+  
+  - `[MSG:Sleeping]` - Appears as an acknowledgement message when Grbl's sleep mode is invoked by issuing a `$SLP` command when in IDLE or ALARM states. Note that Grbl-Mega may invoke this at any time when the sleep timer option has been enabled and the timeout has been exceeded. Grbl may only be exited by a reset in the sleep state and will automatically enter an alarm state since the steppers were disabled.
+	  - NOTE: Sleep will also invoke the parking motion, if it's enabled. However, if sleep is commanded during an ALARM, Grbl will not park and will simply de-energize everything and go to sleep.
+
+- **Queried Feedback Messages:**
+
+	- `[GC:]` G-code Parser State Message 
+
+		```
+		[GC:G0 G54 G17 G21 G90 G94 M5 M9 T0 F0.0 S0]
+		ok
+		```
+		
+   		- Initiated by the user via a `$G` command. Grbl replies as follows, where the `[GC:` denotes the message type and is followed by a separate `ok` to confirm the `$G` was executed.
+     	
+     	- The shown g-code are the current modal states of Grbl's g-code parser. This may not correlate to what is executing since there are usually several motions queued in the planner buffer.
+     	
+     	- NOTE: Program modal state has been fixed and will show `M0`, `M2`, or `M30` when they are active. During a run state, nothing will appear for program modal state.
+     	 
+
+
+  - `[HLP:]` : Initiated by the user via a `$` print help command. The help message is shown below with a separate `ok` to confirm the `$` was executed.
+    ```
+    [HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $C $X $H ~ ! ? ctrl-x]
+    ok
+    ```
+		- _**NOTE:** Grbl v1.1's new override real-time commands are not included in the help message. They use the extended-ASCII character set, which are not easily type-able, and require a GUI that supports them. This is for two reasons: Establish enough characters for all of the overrides with extra for later growth, and prevent accidental keystrokes or characters in a g-code file from enacting an override inadvertently._
+
+
+  - The `$#` print parameter data query produces a large set of data which shown below and completed by an `ok` response message.
+
+    	- Each line of the printout is starts with the data type, a `:`, and followed by the data values. If there is more than one, the order is XYZ axes, separated by commas.
+
+      		```
+      [G54:0.000,0.000,0.000]
+      [G55:0.000,0.000,0.000]
+      [G56:0.000,0.000,0.000]
+      [G57:0.000,0.000,0.000]
+      [G58:0.000,0.000,0.000]
+      [G59:0.000,0.000,0.000]
+      [G28:0.000,0.000,0.000]
+      [G30:0.000,0.000,0.000]
+      [G92:0.000,0.000,0.000]
+      [TLO:0.000]
+      [PRB:0.000,0.000,0.000:0]
+      ok
+      ```
+
+    	- The `PRB:` probe parameter message includes an additional `:` and suffix value is a boolean. It denotes whether the last probe cycle was successful or not.
+
+  - `[VER:]` and `[OPT:]`: Indicates build info data from a `$I` user query. These build info messages are followed by an `ok` to confirm the `$I` was executed, like so:
+ 
+      ```
+      [VER:v1.1f.20170131:Some string]
+      [OPT:VL,16,128]
+      ok
+      ```
+      
+  		- The first line `[VER:]` contains the build version and date.
+      - A string may appear after the second `:` colon. It is a stored EEPROM string a user via a `$I=line` command or OEM can place there for personal use or tracking purposes.
+  		- The `[OPT:]` line follows immediately after and contains character codes for compile-time options that were either enabled or disabled and two values separated by commas, which indicates the total usable planner blocks and serial RX buffer bytes, respectively. The codes are defined below and a CSV file is also provided for quick parsing. This is generally only used for quickly diagnosing firmware bugs or compatibility issues. 
+
+			| `OPT` Code | Setting Description, Units |
+|:-------------:|----|
+| **`V`** | Variable spindle enabled |
+| **`N`** | Line numbers enabled |
+| **`M`** | Mist coolant enabled |
+| **`C`** | CoreXY enabled |
+| **`P`** | Parking motion enabled |
+| **`Z`** | Homing force origin enabled |
+| **`H`** | Homing single axis enabled |
+| **`T`** | Two limit switches on axis enabled |
+| **`D`** | Spindle direction pin used as enable pin |
+| **`0`** | Spindle enable off when speed is zero enabled |
+| **`S`** | Software limit pin debouncing enabled |
+| **`R`** | Parking override control enabled |
+| **`A`** | Allow feed rate overrides in probe cycles |
+| **`*`** | Restore all EEPROM disabled |
+| **`$`** | Restore EEPROM `$` settings disabled |
+| **`#`** | Restore EEPROM parameter data disabled |
+| **`I`** | Build info write user string disabled |
+| **`E`** | Force sync upon EEPROM write disabled |
+| **`W`** | Force sync upon work coordinate offset change disabled |
+| **`L`** | Homing initialization auto-lock disabled |
+    
+  - `[echo:]` : Indicates an automated line echo from a command just prior to being parsed and executed. May be enabled only by a config.h option. Often used for debugging communication issues. A typical line echo message is shown below. A separate `ok` will eventually appear to confirm the line has been parsed and executed, but may not be immediate as with any line command containing motions.
+      ```
+      [echo:G1X0.540Y10.4F100]
+      ```
+      - NOTE: The echoed line will have been pre-parsed a bit by Grbl. No spaces or comments will appear and all letters will be capitalized.
+
+------
+
+#### Startup Line Execution
+
+  - `>G54G20:ok` : The open chevron indicates a startup line has just executed. The startup line `G54G20` immediately follows the `>` character and is followed by an `:ok` response to indicate it executed successfully.
+
+    - A startup line will execute upon initialization only if a line is present and if Grbl is not in an alarm state.
+
+    - The `:ok` on the same line is intentional. It prevents this `ok` response from being counted as part of a stream, because it is not tied to a sent command, but an internally-generated one.
+
+    - There should always be an appended `:ok` because the startup line is checked for validity before it is stored in EEPROM. In the event that it's not, Grbl will print `>G54G20:error:X`, where `X` is the error code explaining why the startup line failed to execute.
+
+    - In the rare chance that there is an EEPROM read error, the startup line execution will print `>:error:7` with no startup line and a error code `7` for a read fail. Grbl will also automatically wipe and try to restore the problematic EEPROM.
+
+
+------
+
+#### Real-time Status Reports
+
+- Contains real-time data of Grbl’s state, position, and other data required independently of the stream.
+
+- Categorized as a real-time message, where it is a separate message that should not be counted as part of the streaming protocol. It may appear at any given time.
+
+- A status report is initiated by sending Grbl a '?' character.
+
+  - Like all real-time commands, the '?' character is intercepted and never enters the serial buffer. It's never a part of the stream and can be sent at any time.
+
+  - Grbl will generate and transmit a report within ~5-20 milliseconds.
+
+  - Every ’?’ command sent by a GUI is not guaranteed with a response. The following are the current scenarios when Grbl may not immediately or ignore a status report request. _NOTE: These may change in the future and will be documented here._
+
+    - If two or more '?' queries are sent before the first report is generated, the additional queries are ignored.
+
+    - A soft-reset commanded clears the last status report query.
+
+    - When Grbl throws a critical alarm from a limit violation. A soft-reset is required to resume operation.
+
+    - During a homing cycle.
+
+- **Message Construction:**
+
+  - A message is a single line of ascii text, completed by a carriage return and line feed.
+
+  - `< >` Chevrons uniquely enclose reports to indicate message type.
+
+  - `|` Pipe delimiters separate data fields inside the report.
+
+  - The first data field is an exception to the following data field rules. See 'Machine State' description for details.
+
+  - All remaining data fields consist of a data type followed by a `:` colon delimiter and data values. `type:value(s)`
+
+  - Data values are given either as as one or more pre-defined character codes to indicate certain states/conditions or as numeric values, which are separated by a `,` comma delimiter when more than one is present. Numeric values are also in a pre-defined order and units of measure.
+
+  - The first (Machine State) and second (Current Position) data fields are always included in every report.
+
+  - Assume any following data field may or may not exist and can be in any order. The `$10` status report mask setting can alter what data is present and certain data fields can be reported intermittently (see descriptions for details.)
+
+  - The `$13` report inches settings alters the units of some data values. `$13=0` false indicates mm-mode, while `$13=1` true indicates inch-mode reporting. Keep note of this setting and which report values can be altered.
+
+- **Data Field Descriptions:**
+
+    - **Machine State:**
+
+      - Valid states types:  `Idle, Run, Hold, Jog, Alarm, Door, Check, Home, Sleep`
+
+      - Sub-states may be included via `:` a colon delimiter and numeric code.
+
+      - Current sub-states are:
+
+        	- `Hold:0` Hold complete. Ready to resume.
+	     	- `Hold:1` Hold in-progress. Reset will throw an alarm.
+        	- `Door:0` Door closed. Ready to resume.
+        	- `Door:1` Machine stopped. Door still ajar. Can't resume until closed.
+        	- `Door:2` Door opened. Hold (or parking retract) in-progress. Reset will throw an alarm.
+			- `Door:3` Door closed and resuming. Restoring from park, if applicable. Reset will throw an alarm.
+
+      - This data field is always present as the first field.
+
+    - **Current Position:**
+
+        - Depending on `$10` status report mask settings, position may be sent as either:
+
+          - `MPos:0.000,-10.000,5.000` machine position or
+          - `WPos:-2.500,0.000,11.000` work position
+
+        - **NOTE: Grbl v1.1 sends only one position vector because a GUI can easily compute the other position vector with the work coordinate offset `WCO:` data. See WCO description for details.**
+
+        - Three position values are given in the order of X, Y, and Z. A fourth position value may exist in later versions for the A-axis.
+
+        - `$13` report inches user setting effects these values and is given as either mm or inches.
+
+        - This data field is always present as the second field.
+
+    - **Work Coordinate Offset:**
+
+        - `WCO:0.000,1.551,5.664` is the current work coordinate offset of the g-code parser, which is the sum of the current work coordinate system, G92 offsets, and G43.1 tool length offset.
+
+        - Machine position and work position are related by this simple equation per axis: `WPos = MPos - WCO`
+        
+        	- **GUI Developers:** Simply track and retain the last `WCO:` vector and use the above equation to compute the other position vector for your position readouts. If Grbl's status reports show either `WPos` or `MPos`, just follow the equations below. It's as easy as that!
+        		- If `WPos:` is given, use `MPos = WPos + WCO`.
+        		- If `MPos:` is given, use `WPos = MPos - WCO`.
+
+        - Values are given in the order of the X,Y, and Z axes offsets. A fourth offset value may exist in later versions for the A-axis.
+        - `$13` report inches user setting effects these values and is given as either mm or inches.
+
+        - `WCO:` values don't change often during a job once set and only requires intermittent refreshing.
+
+        - This data field appears:
+
+          - In every 10 or 30 (configurable 1-255) status reports, depending on if Grbl is in a motion state or not.
+          - Immediately in the next report, if an offset value has changed.
+          - In the first report after a reset/power-cycle.
+
+        - This data field will not appear if:
+
+          - It is disabled in the config.h file. No `$` mask setting available.
+          - The refresh counter is in-between intermittent reports.       
+
+    - **Buffer State:**
+
+        - `Bf:15,128`. The first value is the number of available blocks in the planner buffer and the second is number of available bytes in the serial RX buffer.
+        
+        - The usage of this data is generally for debugging an interface, but is known to be used to control some GUI-specific tasks. While this is disabled by default, GUIs should expect this data field to appear, but they may ignore it, if desired.
+        
+        	- IMPORTANT: Do not use this buffer data to control streaming. During a stream, the reported buffer will often be out-dated and may be incorrect by the time it has been received by the GUI. Instead, please use the streaming protocols outlined. They use Grbl's responses as a direct way to accurately determine the buffer state.
+        	        
+        - NOTE: The buffer state values changed from showing "in-use" blocks or bytes to "available". This change does not require the GUI knowing how many block/bytes Grbl has been compiled with.
+
+        - This data field appears:
+        
+          - In every status report when enabled. It is disabled in the settings mask by default.
+        
+        - This data field will not appear if:
+
+          - It is disabled by the `$` status report mask setting or disabled in the config.h file.
+
+    - **Line Number:**
+
+        - `Ln:99999` indicates line 99999 is currently being executed. This differs from the `$G` line `N` value since the parser is usually queued few blocks behind execution.
+
+        - Compile-time option only because of memory requirements. However, if a GUI passes indicator line numbers onto Grbl, it's very useful to determine when Grbl is executing them.
+
+        - This data field will not appear if:
+
+          - It is disabled in the config.h file. No `$` mask setting available.
+          - The line number reporting not enabled in config.h. Different option to reporting data field.
+          - No line number or `N0` is passed with the g-code block.
+          - Grbl is homing, jogging, parking, or performing a system task/motion.
+          - There is no motion in the g-code block like a `G4P1` dwell. (May be fixed in later versions.)
+
+    - **Current Feed and Speed:**
+
+        - There are two versions of this data field that Grbl may respond with. 
+        
+        	- `F:500` contains real-time feed rate data as the value. This appears only when VARIABLE_SPINDLE is disabled in config.h, because spindle speed is not tracked in this mode.
+        	- `FS:500,8000` contains real-time feed rate, followed by spindle speed, data as the values. Note the `FS:`, rather than `F:`, data type name indicates spindle speed data is included.
+                
+        - The current feed rate value is in mm/min or inches/min, depending on the `$` report inches user setting. 
+        - The second value is the current spindle speed in RPM
+        
+        - These values will often not be the programmed feed rate or spindle speed, because several situations can alter or limit them. For example, overrides directly scale the programmed values to a different running value, while machine settings, acceleration profiles, and even the direction traveled can also limit rates to maximum values allowable.
+
+        - As a operational note, reported rate is typically 30-50 msec behind actual position reported.
+
+        - This data field will always appear, unless it was explicitly disabled in the config.h file.
+
+    - **Input Pin State:**
+
+        - `Pn:XYZPDHRS` indicates which input pins Grbl has detected as 'triggered'.
+
+        - Pin state is evaluated every time a status report is generated. All input pin inversions are appropriately applied to determine 'triggered' states.
+
+        - Each letter of `XYZPDHRS` denotes a particular 'triggered' input pin.
+
+          - `X Y Z` XYZ limit pins, respectively
+          - `P` the probe pin.
+          - `D H R S` the door, hold, soft-reset, and cycle-start pins, respectively.
+          - Example: `Pn:PZ` indicates the probe and z-limit pins are 'triggered'.
+          - Note: `A` may be added in later versions for an A-axis limit pin.
+
+        - Assume input pin letters are presented in no particular order.
+
+        - One or more 'triggered' pin letter(s) will always be present with a `Pn:` data field.
+
+        - This data field will not appear if:
+
+          - It is disabled in the config.h file. No `$` mask setting available.
+          - No input pins are detected as triggered.
+
+    - **Override Values:**
+
+        - `Ov:100,100,100` indicates current override values in percent of programmed values for feed, rapids, and spindle speed, respectively.
+
+        - Override maximum, minimum, and increment sizes are all configurable within config.h. Assume that a user or OEM will alter these based on customized use-cases. Recommend not hard-coding these values into a GUI, but rather just show the actual override values and generic increment buttons.
+
+        - Override values don't change often during a job once set and only requires intermittent refreshing. This data field appears:
+
+          - After 10 or 20 (configurable 1-255) status reports, depending on is in a motion state or not.
+          - If an override value has changed, this data field will appear immediately in the next report. However, if `WCO:` is present, this data field will be delayed one report.
+          - In the second report after a reset/power-cycle.
+
+        - This data field will not appear if:
+
+          - It is disabled in the config.h file. No `$` mask setting available.
+          - The override refresh counter is in-between intermittent reports.
+          - `WCO:` exists in current report during refresh. Automatically set to try again on next report.
+
+	- **Accessory State:**
+
+		- `A:SFM` indicates the current state of accessory machine components, such as the spindle and coolant.
+
+		- Due to the new toggle overrides, these machine components may not be running according to the g-code program. This data is provided to ensure the user knows exactly what Grbl is doing at any given time.
+		
+		- Each letter after `A:` denotes a particular state. When it appears, the state is enabled. When it does not appear, the state is disabled.
+
+			- `S` indicates spindle is enabled in the CW direction. This does not appear with `C`.
+			- `C` indicates spindle is enabled in the CCW direction. This does not appear with `S`.
+        	- `F` indicates flood coolant is enabled.
+        	- `M` indicates mist coolant is enabled.
+		
+	   - Assume accessory state letters are presented in no particular order.
+      
+      - This data field appears:
+
+			- When any accessory state is enabled.
+        	- Only with the override values field in the same message. Any accessory state change will trigger the accessory state and override values fields to be shown on the next report.
+
+      - This data field will not appear if:
+
+        	- No accessory state is active.
+        	- It is disabled in the config.h file. No `$` mask setting available.
+        	- If override refresh counter is in-between intermittent reports.
+        	- `WCO:` exists in current report during refresh. Automatically set to try again on next report.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/jogging.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,93 @@
+# Grbl v1.1 Jogging
+
+This document outlines how to use Grbl v1.1's new jogging commands. These command differ because they can be cancelled and all queued motions are automatically purged with a simple jog-cancel or feed hold real-time command. Jogging command do not alter the g-code parser state in any way, so you no longer have to worry if you remembered to set the distance mode back to `G90` prior to starting a job. Also, jogging works well with an analog joysticks and rotary dials! See the implementation notes below.
+
+## How to Use
+Executing a jog requires a specific command structure, as described below:
+
+ - The first three characters must be '$J=' to indicate the jog.
+ - The jog command follows immediate after the '=' and works like a normal G1 command.
+ - Feed rate is only interpreted in G94 units per minute. A prior G93 state is ignored during jog.
+ - Required words:
+   - XYZ: One or more axis words with target value.
+   - F - Feed rate value. NOTE: Each jog requires this value and is not treated as modal.
+ - Optional words: Jog executes based on current G20/G21 and G90/G91 g-code parser state. If one of the following optional words is passed, that state is overridden for one command only.
+   - G20 or G21 - Inch and millimeter mode
+   - G90 or G91 - Absolute and incremental distances
+   - G53 - Move in machine coordinates
+   - N line numbers are valid. Will show in reports, if enabled, but is otherwise ignored.
+ - All other g-codes, m-codes, and value words (including S and T) are not accepted in the jog command.
+ - Spaces and comments are allowed in the command. These are removed by the pre-parser.
+
+ - Example: G21 and G90 are active modal states prior to jogging. These are sequential commands.
+    - `$J=X10.0 Y-1.5` will move to X=10.0mm and Y=-1.5mm in work coordinate frame (WPos).
+    - `$J=G91 G20 X0.5` will move +0.5 inches (12.7mm) to X=22.7mm (WPos). Note that G91 and G20 are only applied to this jog command.
+    - `$J=G53 Y5.0` will move the machine to Y=5.0mm in the machine coordinate frame (MPos). If the work coordinate offset for the y-axis is 2.0mm, then Y is 3.0mm in (WPos).
+
+Jog commands behave almost identically to normal g-code streaming. Every jog command will
+return an 'ok' when the jogging motion has been parsed and is setup for execution. If a
+command is not valid, Grbl will return an 'error:'. Multiple jogging commands may be
+queued in sequence.
+
+The main differences are:  
+
+- During a jog, Grbl will report a 'Jog' state while executing the jog.
+- A jog command will only be accepted when Grbl is in either the 'Idle' or 'Jog' states.
+- Jogging motions may not be mixed with g-code commands while executing, which will return a lockout error, if attempted.
+- All jogging motion(s) may be cancelled at anytime with a simple jog cancel realtime command or a feed hold or safety door event. Grbl will automatically flush Grbl's internal buffers of any queued jogging motions and return to the 'Idle' state. No soft-reset required.
+- If soft-limits are enabled, jog commands that exceed the machine travel simply does not execute the command and return an error, rather than throwing an alarm in normal operation.
+- IMPORTANT: Jogging does not alter the g-code parser state. Hence, no g-code modes need to be explicitly managed, unlike previous ways of implementing jogs with commands like 'G91G1X1F100'. Since G91, G1, and F feed rates are modal and if they are not changed back prior to resuming/starting a job, a job may not run how its was intended and result in a crash.
+
+------
+
+## Joystick Implementation
+
+Jogging in Grbl v1.1 is generally intended to address some prior issues with old bootstrapped jogging methods. Unfortunately, the new Grbl jogging is not a complete solution. Flash and memory restrictions prevent the original envisioned implementation, but most of these can be mimicked by the following suggested methodology. 
+
+With a combination of the new jog cancel and moving in `G91` incremental mode, the following implementation can create low latency feel for an analog joystick or similar control device.
+
+- Basic Implementation Overview: 
+  - Create a loop to read the joystick signal and translate it to a desired jog motion vector.
+  - Send Grbl a very short `G91` incremental distance jog command with a feed rate based on the joystick throw.
+  - Wait for an 'ok' acknowledgement before restarting the loop.
+  - Continually read the joystick input and send Grbl short jog motions to keep Grbl's planner buffer full.
+  - If the joystick is returned to its neutral position, stop the jog loop and simply send Grbl a jog cancel real-time command. This will stop motion immediately somewhere along the programmed jog path with virtually zero-latency and automatically flush Grbl's planner queue. It's not advised to use a feed hold to cancel a jog, as it can lead to inadvertently suspending Grbl if its sent after returning to the IDLE state.
+
+
+The overall idea is to minimize the total distance in the planner queue to provide a low-latency feel to joystick control. The main trick is ensuring there is just enough distance in the planner queue, such that the programmed feed rate is always met. How to compute this will be explain later. In practice, most machines will have a 0.5-1.0 second latency. When combined with the immediate jog cancel command, joystick interaction can be quite enjoyable and satisfying.
+
+However, please note, if a machine has a low acceleration and is being asked to move at a high programmed feed rate, joystick latency can get up to a handful of seconds. It may sound bad, but this is how long it'll take for a low acceleration machine, traveling at a high feed rate, to slow down to a stop. The argument can be made for a low acceleration machine that you really shouldn't be jogging at a high feed rate. It is difficult for a user to gauge where the machine will come to a stop. You risk overshooting your target destination, which can result in an expensive or dangerous crash. 
+
+One of the advantages of this approach is that a GUI can deterministically track where Grbl will go by the jog commands it has already sent to Grbl. As long as a jog isn't cancelled, every jog command is guaranteed to execute. In the event a jog cancel is invoked, the GUI would just need to refresh their internal position from a status report after Grbl has cleared planner buffer and returned to the IDLE (or DOOR, if ajar) state from the JOG state. This stopped position will always be somewhere along the programmed jog path. If desired, jogging can then be quickly and easily restarted with a new tracked path.
+
+In combination with `G53` move in machine coordinates, a GUI can restrict jogging from moving into "keep-out" zones inside the machine space. This can be very useful for avoiding crashing into delicate probing hardware, workholding mechanisms, or other fixed features inside machine space that you want to avoid.
+
+#### How to compute incremental distances
+
+The quickest and easiest way to determine what the length of a jog motion needs to be to minimize latency are defined by the following equations.
+
+`s = v * dt` - Computes distance traveled for next jog command.
+
+where:  
+
+- `s` - Incremental distance of jog command.
+- `dt` - Estimated execution time of a single jog command in seconds.  
+- `v` - Current jog feed rate in **mm/sec**, not mm/min. Less than or equal to max jog rate.
+- `N` - Number of Grbl planner blocks (`N=15`)
+- `T = dt * N` - Computes total estimated latency in seconds.
+ 
+The time increment `dt` may be defined to whatever value you need. Obviously, you'd like the lowest value, since that translates to lower overall latency `T`. However, it is constrained by two factors.
+
+- `dt > 10ms` - The time it takes Grbl to parse and plan one jog command and receive the next one. Depending on a lot of factors, this can be around 1 to 5 ms. To be conservative, `10ms` is used. Keep in mind that on some systems, this value may still be greater than `10ms` due to round-trip communication latency.
+
+- `dt > v^2 / (2 * a * (N-1))` - The time increment needs to be large enough to ensure the jog feed rate will be acheived. Grbl always plans to a stop over the total distance queued in the planner buffer. This is primarily to ensure the machine will safely stop if a disconnection occurs. This equation simply ensures that `dt` is big enough to satisfy this constraint. 
+
+	- For simplicity, use the max jog feed rate for `v` in mm/sec and the smallest acceleration setting between the jog axes being moved in mm/sec^2.
+
+	- For a lower latency, `dt` can be computed for each jog motion, where `v` is the current rate and `a` is the max acceleration along the jog vector. This is very useful if traveling a very slow speeds to locate a part zero. The `v` rate would be much lower in this scenario and the total latency would decrease quadratically.
+
+In practice, most CNC machines will operate with a jogging time increment of `0.025 sec` < `dt` < `0.06 sec`, which translates to about a `0.4` to `0.9` second total latency when traveling at the max jog rate. Good enough for most people. 
+
+However, if jogging at a slower speed and a GUI adjusts the `dt` with it, you can get very close to the 0.1 second response time by human-interface guidelines for "feeling instantaneous". Not too shabby!
+
+With some ingenuity, this jogging methodology may be applied to different devices such as a rotary dial or touchscreen. An "inertial-feel", like swipe-scrolling on a smartphone or tablet, can be simulated by managing the jog rate decay and sending Grbl the associated jog commands. While this jogging implementation requires more initial work by a GUI, it is also inherently more flexible because you have complete deterministic control of how jogging behaves.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/laser_mode.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,89 @@
+## Grbl v1.1 Laser Mode
+
+**_DISCLAIMER: Lasers are extremely dangerous devices. They can instantly cause fires and permanently damage your vision. Please read and understand all related documentation for your laser prior to using it. The Grbl project is not resposible for any damage or issues the firmware may cause, as defined by its GPL license._**
+
+----
+
+Outlined in this document is how Grbl alters its running conditions for the new laser mode to provide both improved performance and attempting to enforce some basic user safety precautions.
+
+## Laser Mode Overview
+
+The main difference between default Grbl operation and the laser mode is how the spindle/laser output is controlled with motions involved. Every time a spindle state `M3 M4 M5` or spindle speed `Sxxx` is altered, Grbl would come to a stop, allow the spindle to change, and then continue. This is the normal operating procedure for a milling machine spindle. It needs time to change speeds. 
+
+However, if a laser starts and stops like this for every spindle change, this leads to scorching and uneven cutting/engraving! Grbl's new laser mode prevents unnecessary stops whenever possible and adds a new dynamic laser power mode that automagically scales power based on current speed related to programmed rate. So, you can get super clean and crisp results, even on a low-acceleration machine!
+
+Enabling or disabling Grbl's laser mode is easy. Just alter the **$32** Grbl setting. 
+- **To Enable**: Send Grbl a `$32=1` command. 
+- **To Disable:** Send Grbl a `$32=0` command.
+
+**WARNING:** If you switch back from laser mode to a spindle for milling, you **MUST** disable laser mode by sending Grbl a `$32=0` command. Milling operations require the spindle to get up to the right rpm to cut correctly and to be **safe**, helping to prevent a tool from breaking and flinging metal shards everywhere. With laser mode disabled, Grbl will briefly pause upon any spindle speed or state change to give the spindle a chance to get up to speed before continuing.
+
+
+## Laser Mode Operation
+
+When laser mode is enabled, Grbl controls laser power by varying the **0-5V** voltage from the spindle PWM D11 pin. **0V** should be treated as disabled, while **5V** is full power. Intermediate output voltages are also assumed to be linear with laser power, such that **2.5V** is approximate 50% laser power. (A compile time option exists to shift this linear model to start at a non-zero voltage.) 
+
+By default, the spindle PWM frequency is **1kHz**, which is the recommended PWM frequency for most current Grbl-compatible lasers system. If a different frequency is required, this may be altered by editing the `cpu_map.h` file. 
+
+The laser is enabled with the `M3` spindle CW and `M4` spindle CCW commands. These enable two different laser modes that are advantageous for different reasons each.
+	
+- **`M3` Constant Laser Power Mode:**
+
+    - Constant laser power mode simply keeps the laser power as programmed, regardless if the machine is moving, accelerating, or stopped. This provides better control of the laser state. With a good G-code program, this can lead to more consistent cuts in more difficult materials. 
+    
+    - For a clean cut and prevent scorching with `M3` constant power mode, it's a good idea to add lead-in and lead-out motions around the line you want to cut to give some space for the machine to accelerate and decelerate.
+
+    - NOTE: `M3` can be used to keep the laser on for focusing.
+
+- **`M4` Dynamic Laser Power Mode:**
+    - Dynamic laser power mode will automatically adjust laser power based on the current speed relative to the programmed rate. It essentially ensures the amount of laser energy along a cut is consistent even though the machine may be stopped or actively accelerating. This is very useful for clean, precise engraving and cutting on simple materials across a large range of G-code generation methods by CAM programs. It will generally run faster and may be all you need to use.
+    
+    - Grbl calculates laser power based on the assumption that laser power is linear with speed and the material. Often, this is not the case. Lasers can cut differently at varying power levels and some materials may not cut well at a particular speed and/power. In short, this means that dynamic power mode may not work for all situations. Always do a test piece prior to using this with a new material or machine.
+		
+    - When not in motion, `M4` dynamic mode turns off the laser. It only turns on when the machine moves. This generally makes the laser safer to operate, because, unlike `M3`, it will never burn a hole through your table, if you stop and forget to turn `M3` off in time.
+
+Describe below are the operational changes to Grbl when laser mode is enabled. Please read these carefully and understand them fully, because nothing is worse than a garage _**fire**_.
+
+- Grbl will move continuously through **consecutive** motion commands when programmed with a new `S` spindle speed (laser power). The spindle PWM pin will be updated instantaneously through each motion without stopping.
+	- Example: The following set of g-code commands will not pause between each of them when laser mode is enabled, but will pause when disabled.
+	
+		```
+		G1 X10 S100 F50
+		G1 X0 S90
+		G2 X0 I5 S80
+		``` 
+	- Grbl will enforce a laser mode motion stop in a few circumstances. Primarily to ensure alterations stay in sync with the g-code program.
+
+		- Any `M3`, `M4`, `M5` spindle state _change_. 
+		- `M3` only and no motion programmed: A `S` spindle speed _change_.
+		- `M3` only and no motion programmed: A `G1 G2 G3` laser powered state _change_ to `G0 G80` laser disabled state.
+		- NOTE: `M4` does not stop for anything but a spindle state _change_.
+
+- The laser will only turn on when Grbl is in a `G1`, `G2`, or `G3` motion mode. 
+
+	- In other words, a `G0` rapid motion mode or `G38.x` probe cycle will never turn on and always disable the laser, but will still update the running modal state. When changed to a `G1 G2 G3` modal state, Grbl will immediately enable the laser based on the current running state.
+	
+	- Please remember that `G0` is the default motion mode upon power up and reset. You will need to alter it to `G1`, `G2`, or `G3` if you want to manually turn on your laser. This is strictly a safety measure.
+	
+	- Example: `G0 M3 S1000` will not turn on the laser, but will set the laser modal state to `M3` enabled and power of `S1000`. A following `G1` command will then immediately be set to `M3` and `S1000`.
+
+	- To have the laser powered during a jog motion, first enable a valid motion mode and spindle state. The following jog motions will inherit and maintain the previous laser state. Please use with caution though. This ability is primarily to allow turning on the laser on a _very low_ power to use the laser dot to jog and visibly locate the start position of a job.
+
+
+- An `S0` spindle speed of zero will turn off the laser. When programmed with a valid laser motion, Grbl will disable the laser instantaneously without stopping for the duration of that motion and future motions until set greater than zero..
+
+	- `M3` constant laser mode, this is a great way to turn off the laser power while continuously moving between a `G1` laser motion and a `G0` rapid motion without having to stop. Program a short `G1 S0` motion right before the `G0` motion and a `G1 Sxxx` motion is commanded right after to go back to cutting.
+
+
+-----
+###CAM Developer Implementation Notes
+
+TODO: Add some suggestions on how to write laser G-code for Grbl. 
+
+- When using `M3` constant laser power mode, try to avoid force-sync conditions during a job whenever possible. Basically every spindle speed change must be accompanied by a valid motion. Any motion is fine, since Grbl will automatically enable and disable the laser based on the modal state. Avoid a `G0` and `G1` command with no axis words in this mode and in the middle of a job.
+
+- Ensure smooth motions throughout by turning the laser on and off without an `M3 M4 M5` spindle state command. There are two ways to do this:
+
+    - _Program a zero spindle speed `S0`_: `S0` is valid G-code and turns off the spindle/laser without changing the spindle state. In laser mode, Grbl will smoothly move through consecutive motions and turn off the spindle. Conversely, you can turn on the laser with a spindle speed `S` greater than zero. Remember that `M3` constant power mode requires any spindle speed `S` change to be programmed with a motion to allow continuous motion, while `M4` dynamic power mode does not.
+
+    - _Program an unpowered motion between powered motions_: If you are traversing between parts of a raster job that don't need to have the laser powered, program a `G0` rapid between them. `G0` enforces the laser to be disabled automatically. The last spindle speed programmed doesn't change, so if a valid powered motion, like a `G1` is executed after, it'll immediately re-power the laser with the last programmed spindle speed when executing that motion.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/old_wiki_pages/interface_notes.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,105 @@
+***
+
+# Writing an Interface for Grbl
+
+_**FOR DEVELOPERS ONLY: This section outlines the recommended ways to setup a communications and streaming protocol with Grbl for a GUI.**_
+
+The general interface for Grbl has been described above, but what's missing is how to run an entire G-code program on Grbl, when it doesn't seem to have an upload feature. Or, how to build a decent GUI with real-time feedback. This is where this section fits in. Early on, users fiercely requested for flash drive, external RAM, LCD support, joysticks, or network support so they can upload a g-code program and run it directly on Grbl. The general answer to that is, good ideas, but Grbl doesn't need them. Grbl already has nearly all of the tools and features to reliably communicate with a simple graphical user interface (GUI). Plus, we want to minimize as much as we can on what Grbl should be doing, because, in the end, Grbl needs to be concentrating on producing clean, reliable motion. That's it.
+
+
+## Streaming a G-Code Program to Grbl
+
+Here we will describe three different streaming methods for Grbl GUIs, but really there's only two that we recommend using. One of the main problems with streaming to Grbl is the USB port itself. Arduinos and most all micro controllers use a USB-to-serial converter chip that, at times, behaves strangely and not typically how you'd expect, like USB packet buffering and delays that can wreak havoc to a streaming protocol. Another problem is how to deal with some of the latency and oddities of the PCs themselves, because none of them are truly real-time and always create micro-delays when executing other tasks. Regardless, we've come up with ways to ensure the G-code stream is reliable and simple.
+
+#### Streaming Protocol: Simple Send-Response _[Recommended for Grbl v0.9+]_
+The send-response streaming protocol is the most fool-proof and simplest method to stream a G-code program to Grbl. The host PC interface simply sends a line of G-code to Grbl and waits for an `ok` or `error:` response before sending the next line of G-code. So, no matter if Grbl needs to wait for room in the look-ahead planner buffer to finish parsing and executing the last line of G-code or if the the host computer is busy doing something, this guarantees both to the host PC and Grbl, the programmed G-code has been sent and received properly. An example of this protocol is published in our `simple_stream.py` script in our repository.
+
+However, it's also the slowest of three outlined streaming protocols. Grbl essentially has two buffers between the execution of steps and the host PC interface. One of them is the serial receive buffer. This briefly stores up to 127 characters of data received from the host PC until Grbl has time to fetch and parse the line of G-code. The other buffer is the look-ahead planner buffer. This buffer stores up to 17 line motions that are acceleration-planned and optimized for step execution. Since the send-response protocol receives a line of G-code while the host PC waits for a response, Grbl's serial receive buffer is usually empty and under-utilized. If Grbl is actively running and executing steps, Grbl will immediately begin to execute and empty the look-ahead planner buffer, while it sends the response to the host PC, waits for the next line from the host PC, upon receiving it, parse and plan it, and add it to the end of the look-ahead buffer.
+
+Although this communication lag may take only a fraction of a second, there is a cumulative effect, because there is a lag with every G-code block sent to Grbl. In certain scenarios, like a G-code program containing lots of sequential, very short, line segments with high feed rates, the cumulative lag can be large enough to empty and starve the look-ahead planner buffer within this time. This could lead to start-stop motion when the streaming can't keep up with G-code program execution. Also, since Grbl can only plan and optimize what's in the look-ahead planner buffer, the performance through these types of motions will never be full-speed, because look-ahead buffer will always be partially full when using this streaming method. If your expected application doesn't contain a lot of these short line segments with high feed rates, this streaming protocol should be more than adequate for a vast majority of applications, is very robust, and is a quick way to get started. However, we do not recommend using this method for Grbl versions v0.8 or prior due to some performance issues with these versions.
+
+#### Streaming Protocol: Via Flow Control (XON/XOFF)
+
+To avoid the risk of starving the look-ahead planner buffer, a flow control streaming protocol can be used to try to keep Grbl's serial receive buffer full, so that Grbl has immediate access to the next g-code line to parse and plan without having to wait for the host PC to send it. Flow control, also known as XON/XOFF software flow control, uses two special characters to tell the host PC when it has or doesn't have room in the serial receive buffer to receive more data. When there is room, usually at 20% full, the special character is sent to the host PC indicating ready-to-receive. The host PC will begin to send data until it receives the other stop-receive special character, usually at 80% full. Grbl's XON/XOFF software flow control feature may be enabled through the config.h, but is not officially supported for the following reasons.
+
+While sound in logic, software flow control has a number of problems. The timing between Grbl and the host PC is almost never perfectly in sync, in large part due to the USB protocol and the USB-serial converter chips on every Arduino. This poses a big problem when sending and receiving these special flow-control characters. When Grbl's serial receive buffer is low, the time between when it sends the ready-to-receive character and when the host PC sends more data all depends everything in between. If the host PC is busy or the Arduino USB-serial converter is not sending the character on time, this lag can cause Grbl to wait for more serial data to come in before parsing and executing the next line of G-code. Even worse though, if the serial receive buffer is nearing full and the stop-receive character is sent, the host PC may not receive the signal in time to stop the data transfer and over-flow Grbl's serial buffer. This is bad and will corrupt the data stream.
+
+Because the software flow-control method is dependent on the performance of the USB-serial converter on the Arduino and the host PC, the low and high watermarks for the ready-to-receive and stop-receive characters must be tuned for each case. Thus, it's not really a robust solution. In our experience with XON/XOFF software flow control, it absolutely **DOES NOT** work with Arduinos with the Atmega8U/16U USB-serial converter chips (on all current Arduinos from the Uno to Mega2560). For some reason, there are USB packet delays that are out of Grbl's control and almost always led to data corruption. However, XON/XOFF worked, but only on older Arduinos or micro controllers that featured an FTDI RS232 USB-serial converter chip, such as the Duemilanove or controllers with an FTDI break-out board. The FTDI's firmware reliably sent the XON/XOFF special characters in time and on time. We're not sure why there is such a difference between them.
+
+If you decide to use XON/XOFF software flow control for your GUI, keep in mind that, at the moment, it'll only really works with FTDI USB-serial converters. But, the great thing about this method is that you can connect with Grbl over a serial emulator program like Coolterm, enable XON/XOFF flow control, cut-and-paste an entire g-code program into it, and Grbl will execute it completely. (Nice but not really necessary.)
+
+#### Streaming Protocol: Character-Counting _[**Recommended with Reservations**]_
+
+To get the best of both worlds, the simplicity and reliability of the send-response method and assurance of maximum performance with software flow control, we came up with a simple character-counting protocol for streaming a G-code program to Grbl. It works like the send-response method, where the host PC sends a line of G-code for Grbl to execute and waits for a response, but, rather than needing special XON/XOFF characters for flow control, this protocol simply uses Grbl's responses as a way to reliably track how much room there is in Grbl's serial receive buffer. An example of this protocol is outlined in the `stream.py` streaming script in our repo.
+
+The main difference between this protocol and the others is the host PC needs to maintain a standing count of how many characters it has sent to Grbl and then subtract the number of characters corresponding to the line executed with each Grbl response. Suppose there is a short G-code program that has 5 lines with 25, 40, 31, 58, and 20 characters (counting the line feed and carriage return characters too). We know Grbl has a 127 character serial receive buffer, and the host PC can send up to 127 characters without overflowing the buffer. If we let the host PC send as many complete lines as we can without over flowing Grbl's serial receive buffer, the first three lines of 25, 40, and 31 characters can be sent for a total of 96 characters. When Grbl responds, we know the first line has been processed and is no longer in the serial read buffer. As it stands, the serial read buffer now has the 40 and 31 character lines in it for a total of 71 characters. The host PC needs to then determine if it's safe to send the next line without overflowing the buffer. With the next line at 58 characters and the serial buffer at 71 for a total of 129 characters, the host PC will need to wait until more room has cleared from the serial buffer. When the next Grbl response comes in, the second line has been processed and only the third 31 character line remains in the serial buffer. At this point, it's safe to send the remaining last two 58 and 20 character lines of the g-code program for a total of 109.
+
+While seemingly complicated, this character-counting streaming protocol is extremely effective in practice. It always ensures Grbl's serial read buffer is filled, while never overflowing it. It maximizes Grbl's performance by keeping the look-ahead planner buffer full by better utilizing the bi-directional data flow of the serial port, and it's fairly simple to implement as our `stream.py` script illustrates. We have stress-tested this character-counting protocol to extremes and it has not yet failed. Seemingly, only the speed of the serial connection is the limit.
+
+_UPDATE: Up until recently, we've recommended that Grbl GUIs use this streaming protocol. It is indeed very efficient and effective, but there are a couple of additional things interface writers should aware of. These are issues being worked on for the v1.0 release._
+- _Since the GUI is preloading Grbl's serial RX buffer with commands, Grbl will continually execute all of the queued g-code in the RX serial buffer. The first problem is if there is an error at the beginning of the RX buffer, Grbl will continue to execute the remaining buffered g-code and the GUI won't be able to control what happens. The interim solution is to check all of the g-code via the $C check mode, so all errors are vetted prior to streaming._
+- _When Grbl stores data to EEPROM, the AVR requires all interrupts to be disabled during this write process, including the serial RX ISR. This means that if a g-code or Grbl `$` command writes to EEPROM, the data sent during the write may be lost. This is usually rare and typically occurs when streaming a G10 command inappropriately inside a program. For robustness, GUIs should track and detect these EEPROM write commands and handle them appropriately by waiting for the queue to finish executing before sending more data. Note that the simple send-response protocol doesn't not suffer from this issue._
+
+
+## Interacting with Grbl's Systems
+
+Along with streaming a G-code program, there a few more things to consider when writing a GUI for Grbl, such as how to use status reporting, real-time control commands, dealing with EEPROM, and general message handling.
+
+#### Status Reporting
+When a `?` character is sent to Grbl (no additional line feed or carriage return character required), it will immediately respond with something like `<Idle,MPos:0.000,0.000,0.000,WPos:0.000,0.000,0.000>` to report its state and current position. The `?` is always picked-off and removed from the serial receive buffer whenever Grbl detects one. So, these can be sent at any time. Also, to make it a little easier for GUIs to pick up on status reports, they are always encased by `<>` chevrons.
+
+Developers can use this data to provide an on-screen position digital-read-out (DRO) for the user and/or to show the user a 3D position in a virtual workspace. We recommend querying Grbl for a `?` real-time status report at no more than 5Hz. 10Hz may be possible, but at some point, there are diminishing returns and you are taxing Grbl's CPU more by asking it to generate and send a lot of position data.
+
+Grbl's status report is fairly simply in organization. It always starts with a word describing the machine state like `IDLE` (descriptions of these are available elsewhere in the Wiki). The following data values are usually in the order listed below and separated by commas, but may not be in the exact order or printed at all. Report output depends on the user's `$10` status report mask setting.
+
+* `MPos:0.000,0.000,0.000` : Machine position listed as `X,Y,Z` coordinates. Units (mm or inch) depends on `$13` Grbl unit reporting setting.
+* `WPos:0.000,0.000,0.000` : Work position listed as `X,Y,Z` coordinates. Units (mm or inch) depends on `$13` Grbl unit reporting setting.
+* `Buf:0` : Number of motions queued in Grbl's planner buffer.
+* `RX:0` : Number of characters queued in Grbl's serial RX receive buffer.
+
+#### Real-Time Control Commands
+The real-time control commands, `~` cycle start/resume, `!` feed hold, and `^X` soft-reset, all immediately signal Grbl to change its running state. Just like `?` status reports, these control characters are picked-off and removed from the serial buffer when they are detected and do not require an additional line-feed or carriage-return character to operate.
+
+#### EEPROM Issues
+EEPROM access on the Arduino AVR CPUs turns off all of the interrupts while the CPU reads and writes to EEPROM. This poses a problem for certain features in Grbl, particularly if a user is streaming and running a g-code program, since it can pause the main step generator interrupt from executing on time. Most of the EEPROM access is restricted by Grbl when it's in certain states, but there are some things that developers need to know.
+
+* Settings can't be streamed to Grbl with either the XON/XOFF software flow control or the character-counting streaming protocols. Only the simple send-response protocol works. This is because during the EEPROM write, the AVR CPU also shuts-down the serial RX interrupt, which means data can get corrupted or lost. Note that the send-response protocol doesn't send any data until a response comes back.
+
+* When changing work coordinates, printing `$#` parameters, or accessing the `G28`/`G30` predefined positions, Grbl has to fetch them from EEPROM. There is a small chance this access can pause the stepper or serial receive interrupt long enough to cause motion issues, but since it only fetches 12 bytes at a time at 2 cycles per fetch, the chances are very small that this will do anything to how Grbl runs. We just suggest keeping an eye on this and report to us any issues you might think are related to this.
+
+For reference:
+* Grbl's EEPROM write commands: `G10 L2`, `G10 L20`, `G28.1`, `G30.1`, `$x=`, `$I=`, `$Nx=`, `$RST=`
+* Grbl's EEPROM read commands: `G54-G59`, `G28`, `G30`, `$$`, `$I`, `$N`, `$#`
+
+#### Message Handling
+Most of the feedback from Grbl fits into nice categories so GUIs can easily tell what is what. Here's how they are organized:
+
+* `ok`: Standard all-is-good response to a single line sent to Grbl.
+* `error:`: Standard error response to a single line sent to Grbl.
+* `ALARM:`: A critical error message that occurred. All processes stopped until user acknowledgment.
+* `[]`: All feedback messages are sent in brackets. These include parameter and g-code parser state print-outs.
+* `<>`: Status reports are sent in chevrons.
+
+There are few things that don't fit neatly into this setup at the moment. In the next version, we'll try to make this more universal, but for now, your GUIs will need to manually account for these:
+* The startup message.
+* `$` Help print-out.
+* `$N` Start-up blocks execution after the startup message.
+* The `$$` view Grbl settings print-out.
+
+#### G-code Error Handling
+
+As of Grbl v0.9, the g-code parser is fully standards-compilant with complete error-checking. When a G-code parser detects an error in a G-code block/line, the parser will dump everything in the block from memory and report an `error:` back to the user or GUI. This dump can pose problematic, because the bad G-code block may have contained some valuable positioning commands or feed rate settings.
+
+It's highly recommended to do what all professional CNC controllers do when they detect an error in the G-code program, _**halt**_. Don't do anything further until the user has modified the G-code and fixed the error in their program. Otherwise, bad things could happen.
+
+As a service to GUIs, Grbl has a "check G-code" mode, enabled by the `$C` system command. GUIs can stream a G-code program to Grbl, where it will parse it, error-check it, and report `ok`'s and `errors:`'s without powering on anything or moving. So GUIs can pre-check the programs before streaming them for real. To disable the "check G-code" mode, send another `$C` system command and Grbl will automatically soft-reset to flush and re-initialize the G-code parser and the rest of the system. This perhaps should be run in the background when a user first loads a program, before a user sets up his machine. This flushing and re-initialization clears `G92`'s by G-code standard, which some users still incorrectly use to set their part zero.
+
+#### Jogging
+
+Unfortunately, Grbl doesn't have a proper jogging interface, at least for now. This was to conserve precious flash space for the development of Grbl v0.9, but may be installed in the next release of Grbl. However, authors of Grbl GUIs have come up with ways to simulate jogging with Grbl by sending incremental motions, such as `G91 X0.1`, with each jogging click or key press. This works pretty well, but, if uncontrolled, a user can easily queue up more motions than they want without realizing it and move well-past their desired location.
+
+The general methodology that has been shown to work is to simply restrict the number of jogging commands sent to Grbl. This can be done by disabling key repeating when held down. The planner buffer queue size can be tracked such that only a handful of motions can be queued and executed.
+
+#### Synchronization
+
+For situations when a GUI needs to run a special set of commands for tool changes, auto-leveling, etc, there often needs to be a way to know when Grbl has completed a task and the planner buffer is empty. The absolute simplest way to do this is to insert a `G4 P0.01` dwell command, where P is in seconds and must be greater than 0.0. This acts as a quick force-synchronization and ensures the planner buffer is completely empty before the GUI sends the next task to execute.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/realtime_cmds.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,149 @@
+## Grbl v1.1 Realtime commands
+
+Realtime commands are single control characters that may be sent to Grbl to command and perform an action in real-time. This means that they can be sent at anytime, anywhere, and Grbl will immediately respond, regardless of what it is doing at the time. These commands include a reset, feed hold, resume, status report query, and overrides (in v1.1).
+
+A realtime command:
+
+- Will execute within tens of milliseconds.
+
+- Is a single character that may be sent to Grbl at any time.
+
+- Does not require a line feed or carriage return after them.
+
+- Is not considered a part of the streaming protocol. 
+
+- Are intercepted when they are received and never placed in a buffer to be parsed by Grbl.
+
+- Will ignore multiple commands until it has executed the first received command.
+
+- May be tied to an input pin and may be operated with a button or switch.
+
+- Actions depends on state or what Grbl is doing. It may not do anything.
+
+- Descriptions explain how they work and what to expect.
+
+#### ASCII Realtime Command Descriptions
+Four realtime commands are type-able by users on a keyboard and shown in the `$` Grbl help message. These realtime command characters control some of Grbl's basic functions.
+
+- `0x18` (ctrl-x) : Soft-Reset
+
+  - Immediately halts and safely resets Grbl without a power-cycle.
+  - Accepts and executes this command at any time.
+  - If reset while in motion, Grbl will throw an alarm to indicate position may be lost from the motion halt.
+  - If reset while in not motion, position is retained and re-homing is not required.
+  - An input pin is available to connect a button or switch.
+
+
+- `?` : Status Report Query
+
+  - Immediately generates and sends back runtime data with a status report.
+  - Accepts and executes this command at any time, except during a homing cycle and when critical alarm (hard/soft limit error) is thrown.
+
+
+- `~` : Cycle Start / Resume
+
+  - Resumes a feed hold, a safety door/parking state when the door is closed, and the M0 program pause states.
+  - Command is otherwise ignored.
+  - If the parking compile-time option is enabled and the safety door state is ready to resume, Grbl will re-enable the spindle and coolant, move back into position, and then resume.
+  - An input pin is available to connect a button or switch.
+
+
+- `!` : Feed Hold
+
+  - Places Grbl into a suspend or HOLD state. If in motion, the machine will decelerate to a stop and then be suspended.
+  - Command executes when Grbl is in an IDLE, RUN, or JOG state. It is otherwise ignored.
+  - If jogging, a feed hold will cancel the jog motion and flush all remaining jog motions in the planner buffer. The state will return from JOG to IDLE or DOOR, if was detected as ajar during the active hold.
+  - By machine control definition, a feed hold does not disable the spindle or coolant. Only motion.
+  - An input pin is available to connect a button or switch.
+
+
+#### Extended-ASCII Realtime Command Descriptions
+
+Grbl v1.1 installed more than a dozen new realtime commands to control feed, rapid, and spindle overrides. To help prevent users from inadvertently altering overrides with a keystroke and allow for more commands later on, all of the new control characters have been moved to the extended ASCII character set. These are not easily type-able on a keyboard, but, depending on the OS, they may be entered using specific keystroke and code. GUI developers will need to be able to send extended ASCII characters, values `128 (0x80)` to `255 (0xFF)`, to Grbl to take advantage of these new features.
+
+- `0x84` : Safety Door
+
+  - Although typically connected to an input pin to detect the opening of a safety door, this command allows a GUI to enact the safety door behavior with this command.
+  - Immediately suspends into a DOOR state and disables the spindle and coolant. If in motion, the machine will decelerate to a stop and then be suspended.
+  - If executed during homing, Grbl will instead halt motion and throw a homing alarm.
+  - If already in a suspend state or HOLD, the DOOR state supersedes it.
+  - If the parking compile-time option is enabled, Grbl will park the spindle to a specified location.
+  - Command executes when Grbl is in an IDLE, HOLD, RUN, HOMING, or JOG state. It is otherwise ignored.
+  - If jogging, a safety door will cancel the jog and all queued motions in the planner buffer. When the safety door is closed and resumed, Grbl will return to an IDLE state.
+  - An input pin is available to connect a button or switch, if enabled with a compile-time option.
+  - Some builds of Grbl v0.9 used the `@` character for this command, but it was undocumented. Moved to extended-ASCII to prevent accidental commanding.
+
+
+- `0x85` : Jog Cancel
+
+  - Immediately cancels the current jog state by a feed hold and automatically flushing any remaining jog commands in the buffer.
+  - Command is ignored, if not in a JOG state or if jog cancel is already invoked and in-process.
+  - Grbl will return to the IDLE state or the DOOR state, if the safety door was detected as ajar during the cancel.
+  
+
+- Feed Overrides
+
+  - Immediately alters the feed override value. An active feed motion is altered within tens of milliseconds.
+  - Does not alter rapid rates, which include G0, G28, and G30, or jog motions.
+  - Feed override value can not be 10% or greater than 200%.
+  - If feed override value does not change, the command is ignored.
+  - Feed override range and increments may be changed in config.h.
+  - The commands are:
+    - `0x90` : Set 100% of programmed rate.
+    - `0x91` : Increase 10%
+    - `0x92` : Decrease 10%
+    - `0x93` : Increase 1%
+    - `0x94` : Decrease 1%
+
+
+- Rapid Overrides
+
+  - Immediately alters the rapid override value. An active rapid motion is altered within tens of milliseconds.
+  - Only effects rapid motions, which include G0, G28, and G30.
+  - If rapid override value does not change, the command is ignored.
+  - Rapid override set values may be changed in config.h.
+  - The commands are:
+    - `0x95` : Set to 100% full rapid rate.
+    - `0x96` : Set to 50% of rapid rate.
+    - `0x97` : Set to 25% of rapid rate.
+
+
+- Spindle Speed Overrides
+
+  - Immediately alters the spindle speed override value. An active spindle speed is altered within tens of milliseconds.
+  - Override values may be changed at any time, regardless of if the spindle is enabled or disabled.
+  - Spindle override value can not be 10% or greater than 200%
+  - If spindle override value does not change, the command is ignored.
+  - Spindle override range and increments may be altered in config.h.
+  - The commands are:
+    - `0x99` : Set 100% of programmed spindle speed
+    - `0x9A` : Increase 10%
+    - `0x9B` : Decrease 10%
+    - `0x9C` : Increase 1%
+    - `0x9D` : Decrease 1%
+
+
+- `0x9E` : Toggle Spindle Stop
+
+  - Toggles spindle enable or disable state immediately, but only while in the HOLD state.
+  - The command is otherwise ignored, especially while in motion. This prevents accidental disabling during a job that can either destroy the part/machine or cause personal injury. Industrial machines handle the spindle stop override similarly.
+  - When motion restarts via cycle start, the last spindle state will be restored and wait 4.0 seconds (configurable) before resuming the tool path. This ensures the user doesn't forget to turn it back on.
+  - While disabled, spindle speed override values may still be altered and will be in effect once the spindle is re-enabled.
+  - If a safety door is opened, the DOOR state will supersede the spindle stop override, where it will manage the spindle re-energizing itself upon closing the door and resuming. The prior spindle stop override state is cleared and reset.
+
+
+- `0xA0` : Toggle Flood Coolant
+
+  - Toggles flood coolant state and output pin until the next toggle or g-code command alters it.
+  - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.
+  - This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M8` or `M9` g-code command.
+  - When `$G` g-code parser state is queried, the toggle override change will be reflected by an `M8` enabled or disabled with an `M9` or not appearing when `M7` is present.
+
+
+- `0xA1` : Toggle Mist Coolant
+
+  - Enabled by `ENABLE_M7` compile-time option. Default is disabled.
+  - Toggles mist coolant state and output pin until the next toggle or g-code command alters it.
+  - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.
+  - This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M7` or `M9` g-code command.
+  - When `$G` g-code parser state is queried, the toggle override change will be reflected by an `M7` enabled or disabled with an `M9` or not appearing when `M8` is present.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/markdown/settings.md	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,259 @@
+## Getting Started
+
+First, connect to Grbl using the serial terminal of your choice.
+
+Set the baud rate  to **115200** as 8-N-1 (8-bits, no parity, and 1-stop bit.)
+
+Once connected
+ you should get the Grbl-prompt, which looks like this:
+
+```
+Grbl 1.1d ['$' for help]
+```
+
+Type $ and press enter to have Grbl print a help message. You should not see any local echo of the $ and enter. Grbl should respond with:
+
+```
+[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]
+```
+
+The ‘$’-commands are Grbl system commands used to tweak the settings, view or change Grbl's states and running modes, and start a homing cycle. The last four **non**-'$' commands are realtime control commands that can be sent at anytime, no matter what Grbl is doing. These either immediately change Grbl's running behavior or immediately print a report of the important realtime data like current position (aka DRO).
+
+***
+
+##Grbl Settings
+
+#### $$ - View Grbl settings
+To view the settings, type `$$` and press enter after connecting to Grbl. Grbl should respond with a list of the current system settings, as shown in the example below. All of these settings are persistent and kept in EEPROM, so if you power down, these will be loaded back up the next time you power up your Arduino.
+
+The `x` of `$x=val` indicates a particular setting, while `val` is the setting value. In prior versions of Grbl, each setting had a description next to it in `()` parentheses, but Grbl v1.1+ no longer includes them unfortunately. This was done to free up precious flash memory to add the new features available in v1.1. However, most good GUIs will help out by attaching descriptions for you, so you know what you are looking at.
+
+```
+$0=10
+$1=25
+$2=0
+$3=0
+$4=0
+$5=0
+$6=0
+$10=1
+$11=0.010
+$12=0.002
+$13=0
+$20=0
+$21=0
+$22=1
+$23=0
+$24=25.000
+$25=500.000
+$26=250
+$27=1.000
+$30=1000.
+$31=0.
+$32=0
+$100=250.000
+$101=250.000
+$102=250.000
+$110=500.000
+$111=500.000
+$112=500.000
+$120=10.000
+$121=10.000
+$122=10.000
+$130=200.000
+$131=200.000
+$132=200.000
+```
+
+#### $x=val - Save Grbl setting
+
+The `$x=val` command saves or alters a Grbl setting, which can be done manually by sending this command when connected to Grbl through a serial terminal program, but most Grbl GUIs will do this for you as a user-friendly feature.
+
+To manually change e.g. the microseconds step pulse option to 10us you would type this, followed by an enter:
+```
+$0=10
+```
+If everything went well, Grbl will respond with an 'ok' and this setting is stored in EEPROM and will be retained forever or until you change them. You can check if Grbl has received and stored your setting correctly by typing `$$` to view the system settings again.
+
+
+***
+
+## Grbl's `$x=val` settings and what they mean
+
+**NOTE: From Grbl v0.9 to Grbl v1.1, only `$10` status reports changed and new `$30`/ `$31` spindle rpm max/min and `$32` laser mode settings were added. Everything else is the same.**
+
+#### $0 – Step pulse, microseconds
+
+Stepper drivers are rated for a certain minimum step pulse length. Check the data sheet or just try some numbers. You want the shortest pulses the stepper drivers can reliably recognize. If the pulses are too long, you might run into trouble when running the system at very high feed and pulse rates, because the step pulses can begin to overlap each other. We recommend something around 10 microseconds, which is the default value.
+
+#### $1 - Step idle delay, milliseconds
+
+Every time your steppers complete a motion and come to a stop, Grbl will delay disabling the steppers by this value. **OR**, you can always keep your axes enabled (powered so as to hold position) by setting this value to the maximum 255 milliseconds. Again, just to repeat, you can keep all axes always enabled by setting `$1=255`.
+
+The stepper idle lock time is the time length Grbl will keep the steppers locked before disabling. Depending on the system, you can set this to zero and disable it. On others, you may need 25-50 milliseconds to make sure your axes come to a complete stop before disabling. This is to help account for machine motors that do not like to be left on for long periods of time without doing something. Also, keep in mind that some stepper drivers don't remember which micro step they stopped on, so when you re-enable, you may witness some 'lost' steps due to this. In this case, just keep your steppers enabled via `$1=255`.
+
+#### $2 – Step port invert, mask
+
+This setting inverts the step pulse signal. By default, a step signal starts at normal-low and goes high upon a step pulse event. After a step pulse time set by `$0`, the pin resets to low, until the next step pulse event. When inverted, the step pulse behavior switches from normal-high, to low during the pulse, and back to high. Most users will not need to use this setting, but this can be useful for certain CNC-stepper drivers that have peculiar requirements. For example, an artificial delay between the direction pin and step pulse can be created by inverting the step pin.
+
+This invert mask setting is a value which stores the axes to invert as bit flags. You really don't need to completely understand how it works. You simply need to enter the settings value for the axes you want to invert. For example, if you want to invert the X and Z axes, you'd send `$2=5` to Grbl and the setting should now read `$2=5 (step port invert mask:00000101)`.
+
+| Setting Value | Mask |Invert X | Invert Y | Invert Z |
+|:-------------:|:----:|:-------:|:--------:|:--------:|
+| 0 | 00000000 |N | N | N |
+| 1 | 00000001 |Y | N | N |
+| 2 | 00000010 |N | Y | N |
+| 3 | 00000011 |Y | Y | N |
+| 4 | 00000100 |N | N | Y |
+| 5 | 00000101 |Y | N | Y |
+| 6 | 00000110 |N | Y | Y |
+| 7 | 00000111 |Y | Y | Y |
+
+#### $3 – Direction port invert, mask
+
+This setting inverts the direction signal for each axis. By default, Grbl assumes that the axes move in a positive direction when the direction pin signal is low, and a negative direction when the pin is high. Often, axes don't move this way with some machines. This setting will invert the direction pin signal for those axes that move the opposite way.
+
+This invert mask setting works exactly like the step port invert mask and stores which axes to invert as bit flags. To configure this setting, you simply need to send the value for the axes you want to invert. Use the table above. For example, if want to invert the Y axis direction only, you'd send `$3=2` to Grbl and the setting should now read `$3=2 (dir port invert mask:00000010)`
+
+#### $4 - Step enable invert, boolean
+
+By default, the stepper enable pin is high to disable and low to enable. If your setup needs the opposite, just invert the stepper enable pin by typing `$4=1`. Disable with `$4=0`. (May need a power cycle to load the change.)
+
+#### $5 -  Limit pins invert, boolean
+
+By default, the limit pins are held normally-high with the Arduino's internal pull-up resistor. When a limit pin is low, Grbl interprets this as triggered. For the opposite behavior, just invert the limit pins by typing `$5=1`. Disable with `$5=0`. You may need a power cycle to load the change.
+
+NOTE: If you invert your limit pins, you will need an external pull-down resistor wired in to all of the limit pins to prevent overloading the pins with current and frying them.
+
+#### $6 -  Probe pin invert, boolean
+
+By default, the probe pin is held normally-high with the Arduino's internal pull-up resistor. When the probe pin is low, Grbl interprets this as triggered. For the opposite behavior, just invert the probe pin by typing `$6=1`. Disable with `$6=0`. You may need a power cycle to load the change.
+
+NOTE: If you invert your probe pin, you will need an external pull-down resistor wired in to the probe pin to prevent overloading it with current and frying it.
+
+
+#### $10 - Status report, mask
+
+This setting determines what Grbl real-time data it reports back to the user when a '?' status report is sent. This data includes current run state, real-time position, real-time feed rate, pin states, current override values, buffer states, and the g-code line number currently executing (if enabled through compile-time options).
+
+By default, the new report implementation in Grbl v1.1+ will include just about everything in the standard status report. A lot of the data is hidden and will appear only if it changes. This increases efficiency dramatically over of the old report style and allows you to get faster updates and still get more data about your machine. The interface documentation outlines how it works and most of it applies only to GUI developers or the curious.
+
+To keep things simple and consistent, Grbl v1.1 has only two reporting options. These are primarily here just for users and developers to help set things up. 
+
+- Position type may be specified to show either machine position (`MPos:`)  or work position (`WPos:`), but no longer both at the same time. Enabling work position is useful in certain scenarios when Grbl is being directly interacted with through a serial terminal, but _machine position reporting should be used by default._ 
+- Usage data of Grbl's planner and serial RX buffers may be enabled. This shows the number of blocks or bytes available in the respective buffers. This is generally used to helps determine how Grbl is performing when testing out a streaming interface. _This should be disabled by default._
+
+Use the table below enables and disable reporting options. Simply add the values listed of what you'd like to enable, then save it by sending Grbl your setting value. For example, the default report with machine position and no buffer data reports setting is `$10=1`. If work position and buffer data are desired, the setting will be `$10=2`.
+
+| Report Type | Value | Description |
+|:-------------:|:----:|:----:|
+| Position Type | 1 | Enabled `MPos:`. Disabled `WPos:`. |
+| Buffer Data | 2 | Enabled `Buf:` field appears with planner and serial RX available buffer.
+
+#### $11 - Junction deviation, mm
+
+Junction deviation is used by the acceleration manager to determine how fast it can move through line segment junctions of a G-code program path. For example, if the G-code path has a sharp 10 degree turn coming up and the machine is moving at full speed, this setting helps determine how much the machine needs to slow down to safely go through the corner without losing steps.
+
+How we calculate it is a bit complicated, but, in general, higher values gives faster motion through corners, while increasing the risk of losing steps and positioning. Lower values makes the acceleration manager more careful and will lead to careful and slower cornering. So if you run into problems where your machine tries to take a corner too fast, *decrease* this value to make it slow down when entering corners. If you want your machine to move faster through junctions, *increase* this value to speed it up. For curious people, hit this [link](http://t.co/KQ5BvueY) to read about Grbl's cornering algorithm, which accounts for both velocity and junction angle with a very simple, efficient, and robust method.
+
+#### $12 – Arc tolerance, mm
+
+Grbl renders G2/G3 circles, arcs, and helices by subdividing them into teeny tiny lines, such that the arc tracing accuracy is never below this value. You will probably never need to adjust this setting, since `0.002mm` is well below the accuracy of most all CNC machines. But if you find that your circles are too crude or arc tracing is performing slowly, adjust this setting. Lower values give higher precision but may lead to performance issues by overloading Grbl with too many tiny lines. Alternately, higher values traces to a lower precision, but can speed up arc performance since Grbl has fewer lines to deal with.
+
+For the curious, arc tolerance is defined as the maximum perpendicular distance from a line segment with its end points lying on the arc, aka a chord. With some basic geometry, we solve for the length of the line segments to trace the arc that satisfies this setting. Modeling arcs in this way is great, because the arc line segments automatically adjust and scale with length to ensure optimum arc tracing performance, while never losing accuracy.
+
+#### $13 - Report inches, boolean
+
+Grbl has a real-time positioning reporting feature to provide a user feedback on where the machine is exactly at that time, as well as, parameters for coordinate offsets and probing. By default, it is set to report in mm, but by sending a `$13=1` command, you send this boolean flag to true and these reporting features will now report in inches. `$13=0` to set back to mm.
+
+#### $20 - Soft limits, boolean
+
+Soft limits is a safety feature to help prevent your machine from traveling too far and beyond the limits of travel, crashing or breaking something expensive. It works by knowing the maximum travel limits for each axis and where Grbl is in machine coordinates. Whenever a new G-code motion is sent to Grbl, it checks whether or not you accidentally have exceeded your machine space. If you do, Grbl will issue an immediate feed hold wherever it is, shutdown the spindle and coolant, and then set the system alarm indicating the problem. Machine position will be retained afterwards, since it's not due to an immediate forced stop like hard limits.
+
+NOTE: Soft limits requires homing to be enabled and accurate axis maximum travel settings, because Grbl needs to know where it is. `$20=1` to enable, and `$20=0` to disable.
+
+#### $21 - Hard limits, boolean
+
+Hard limit work basically the same as soft limits, but use physical switches instead. Basically you wire up some switches (mechanical, magnetic, or optical) near the end of travel of each axes, or where ever you feel that there might be trouble if your program moves too far to where it shouldn't. When the switch triggers, it will immediately halt all motion, shutdown the coolant and spindle (if connected), and go into alarm mode, which forces you to check your machine and reset everything.
+
+To use hard limits with Grbl, the limit pins are held high with an internal pull-up resistor, so all you have to do is wire in a normally-open switch with the pin and ground and enable hard limits with `$21=1`. (Disable with `$21=0`.) We strongly advise taking electric interference prevention measures. If you want a limit for both ends of travel of one axes, just wire in two switches in parallel with the pin and ground, so if either one of them trips, it triggers the hard limit.
+
+Keep in mind, that a hard limit event is considered to be critical event, where steppers immediately stop and will have likely have lost steps. Grbl doesn't have any feedback on position, so it can't guarantee it has any idea where it is. So, if a hard limit is triggered, Grbl will go into an infinite loop ALARM mode, giving you a chance to check your machine and forcing you to reset Grbl. Remember it's a purely a safety feature.
+
+#### $22 - Homing cycle, boolean
+
+Ahh, homing. For those just initiated into CNC, the homing cycle is used to accurately and precisely locate a known and consistent position on a machine every time you start up your Grbl between sessions. In other words, you know exactly where you are at any given time, every time. Say you start machining something or are about to start the next step in a job and the power goes out, you re-start Grbl and Grbl has no idea where it is. You're left with the task of figuring out where you are. If you have homing, you always have the machine zero reference point to locate from, so all you have to do is run the homing cycle and resume where you left off.
+
+To set up the homing cycle for Grbl, you need to have limit switches in a fixed position that won't get bumped or moved, or else your reference point gets messed up. Usually they are setup in the farthest point in +x, +y, +z of each axes. Wire your limit switches in with the limit pins and ground, just like with the hard limits, and enable homing. If you're curious, you can use your limit switches for both hard limits AND homing. They play nice with each other.
+
+By default, Grbl's homing cycle moves the Z-axis positive first to clear the workspace and then moves both the X and Y-axes at the same time in the positive direction. To set up how your homing cycle behaves, there are more Grbl settings down the page describing what they do (and compile-time options as well.)
+
+Also, one more thing to note, when homing is enabled. Grbl will lock out all G-code commands until you perform a homing cycle. Meaning no axes motions, unless the lock is disabled ($X) but more on that later. Most, if not all CNC controllers, do something similar, as it is mostly a safety feature to prevent users from making a positioning mistake, which is very easy to do and be saddened when a mistake ruins a part. If you find this annoying or find any weird bugs, please let us know and we'll try to work on it so everyone is happy. :)
+
+NOTE: Check out config.h for more homing options for advanced users. You can disable the homing lockout at startup, configure which axes move first during a homing cycle and in what order, and more.
+
+
+#### $23 - Homing dir invert, mask
+
+By default, Grbl assumes your homing limit switches are in the positive direction, first moving the z-axis positive, then the x-y axes positive before trying to precisely locate machine zero by going back and forth slowly around the switch. If your machine has a limit switch in the negative direction, the homing direction mask can invert the axes' direction. It works just like the step port invert and direction port invert masks, where all you have to do is send the value in the table to indicate what axes you want to invert and search for in the opposite direction.
+
+#### $24 - Homing feed, mm/min
+
+The homing cycle first searches for the limit switches at a higher seek rate, and after it finds them, it moves at a slower feed rate to home into the precise location of machine zero. Homing feed rate is that slower feed rate. Set this to whatever rate value that provides repeatable and precise machine zero locating.
+
+#### $25 - Homing seek, mm/min
+
+Homing seek rate is the homing cycle search rate, or the rate at which it first tries to find the limit switches. Adjust to whatever rate gets to the limit switches in a short enough time without crashing into your limit switches if they come in too fast.
+
+#### $26 - Homing debounce, milliseconds
+
+Whenever a switch triggers, some of them can have electrical/mechanical noise that actually 'bounce' the signal high and low for a few milliseconds before settling in. To solve this, you need to debounce the signal, either by hardware with some kind of signal conditioner or by software with a short delay to let the signal finish bouncing. Grbl performs a short delay, only homing when locating machine zero. Set this delay value to whatever your switch needs to get repeatable homing. In most cases, 5-25 milliseconds is fine.
+
+#### $27 - Homing pull-off, mm
+
+To play nice with the hard limits feature, where homing can share the same limit switches, the homing cycle will move off all of the limit switches by this pull-off travel after it completes. In other words, it helps to prevent accidental triggering of the hard limit after a homing cycle.
+
+#### $30 - Max spindle speed, RPM
+
+This sets the spindle speed for the maximum 5V PWM pin output. Higher programmed spindle RPMs are accepted by Grbl but the PWM output will not exceed the max 5V. By default, Grbl linearly relates the max-min RPMs to 5V-0.02V PWM pin output in 255 increments. When the PWM pin reads 0V, this indicates spindle disabled. Note that there are additional configuration options are available in config.h to tweak how this operates.
+
+#### $31 - Min spindle speed, RPM
+
+This sets the spindle speed for the minimum 0.02V PWM pin output (0V is disabled).  Lower RPM values are accepted by Grbl but the PWM output will not go below 0.02V, except when RPM is zero. If zero, the spindle is disabled and PWM output is 0V. 
+
+#### $32 - Laser mode, boolean
+
+When enabled, Grbl will move continuously through consecutive `G1`, `G2`, or `G3` motion commands when programmed with a `S` spindle speed (laser power). The spindle PWM pin will be updated instantaneously through each motion without stopping. Please read the Grbl laser documentation and your laser device documentation prior to using this mode. Lasers are very dangerous. They can instantly damage your vision permanantly and cause fires. Grbl does not assume any responsibility for any issues the firmware may cause, as defined by its GPL license. 
+
+When disabled, Grbl will operate as it always has, stopping motion with every `S` spindle speed command. This is the default operation of a milling machine to allow a pause to let the spindle change speeds.
+
+#### $100, $101 and $102 – [X,Y,Z] steps/mm
+
+Grbl needs to know how far each step will take the tool in reality. To calculate steps/mm for an axis of your machine you need to know:
+
+* The mm traveled per revolution of your stepper motor. This is dependent on your belt drive gears or lead screw pitch.
+* The full steps per revolution of your steppers (typically 200)
+* The microsteps per step of your controller (typically 1, 2, 4, 8, or 16). _Tip: Using high microstep values (e.g., 16) can reduce your stepper motor torque, so use the lowest that gives you the desired axis resolution and comfortable running properties._
+
+The steps/mm can then be calculated like this: ```steps_per_mm = (steps_per_revolution*microsteps)/mm_per_rev```
+
+Compute this value for every axis and write these settings to Grbl.
+
+#### $110, $111 and $112 – [X,Y,Z] Max rate, mm/min
+
+This sets the maximum rate each axis can move. Whenever Grbl plans a move, it checks whether or not the move causes any one of these individual axes to exceed their max rate. If so, it'll slow down the motion to ensure none of the axes exceed their max rate limits. This means that each axis has its own independent speed, which is extremely useful for limiting the typically slower Z-axis.
+
+The simplest way to determine these values is to test each axis one at a time by slowly increasing max rate settings and moving it. For example, to test the X-axis, send Grbl something like `G0 X50` with enough travel distance so that the axis accelerates to its max speed. You'll know you've hit the max rate threshold when your steppers stall. It'll make a bit of noise, but shouldn't hurt your motors. Enter a setting a 10-20% below this value, so you can account for wear, friction, and the mass of your workpiece/tool. Then, repeat for your other axes.
+
+NOTE: This max rate setting also sets the G0 seek rates.
+
+#### $120, $121, $122 – [X,Y,Z] Acceleration, mm/sec^2
+
+This sets the axes acceleration parameters in mm/second/second. Simplistically, a lower value makes Grbl ease slower into motion, while a higher value yields tighter moves and reaches the desired feed rates much quicker. Much like the max rate setting, each axis has its own acceleration value and are independent of each other. This means that a multi-axis motion will only accelerate as quickly as the lowest contributing axis can.
+
+Again, like the max rate setting, the simplest way to determine the values for this setting is to individually test each axis with slowly increasing values until the motor stalls. Then finalize your acceleration setting with a value 10-20% below this absolute max value. This should account for wear, friction, and mass inertia. We highly recommend that you dry test some G-code programs with your new settings before committing to them. Sometimes the loading on your machine is different when moving in all axes together.
+
+
+#### $130, $131, $132 – [X,Y,Z] Max travel, mm
+
+This sets the maximum travel from end to end for each axis in mm. This is only useful if you have soft limits (and homing) enabled, as this is only used by Grbl's soft limit feature to check if you have exceeded your machine limits with a motion command.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/media/COPYING	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2 @@
+
+Copyright (c) 2015 Gnea Research LLC. All Rights Reserved.
Binary file doc/media/Grbl Logo 150px.png has changed
Binary file doc/media/Grbl Logo 250px.png has changed
Binary file doc/media/Grbl Logo 320px.png has changed
Binary file doc/media/Grbl Logo 640px.png has changed
Binary file doc/media/Grbl Logo.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/media/Grbl Logo.svg	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.094488189"
+   height="1052.36220472"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="Grbl Logo.svg">
+  <metadata
+     id="metadata97">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1000"
+     inkscape:window-height="751"
+     id="namedview95"
+     showgrid="false"
+     inkscape:zoom="0.89702957"
+     inkscape:cx="393.978"
+     inkscape:cy="560.38231"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g21" />
+  <desc
+     id="desc4">/Users/chamnit/Dropbox/documents/OHS/Logo/Grbl.DXF - scale = 58.043118, origin = (0.000000, 0.000000), auto = True</desc>
+  <defs
+     id="defs6">
+    <marker
+       id="DistanceX"
+       orient="auto"
+       refX="0.0"
+       refY="0.0"
+       style="overflow:visible">
+      <path
+         d="M 3,-3 L -3,3 M 0,-5 L  0,5"
+         style="stroke:#000000; stroke-width:0.5"
+         id="path9" />
+    </marker>
+    <pattern
+       height="8"
+       id="Hatch"
+       patternUnits="userSpaceOnUse"
+       width="8"
+       x="0"
+       y="0">
+      <path
+         d="M8 4 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path12" />
+      <path
+         d="M6 2 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path14" />
+      <path
+         d="M4 0 l-4,4"
+         linecap="square"
+         stroke="#000000"
+         stroke-width="0.25"
+         id="path16" />
+    </pattern>
+    <symbol
+       id="*Model_Space" />
+    <symbol
+       id="*Paper_Space" />
+    <symbol
+       id="*Paper_Space0" />
+  </defs>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="0"
+     id="g21">
+    <g
+       id="g3562"
+       transform="matrix(0.74854703,0,0,0.74854703,93.578346,130.5299)">
+      <path
+         sodipodi:nodetypes="ccscccccc"
+         inkscape:connector-curvature="0"
+         id="path45"
+         style="fill:#000000;stroke:#000000;stroke-linecap:round"
+         d="m 666.97027,519.20619 0,-204.22494 c 0,-14.19819 -11.5099,-25.70806 -25.70807,-25.70806 -14.19818,0 -25.70808,11.50987 -25.70808,25.70806 l 0,204.22494 c 0,56.79271 46.03958,102.83229 102.83229,102.8323 l 25.70808,-25.70808 -25.70808,-25.70807 c -28.39635,0 -51.41614,-23.0198 -51.41614,-51.41615 z" />
+      <path
+         sodipodi:nodetypes="ccsccccccc"
+         inkscape:connector-curvature="0"
+         id="path61"
+         style="fill:#000000;stroke:#000000;stroke-linecap:round"
+         d="m 230.65284,519.20619 0,77.12422 c 0,14.19819 11.5099,25.70806 25.70807,25.70806 14.19818,0 25.70808,-11.50987 25.70808,-25.70806 l 0,-77.12422 c 0,-28.39635 23.01979,-51.41615 51.41614,-51.41615 l 38.92203,0 0,-51.41614 -38.92203,0 c -56.7927,1e-5 -102.83228,46.03959 -102.83229,102.83229" />
+      <path
+         sodipodi:nodetypes="ccccssscccccsssc"
+         inkscape:connector-curvature="0"
+         id="path73"
+         style="fill:#000000;stroke:#000000;stroke-linecap:round"
+         d="m 487.73358,416.3739 -38.92203,0 0,51.41614 38.92203,0 c 20.79587,0 39.54419,12.52721 47.50197,31.73975 7.95777,19.21249 3.55772,41.32642 -11.14711,56.03126 -14.70484,14.70483 -36.81877,19.10488 -56.03126,11.14711 -19.21254,-7.95778 -31.73975,-26.7061 -31.73975,-47.50197 l 0,-204.22494 -25.70808,-25.70807 -25.70807,25.70807 0,204.22494 c 0,41.59174 25.05442,79.08838 63.47948,95.00395 38.42499,15.91554 82.65286,7.11546 112.06254,-22.29421 29.40967,-29.40968 38.20976,-73.63755 22.29423,-112.06254 -15.91557,-38.42506 -53.41221,-63.47949 -95.00395,-63.47949" />
+      <path
+         sodipodi:nodetypes="cssscccscccsssccccc"
+         inkscape:connector-curvature="0"
+         id="path81"
+         style="fill:#000000;stroke:#000000;stroke-linecap:round"
+         d="m 102.8323,570.62234 c -20.795869,0 -39.544189,-12.52721 -47.501976,-31.73974 -7.95777,-19.21249 -3.557731,-41.32643 11.147104,-56.03126 14.704835,-14.70484 36.818772,-19.10489 56.031262,-11.14712 19.21254,7.95778 31.73975,26.7061 31.73975,47.50197 l 0,127.10072 c 0,28.39635 -23.01979,51.41615 -51.41614,51.41615 -14.192584,0.008 -25.693722,11.51549 -25.693722,25.70807 0,14.19258 11.501138,25.70007 25.693722,25.70807 56.7927,-10e-6 102.83228,-46.03959 102.83229,-102.83229 l 0,-127.10072 c 0,-41.59174 -25.05443,-79.08838 -63.47949,-95.00395 C 103.76011,408.28671 59.532236,417.0868 30.122564,446.49647 0.712891,475.90615 -8.0871904,520.13402 7.8283485,558.55901 23.74392,596.98407 61.240561,622.03849 102.8323,622.03849 l 25.70807,0 25.70807,-25.70808 -25.70807,-25.70807 -25.70807,0" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path91"
+         style="fill:none;stroke:#000000;stroke-linecap:round"
+         d="m 744.09449,596.33041 -25.70808,25.70808" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/script/simple_stream.py	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+"""\
+Simple g-code streaming script for grbl
+
+Provided as an illustration of the basic communication interface
+for grbl. When grbl has finished parsing the g-code block, it will
+return an 'ok' or 'error' response. When the planner buffer is full,
+grbl will not send a response until the planner buffer clears space.
+
+G02/03 arcs are special exceptions, where they inject short line 
+segments directly into the planner. So there may not be a response 
+from grbl for the duration of the arc.
+
+---------------------
+The MIT License (MIT)
+
+Copyright (c) 2012 Sungeun K. Jeon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+---------------------
+"""
+
+import serial
+import time
+
+# Open grbl serial port
+s = serial.Serial('/dev/tty.usbmodem1811',115200)
+
+# Open g-code file
+f = open('grbl.gcode','r');
+
+# Wake up grbl
+s.write("\r\n\r\n")
+time.sleep(2)   # Wait for grbl to initialize 
+s.flushInput()  # Flush startup text in serial input
+
+# Stream g-code to grbl
+for line in f:
+    l = line.strip() # Strip all EOL characters for consistency
+    print 'Sending: ' + l,
+    s.write(l + '\n') # Send g-code block to grbl
+    grbl_out = s.readline() # Wait for grbl response with carriage return
+    print ' : ' + grbl_out.strip()
+
+# Wait here until grbl is finished to close serial port and file.
+raw_input("  Press <Enter> to exit and disable grbl.") 
+
+# Close file and serial port
+f.close()
+s.close()    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/script/stream.py	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+"""\
+
+Stream g-code to grbl controller
+
+This script differs from the simple_stream.py script by 
+tracking the number of characters in grbl's serial read
+buffer. This allows grbl to fetch the next line directly
+from the serial buffer and does not have to wait for a 
+response from the computer. This effectively adds another
+buffer layer to prevent buffer starvation.
+
+CHANGELOG:
+- 20161212: Added push message feedback for simple streaming
+- 20140714: Updated baud rate to 115200. Added a settings
+  write mode via simple streaming method. MIT-licensed.
+
+TODO: 
+- Add runtime command capabilities
+
+---------------------
+The MIT License (MIT)
+
+Copyright (c) 2012-2016 Sungeun K. Jeon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+---------------------
+"""
+
+import serial
+import re
+import time
+import sys
+import argparse
+# import threading
+
+RX_BUFFER_SIZE = 128
+
+# Define command line argument interface
+parser = argparse.ArgumentParser(description='Stream g-code file to grbl. (pySerial and argparse libraries required)')
+parser.add_argument('gcode_file', type=argparse.FileType('r'),
+        help='g-code filename to be streamed')
+parser.add_argument('device_file',
+        help='serial device path')
+parser.add_argument('-q','--quiet',action='store_true', default=False, 
+        help='suppress output text')
+parser.add_argument('-s','--settings',action='store_true', default=False, 
+        help='settings write mode')        
+args = parser.parse_args()
+
+# Periodic timer to query for status reports
+# TODO: Need to track down why this doesn't restart consistently before a release.
+# def periodic():
+#     s.write('?')
+#     t = threading.Timer(0.1, periodic) # In seconds
+#     t.start()
+
+# Initialize
+s = serial.Serial(args.device_file,115200)
+f = args.gcode_file
+verbose = True
+if args.quiet : verbose = False
+settings_mode = False
+if args.settings : settings_mode = True
+
+# Wake up grbl
+print "Initializing grbl..."
+s.write("\r\n\r\n")
+
+# Wait for grbl to initialize and flush startup text in serial input
+time.sleep(2)
+s.flushInput()
+
+# Stream g-code to grbl
+l_count = 0
+if settings_mode:
+    # Send settings file via simple call-response streaming method. Settings must be streamed
+    # in this manner since the EEPROM accessing cycles shut-off the serial interrupt.
+    print "SETTINGS MODE: Streaming", args.gcode_file.name, " to ", args.device_file
+    for line in f:
+        l_count += 1 # Iterate line counter    
+        # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize
+        l_block = line.strip() # Strip all EOL characters for consistency
+        if verbose: print 'SND: ' + str(l_count) + ':' + l_block,
+        s.write(l_block + '\n') # Send g-code block to grbl
+        while 1:
+            grbl_out = s.readline().strip() # Wait for grbl response with carriage return
+            if grbl_out.find('ok') < 0 and grbl_out.find('error') < 0 :
+                print "\n  Debug: ",grbl_out,
+            else : 
+                if verbose: print 'REC:',grbl_out
+                break
+else:    
+    # Send g-code program via a more agressive streaming protocol that forces characters into
+    # Grbl's serial read buffer to ensure Grbl has immediate access to the next g-code command
+    # rather than wait for the call-response serial protocol to finish. This is done by careful
+    # counting of the number of characters sent by the streamer to Grbl and tracking Grbl's 
+    # responses, such that we never overflow Grbl's serial read buffer. 
+    g_count = 0
+    c_line = []
+    # periodic() # Start status report periodic timer
+    for line in f:
+        l_count += 1 # Iterate line counter
+        # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize
+        l_block = line.strip()
+        c_line.append(len(l_block)+1) # Track number of characters in grbl serial read buffer
+        grbl_out = '' 
+        while sum(c_line) >= RX_BUFFER_SIZE-1 | s.inWaiting() :
+            out_temp = s.readline().strip() # Wait for grbl response
+            if out_temp.find('ok') < 0 and out_temp.find('error') < 0 :
+                print "  Debug: ",out_temp # Debug response
+            else :
+                grbl_out += out_temp;
+                g_count += 1 # Iterate g-code counter
+                grbl_out += str(g_count); # Add line finished indicator
+                del c_line[0] # Delete the block character count corresponding to the last 'ok'
+        if verbose: print "SND: " + str(l_count) + " : " + l_block,
+        s.write(l_block + '\n') # Send g-code block to grbl
+        if verbose : print "BUF:",str(sum(c_line)),"REC:",grbl_out
+
+# Wait for user input after streaming is completed
+print "G-code streaming finished!\n"
+print "WARNING: Wait until grbl completes buffered g-code blocks before exiting."
+raw_input("  Press <Enter> to exit and disable grbl.") 
+
+# Close file and serial port
+f.close()
+s.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/config.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,614 @@
+/*
+  config.h - compile time configuration
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// This file contains compile-time configurations for Grbl's internal system. For the most part,
+// users will not need to directly modify these, but they are here for specific needs, i.e.
+// performance tuning or adjusting to non-typical machines.
+
+// IMPORTANT: Any changes here requires a full re-compiling of the source code to propagate them.
+
+#ifndef config_h
+#define config_h
+#include "grbl.h" // For Arduino IDE compatibility.
+
+
+// Define CPU pin map and default settings.
+// NOTE: OEMs can avoid the need to maintain/update the defaults.h and cpu_map.h files and use only
+// one configuration file by placing their specific defaults and pin map at the bottom of this file.
+// If doing so, simply comment out these two defines and see instructions below.
+//#define DEFAULTS_GENERIC
+#define DEFAULT_CNC3020
+#ifdef WIN32
+#define CPU_MAP_WIN32
+#endif
+#ifdef AVRTARGET
+#define CPU_MAP_ATMEGA328P // Arduino Uno CPU
+#endif
+#ifdef STM32F103C8
+#define CPU_MAP_STM32F103
+#endif
+
+// Serial baud rate
+// #define BAUD_RATE 230400
+#define BAUD_RATE 115200
+
+// Define realtime command special characters. These characters are 'picked-off' directly from the
+// serial read data stream and are not passed to the grbl line execution parser. Select characters
+// that do not and must not exist in the streamed g-code program. ASCII control characters may be
+// used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in
+// g-code programs, maybe selected for interface programs.
+// NOTE: If changed, manually update help message in report.c.
+
+#define CMD_RESET 0x18 // ctrl-x.
+#define CMD_STATUS_REPORT '?'
+#define CMD_CYCLE_START '~'
+#define CMD_FEED_HOLD '!'
+
+// NOTE: All override realtime commands must be in the extended ASCII character set, starting
+// at character value 128 (0x80) and up to 255 (0xFF). If the normal set of realtime commands,
+// such as status reports, feed hold, reset, and cycle start, are moved to the extended set
+// space, serial.c's RX ISR will need to be modified to accomodate the change.
+// #define CMD_RESET 0x80
+// #define CMD_STATUS_REPORT 0x81
+// #define CMD_CYCLE_START 0x82
+// #define CMD_FEED_HOLD 0x83
+#define CMD_SAFETY_DOOR 0x84
+#define CMD_JOG_CANCEL  0x85
+#define CMD_DEBUG_REPORT 0x86 // Only when DEBUG enabled, sends debug report in '{}' braces.
+#define CMD_FEED_OVR_RESET 0x90         // Restores feed override value to 100%.
+#define CMD_FEED_OVR_COARSE_PLUS 0x91
+#define CMD_FEED_OVR_COARSE_MINUS 0x92
+#define CMD_FEED_OVR_FINE_PLUS  0x93
+#define CMD_FEED_OVR_FINE_MINUS  0x94
+#define CMD_RAPID_OVR_RESET 0x95        // Restores rapid override value to 100%.
+#define CMD_RAPID_OVR_MEDIUM 0x96
+#define CMD_RAPID_OVR_LOW 0x97
+// #define CMD_RAPID_OVR_EXTRA_LOW 0x98 // *NOT SUPPORTED*
+#define CMD_SPINDLE_OVR_RESET 0x99      // Restores spindle override value to 100%.
+#define CMD_SPINDLE_OVR_COARSE_PLUS 0x9A
+#define CMD_SPINDLE_OVR_COARSE_MINUS 0x9B
+#define CMD_SPINDLE_OVR_FINE_PLUS 0x9C
+#define CMD_SPINDLE_OVR_FINE_MINUS 0x9D
+#define CMD_SPINDLE_OVR_STOP 0x9E
+#define CMD_COOLANT_FLOOD_OVR_TOGGLE 0xA0
+#define CMD_COOLANT_MIST_OVR_TOGGLE 0xA1
+
+// If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces
+// the user to perform the homing cycle (or override the locks) before doing anything else. This is
+// mainly a safety feature to remind the user to home, since position is unknown to Grbl.
+#define HOMING_INIT_LOCK // Comment to disable
+
+// Define the homing cycle patterns with bitmasks. The homing cycle first performs a search mode
+// to quickly engage the limit switches, followed by a slower locate mode, and finished by a short
+// pull-off motion to disengage the limit switches. The following HOMING_CYCLE_x defines are executed
+// in order starting with suffix 0 and completes the homing routine for the specified-axes only. If
+// an axis is omitted from the defines, it will not home, nor will the system update its position.
+// Meaning that this allows for users with non-standard cartesian machines, such as a lathe (x then z,
+// with no y), to configure the homing cycle behavior to their needs.
+// NOTE: The homing cycle is designed to allow sharing of limit pins, if the axes are not in the same
+// cycle, but this requires some pin settings changes in cpu_map.h file. For example, the default homing
+// cycle can share the Z limit pin with either X or Y limit pins, since they are on different cycles.
+// By sharing a pin, this frees up a precious IO pin for other purposes. In theory, all axes limit pins
+// may be reduced to one pin, if all axes are homed with seperate cycles, or vice versa, all three axes
+// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits
+// will not be affected by pin sharing.
+// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y.
+#define HOMING_CYCLE_0 (1<<Z_AXIS)                // REQUIRED: First move Z to clear workspace.
+#define HOMING_CYCLE_1 ((1<<X_AXIS)|(1<<Y_AXIS))  // OPTIONAL: Then move X,Y at the same time.
+// #define HOMING_CYCLE_2                         // OPTIONAL: Uncomment and add axes mask to enable
+
+// NOTE: The following are two examples to setup homing for 2-axis machines.
+// #define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS))  // NOT COMPATIBLE WITH COREXY: Homes both X-Y in one cycle. 
+
+// #define HOMING_CYCLE_0 (1<<X_AXIS)  // COREXY COMPATIBLE: First home X
+// #define HOMING_CYCLE_1 (1<<Y_AXIS)  // COREXY COMPATIBLE: Then home Y
+
+// Number of homing cycles performed after when the machine initially jogs to limit switches.
+// This help in preventing overshoot and should improve repeatability. This value should be one or
+// greater.
+#define N_HOMING_LOCATE_CYCLE 1 // Integer (1-128)
+
+// Enables single axis homing commands. $HX, $HY, and $HZ for X, Y, and Z-axis homing. The full homing 
+// cycle is still invoked by the $H command. This is disabled by default. It's here only to address
+// users that need to switch between a two-axis and three-axis machine. This is actually very rare.
+// If you have a two-axis machine, DON'T USE THIS. Instead, just alter the homing cycle for two-axes.
+// #define HOMING_SINGLE_AXIS_COMMANDS // Default disabled. Uncomment to enable.
+
+// After homing, Grbl will set by default the entire machine space into negative space, as is typical
+// for professional CNC machines, regardless of where the limit switches are located. Uncomment this
+// define to force Grbl to always set the machine origin at the homed location despite switch orientation.
+// #define HOMING_FORCE_SET_ORIGIN // Uncomment to enable.
+
+// Number of blocks Grbl executes upon startup. These blocks are stored in EEPROM, where the size
+// and addresses are defined in settings.h. With the current settings, up to 2 startup blocks may
+// be stored and executed in order. These startup blocks would typically be used to set the g-code
+// parser state depending on user preferences.
+#define N_STARTUP_LINE 2 // Integer (1-2)
+
+// Number of floating decimal points printed by Grbl for certain value types. These settings are
+// determined by realistic and commonly observed values in CNC machines. For example, position
+// values cannot be less than 0.001mm or 0.0001in, because machines can not be physically more
+// precise this. So, there is likely no need to change these, but you can if you need to here.
+// NOTE: Must be an integer value from 0 to ~4. More than 4 may exhibit round-off errors.
+#define N_DECIMAL_COORDVALUE_INCH 4 // Coordinate or position value in inches
+#define N_DECIMAL_COORDVALUE_MM   3 // Coordinate or position value in mm
+#define N_DECIMAL_RATEVALUE_INCH  1 // Rate or velocity value in in/min
+#define N_DECIMAL_RATEVALUE_MM    0 // Rate or velocity value in mm/min
+#define N_DECIMAL_SETTINGVALUE    3 // Decimals for floating point setting values
+#define N_DECIMAL_RPMVALUE        0 // RPM value in rotations per min.
+
+// If your machine has two limits switches wired in parallel to one axis, you will need to enable
+// this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell
+// which one is enabled. This option only effects homing, where if a limit is engaged, Grbl will
+// alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one
+// limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a
+// homing cycle while on the limit switch and not have to move the machine off of it.
+// #define LIMITS_TWO_SWITCHES_ON_AXES
+
+// Allows GRBL to track and report gcode line numbers.  Enabling this means that the planning buffer
+// goes from 16 to 15 to make room for the additional line number data in the plan_block_t struct
+// #define USE_LINE_NUMBERS // Disabled by default. Uncomment to enable.
+
+// Upon a successful probe cycle, this option provides immediately feedback of the probe coordinates
+// through an automatically generated message. If disabled, users can still access the last probe
+// coordinates through Grbl '$#' print parameters.
+#define MESSAGE_PROBE_COORDINATES // Enabled by default. Comment to disable.
+
+// Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno
+// analog pin 4. Only use this option if you require a second coolant control pin.
+// NOTE: The M8 flood coolant control pin on analog pin 3 will still be functional regardless.
+// #define ENABLE_M7 // Disabled by default. Uncomment to enable.
+
+// This option causes the feed hold input to act as a safety door switch. A safety door, when triggered,
+// immediately forces a feed hold and then safely de-energizes the machine. Resuming is blocked until
+// the safety door is re-engaged. When it is, Grbl will re-energize the machine and then resume on the
+// previous tool path, as if nothing happened.
+// #define ENABLE_SAFETY_DOOR_INPUT_PIN // Default disabled. Uncomment to enable.
+
+// After the safety door switch has been toggled and restored, this setting sets the power-up delay
+// between restoring the spindle and coolant and resuming the cycle.
+#define SAFETY_DOOR_SPINDLE_DELAY 4.0 // Float (seconds)
+#define SAFETY_DOOR_COOLANT_DELAY 1.0 // Float (seconds)
+
+// Enable CoreXY kinematics. Use ONLY with CoreXY machines.
+// IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to
+// #define HOMING_CYCLE_0 (1<<X_AXIS) and #define HOMING_CYCLE_1 (1<<Y_AXIS)
+// NOTE: This configuration option alters the motion of the X and Y axes to principle of operation
+// defined at (http://corexy.com/theory.html). Motors are assumed to positioned and wired exactly as
+// described, if not, motions may move in strange directions. Grbl requires the CoreXY A and B motors
+// have the same steps per mm internally.
+// #define COREXY // Default disabled. Uncomment to enable.
+
+// Inverts pin logic of the control command pins based on a mask. This essentially means you can use
+// normally-closed switches on the specified pins, rather than the default normally-open switches.
+// NOTE: The top option will mask and invert all control pins. The bottom option is an example of
+// inverting only two control pins, the safety door and reset. See cpu_map.h for other bit definitions.
+// #define INVERT_CONTROL_PIN_MASK CONTROL_MASK // Default disabled. Uncomment to disable.
+// #define INVERT_CONTROL_PIN_MASK ((1<<CONTROL_SAFETY_DOOR_BIT)|(CONTROL_RESET_BIT)) // Default disabled.
+
+// Inverts select limit pin states based on the following mask. This effects all limit pin functions,
+// such as hard limits and homing. However, this is different from overall invert limits setting.
+// This build option will invert only the limit pins defined here, and then the invert limits setting
+// will be applied to all of them. This is useful when a user has a mixed set of limit pins with both
+// normally-open(NO) and normally-closed(NC) switches installed on their machine.
+// NOTE: PLEASE DO NOT USE THIS, unless you have a situation that needs it.
+// #define INVERT_LIMIT_PIN_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)) // Default disabled. Uncomment to enable.
+
+// Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful
+// for some pre-built electronic boards.
+// NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and
+// spindle enable are combined to one pin. If you need both this option and spindle speed PWM,
+// uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below.
+// #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
+
+// Inverts the selected coolant pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful
+// for some pre-built electronic boards.
+// #define INVERT_COOLANT_FLOOD_PIN // Default disabled. Uncomment to enable.
+// #define INVERT_COOLANT_MIST_PIN // Default disabled. Note: Enable M7 mist coolant in config.h
+
+// When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM
+// by default. This is to make it as simple as possible for new users to start using Grbl. When homing
+// is enabled and a user has installed limit switches, Grbl will boot up in an ALARM state to indicate
+// Grbl doesn't know its position and to force the user to home before proceeding. This option forces
+// Grbl to always initialize into an ALARM state regardless of homing or not. This option is more for
+// OEMs and LinuxCNC users that would like this power-cycle behavior.
+// #define FORCE_INITIALIZATION_ALARM // Default disabled. Uncomment to enable.
+
+// At power-up or a reset, Grbl will check the limit switch states to ensure they are not active
+// before initialization. If it detects a problem and the hard limits setting is enabled, Grbl will
+// simply message the user to check the limits and enter an alarm state, rather than idle. Grbl will
+// not throw an alarm message.
+#define CHECK_LIMITS_AT_INIT
+
+// ---------------------------------------------------------------------------------------
+// ADVANCED CONFIGURATION OPTIONS:
+
+// Enables code for debugging purposes. Not for general use and always in constant flux.
+// #define DEBUG // Uncomment to enable. Default disabled.
+
+// Configure rapid, feed, and spindle override settings. These values define the max and min
+// allowable override values and the coarse and fine increments per command received. Please
+// note the allowable values in the descriptions following each define.
+#define DEFAULT_FEED_OVERRIDE           100 // 100%. Don't change this value.
+#define MAX_FEED_RATE_OVERRIDE          200 // Percent of programmed feed rate (100-255). Usually 120% or 200%
+#define MIN_FEED_RATE_OVERRIDE           10 // Percent of programmed feed rate (1-100). Usually 50% or 1%
+#define FEED_OVERRIDE_COARSE_INCREMENT   10 // (1-99). Usually 10%.
+#define FEED_OVERRIDE_FINE_INCREMENT      1 // (1-99). Usually 1%.
+
+#define DEFAULT_RAPID_OVERRIDE  100 // 100%. Don't change this value.
+#define RAPID_OVERRIDE_MEDIUM    50 // Percent of rapid (1-99). Usually 50%.
+#define RAPID_OVERRIDE_LOW       25 // Percent of rapid (1-99). Usually 25%.
+// #define RAPID_OVERRIDE_EXTRA_LOW 5 // *NOT SUPPORTED* Percent of rapid (1-99). Usually 5%.
+
+#define DEFAULT_SPINDLE_SPEED_OVERRIDE    100 // 100%. Don't change this value.
+#define MAX_SPINDLE_SPEED_OVERRIDE        200 // Percent of programmed spindle speed (100-255). Usually 200%.
+#define MIN_SPINDLE_SPEED_OVERRIDE         10 // Percent of programmed spindle speed (1-100). Usually 10%.
+#define SPINDLE_OVERRIDE_COARSE_INCREMENT  10 // (1-99). Usually 10%.
+#define SPINDLE_OVERRIDE_FINE_INCREMENT     1 // (1-99). Usually 1%.
+
+// When a M2 or M30 program end command is executed, most g-code states are restored to their defaults.
+// This compile-time option includes the restoring of the feed, rapid, and spindle speed override values
+// to their default values at program end.
+#define RESTORE_OVERRIDES_AFTER_PROGRAM_END // Default enabled. Comment to disable.
+
+// The status report change for Grbl v1.1 and after also removed the ability to disable/enable most data
+// fields from the report. This caused issues for GUI developers, who've had to manage several scenarios
+// and configurations. The increased efficiency of the new reporting style allows for all data fields to 
+// be sent without potential performance issues.
+// NOTE: The options below are here only provide a way to disable certain data fields if a unique
+// situation demands it, but be aware GUIs may depend on this data. If disabled, it may not be compatible.
+#define REPORT_FIELD_BUFFER_STATE // Default enabled. Comment to disable.
+#define REPORT_FIELD_PIN_STATE // Default enabled. Comment to disable.
+#define REPORT_FIELD_CURRENT_FEED_SPEED // Default enabled. Comment to disable.
+#define REPORT_FIELD_WORK_COORD_OFFSET // Default enabled. Comment to disable.
+#define REPORT_FIELD_OVERRIDES // Default enabled. Comment to disable.
+#define REPORT_FIELD_LINE_NUMBERS // Default enabled. Comment to disable.
+
+// Some status report data isn't necessary for realtime, only intermittently, because the values don't
+// change often. The following macros configures how many times a status report needs to be called before
+// the associated data is refreshed and included in the status report. However, if one of these value
+// changes, Grbl will automatically include this data in the next status report, regardless of what the
+// count is at the time. This helps reduce the communication overhead involved with high frequency reporting
+// and agressive streaming. There is also a busy and an idle refresh count, which sets up Grbl to send
+// refreshes more often when its not doing anything important. With a good GUI, this data doesn't need
+// to be refreshed very often, on the order of a several seconds.
+// NOTE: WCO refresh must be 2 or greater. OVR refresh must be 1 or greater.
+#define REPORT_OVR_REFRESH_BUSY_COUNT 20  // (1-255)
+#define REPORT_OVR_REFRESH_IDLE_COUNT 10  // (1-255) Must be less than or equal to the busy count
+#define REPORT_WCO_REFRESH_BUSY_COUNT 30  // (2-255)
+#define REPORT_WCO_REFRESH_IDLE_COUNT 10  // (2-255) Must be less than or equal to the busy count
+
+// The temporal resolution of the acceleration management subsystem. A higher number gives smoother
+// acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively
+// impact performance. The correct value for this parameter is machine dependent, so it's advised to
+// set this only as high as needed. Approximate successful values can widely range from 50 to 200 or more.
+// NOTE: Changing this value also changes the execution time of a segment in the step segment buffer.
+// When increasing this value, this stores less overall time in the segment buffer and vice versa. Make
+// certain the step segment buffer is increased/decreased to account for these changes.
+#define ACCELERATION_TICKS_PER_SECOND 100
+
+// Adaptive Multi-Axis Step Smoothing (AMASS) is an advanced feature that does what its name implies,
+// smoothing the stepping of multi-axis motions. This feature smooths motion particularly at low step
+// frequencies below 10kHz, where the aliasing between axes of multi-axis motions can cause audible
+// noise and shake your machine. At even lower step frequencies, AMASS adapts and provides even better
+// step smoothing. See stepper.c for more details on the AMASS system works.
+#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING  // Default enabled. Comment to disable.
+
+// Sets the maximum step rate allowed to be written as a Grbl setting. This option enables an error
+// check in the settings module to prevent settings values that will exceed this limitation. The maximum
+// step rate is strictly limited by the CPU speed and will change if something other than an AVR running
+// at 16MHz is used.
+// NOTE: For now disabled, will enable if flash space permits.
+// #define MAX_STEP_RATE_HZ 30000 // Hz
+
+// By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors
+// enabled. This simplifies the wiring for users by requiring only a switch connected to ground,
+// although its recommended that users take the extra step of wiring in low-pass filter to reduce
+// electrical noise detected by the pin. If the user inverts the pin in Grbl settings, this just flips
+// which high or low reading indicates an active signal. In normal operation, this means the user
+// needs to connect a normal-open switch, but if inverted, this means the user should connect a
+// normal-closed switch.
+// The following options disable the internal pull-up resistors, sets the pins to a normal-low
+// operation, and switches must be now connect to Vcc instead of ground. This also flips the meaning
+// of the invert pin Grbl setting, where an inverted setting now means the user should connect a
+// normal-open switch and vice versa.
+// NOTE: All pins associated with the feature are disabled, i.e. XYZ limit pins, not individual axes.
+// WARNING: When the pull-ups are disabled, this requires additional wiring with pull-down resistors!
+//#define DISABLE_LIMIT_PIN_PULL_UP
+//#define DISABLE_PROBE_PIN_PULL_UP
+//#define DISABLE_CONTROL_PIN_PULL_UP
+
+// Sets which axis the tool length offset is applied. Assumes the spindle is always parallel with
+// the selected axis with the tool oriented toward the negative direction. In other words, a positive
+// tool length offset value is subtracted from the current location.
+#define TOOL_LENGTH_OFFSET_AXIS Z_AXIS // Default z-axis. Valid values are X_AXIS, Y_AXIS, or Z_AXIS.
+
+// Enables variable spindle output voltage for different RPM values. On the Arduino Uno, the spindle
+// enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled.
+// NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch!
+// The hardware PWM output on pin D11 is required for variable spindle output voltages.
+#define VARIABLE_SPINDLE // Default enabled. Comment to disable.
+
+// Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled.
+// The PWM pin will still read 0V when the spindle is disabled. Most users will not need this option, but
+// it may be useful in certain scenarios. This minimum PWM settings coincides with the spindle rpm minimum
+// setting, like rpm max to max PWM. This is handy if you need a larger voltage difference between 0V disabled
+// and the voltage set by the minimum PWM for minimum rpm. This difference is 0.02V per PWM value. So, when
+// minimum PWM is at 1, only 0.02 volts separate enabled and disabled. At PWM 5, this would be 0.1V. Keep
+// in mind that you will begin to lose PWM resolution with increased minimum PWM values, since you have less
+// and less range over the total 255 PWM levels to signal different spindle speeds.
+// NOTE: Compute duty cycle at the minimum PWM by this equation: (% duty cycle)=(SPINDLE_PWM_MIN_VALUE/255)*100
+// #define SPINDLE_PWM_MIN_VALUE 5 // Default disabled. Uncomment to enable. Must be greater than zero. Integer (1-255).
+
+// By default on a 328p(Uno), Grbl combines the variable spindle PWM and the enable into one pin to help
+// preserve I/O pins. For certain setups, these may need to be separate pins. This configure option uses
+// the spindle direction pin(D13) as a separate spindle enable pin along with spindle speed PWM on pin D11.
+// NOTE: This configure option only works with VARIABLE_SPINDLE enabled and a 328p processor (Uno).
+// NOTE: Without a direction pin, M4 will not have a pin output to indicate a difference with M3. 
+// NOTE: BEWARE! The Arduino bootloader toggles the D13 pin when it powers up. If you flash Grbl with
+// a programmer (you can use a spare Arduino as "Arduino as ISP". Search the web on how to wire this.),
+// this D13 LED toggling should go away. We haven't tested this though. Please report how it goes!
+// #define USE_SPINDLE_DIR_AS_ENABLE_PIN // Default disabled. Uncomment to enable.
+
+// Alters the behavior of the spindle enable pin with the USE_SPINDLE_DIR_AS_ENABLE_PIN option . By default,
+// Grbl will not disable the enable pin if spindle speed is zero and M3/4 is active, but still sets the PWM 
+// output to zero. This allows the users to know if the spindle is active and use it as an additional control
+// input. However, in some use cases, user may want the enable pin to disable with a zero spindle speed and 
+// re-enable when spindle speed is greater than zero. This option does that.
+// NOTE: Requires USE_SPINDLE_DIR_AS_ENABLE_PIN to be enabled.
+// #define SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED // Default disabled. Uncomment to enable.
+
+// With this enabled, Grbl sends back an echo of the line it has received, which has been pre-parsed (spaces
+// removed, capitalized letters, no comments) and is to be immediately executed by Grbl. Echoes will not be
+// sent upon a line buffer overflow, but should for all normal lines sent to Grbl. For example, if a user
+// sendss the line 'g1 x1.032 y2.45 (test comment)', Grbl will echo back in the form '[echo: G1X1.032Y2.45]'.
+// NOTE: Only use this for debugging purposes!! When echoing, this takes up valuable resources and can effect
+// performance. If absolutely needed for normal operation, the serial write buffer should be greatly increased
+// to help minimize transmission waiting within the serial write protocol.
+// #define REPORT_ECHO_LINE_RECEIVED // Default disabled. Uncomment to enable.
+
+// Minimum planner junction speed. Sets the default minimum junction speed the planner plans to at
+// every buffer block junction, except for starting from rest and end of the buffer, which are always
+// zero. This value controls how fast the machine moves through junctions with no regard for acceleration
+// limits or angle between neighboring block line move directions. This is useful for machines that can't
+// tolerate the tool dwelling for a split second, i.e. 3d printers or laser cutters. If used, this value
+// should not be much greater than zero or to the minimum value necessary for the machine to work.
+#define MINIMUM_JUNCTION_SPEED 0.0f // (mm/min)
+
+// Sets the minimum feed rate the planner will allow. Any value below it will be set to this minimum
+// value. This also ensures that a planned motion always completes and accounts for any floating-point
+// round-off errors. Although not recommended, a lower value than 1.0 mm/min will likely work in smaller
+// machines, perhaps to 0.1mm/min, but your success may vary based on multiple factors.
+#define MINIMUM_FEED_RATE 1.0 // (mm/min)
+
+// Number of arc generation iterations by small angle approximation before exact arc trajectory
+// correction with expensive sin() and cos() calcualtions. This parameter maybe decreased if there
+// are issues with the accuracy of the arc generations, or increased if arc execution is getting
+// bogged down by too many trig calculations.
+#define N_ARC_CORRECTION 12 // Integer (1-255)
+
+// The arc G2/3 g-code standard is problematic by definition. Radius-based arcs have horrible numerical
+// errors when arc at semi-circles(pi) or full-circles(2*pi). Offset-based arcs are much more accurate
+// but still have a problem when arcs are full-circles (2*pi). This define accounts for the floating
+// point issues when offset-based arcs are commanded as full circles, but get interpreted as extremely
+// small arcs with around machine epsilon (1.2e-7rad) due to numerical round-off and precision issues.
+// This define value sets the machine epsilon cutoff to determine if the arc is a full-circle or not.
+// NOTE: Be very careful when adjusting this value. It should always be greater than 1.2e-7 but not too
+// much greater than this. The default setting should capture most, if not all, full arc error situations.
+#define ARC_ANGULAR_TRAVEL_EPSILON 5E-7 // Float (radians)
+
+// Time delay increments performed during a dwell. The default value is set at 50ms, which provides
+// a maximum time delay of roughly 55 minutes, more than enough for most any application. Increasing
+// this delay will increase the maximum dwell time linearly, but also reduces the responsiveness of
+// run-time command executions, like status reports, since these are performed between each dwell
+// time step. Also, keep in mind that the Arduino delay timer is not very accurate for long delays.
+#define DWELL_TIME_STEP 50 // Integer (1-255) (milliseconds)
+
+// Creates a delay between the direction pin setting and corresponding step pulse by creating
+// another interrupt (Timer2 compare) to manage it. The main Grbl interrupt (Timer1 compare)
+// sets the direction pins, and does not immediately set the stepper pins, as it would in
+// normal operation. The Timer2 compare fires next to set the stepper pins after the step
+// pulse delay time, and Timer2 overflow will complete the step pulse, except now delayed
+// by the step pulse time plus the step pulse delay. (Thanks langwadt for the idea!)
+// NOTE: Uncomment to enable. The recommended delay must be > 3us, and, when added with the
+// user-supplied step pulse time, the total time must not exceed 127us. Reported successful
+// values for certain setups have ranged from 5 to 20us.
+// #define STEP_PULSE_DELAY 10 // Step pulse delay in microseconds. Default disabled.
+
+// The number of linear motions in the planner buffer to be planned at any give time. The vast
+// majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra
+// available RAM, like when re-compiling for a Mega2560. Or decrease if the Arduino begins to
+// crash due to the lack of available RAM or if the CPU is having trouble keeping up with planning
+// new incoming motions as they are executed.
+// #define BLOCK_BUFFER_SIZE 16 // Uncomment to override default in planner.h.
+
+// Governs the size of the intermediary step segment buffer between the step execution algorithm
+// and the planner blocks. Each segment is set of steps executed at a constant velocity over a
+// fixed time defined by ACCELERATION_TICKS_PER_SECOND. They are computed such that the planner
+// block velocity profile is traced exactly. The size of this buffer governs how much step
+// execution lead time there is for other Grbl processes have to compute and do their thing
+// before having to come back and refill this buffer, currently at ~50msec of step moves.
+// #define SEGMENT_BUFFER_SIZE 6 // Uncomment to override default in stepper.h.
+
+// Line buffer size from the serial input stream to be executed. Also, governs the size of
+// each of the startup blocks, as they are each stored as a string of this size. Make sure
+// to account for the available EEPROM at the defined memory address in settings.h and for
+// the number of desired startup blocks.
+// NOTE: 80 characters is not a problem except for extreme cases, but the line buffer size
+// can be too small and g-code blocks can get truncated. Officially, the g-code standards
+// support up to 256 characters. In future versions, this default will be increased, when
+// we know how much extra memory space we can re-invest into this.
+// #define LINE_BUFFER_SIZE 80  // Uncomment to override default in protocol.h
+
+// Serial send and receive buffer size. The receive buffer is often used as another streaming
+// buffer to store incoming blocks to be processed by Grbl when its ready. Most streaming
+// interfaces will character count and track each block send to each block response. So,
+// increase the receive buffer if a deeper receive buffer is needed for streaming and avaiable
+// memory allows. The send buffer primarily handles messages in Grbl. Only increase if large
+// messages are sent and Grbl begins to stall, waiting to send the rest of the message.
+// NOTE: Grbl generates an average status report in about 0.5msec, but the serial TX stream at
+// 115200 baud will take 5 msec to transmit a typical 55 character report. Worst case reports are
+// around 90-100 characters. As long as the serial TX buffer doesn't get continually maxed, Grbl
+// will continue operating efficiently. Size the TX buffer around the size of a worst-case report.
+#if !defined (STM32F103C8)
+// #define RX_BUFFER_SIZE 128 // (1-254) Uncomment to override defaults in serial.h
+// #define TX_BUFFER_SIZE 100 // (1-254)
+#endif
+
+// A simple software debouncing feature for hard limit switches. When enabled, the interrupt 
+// monitoring the hard limit switch pins will enable the Arduino's watchdog timer to re-check 
+// the limit pin state after a delay of about 32msec. This can help with CNC machines with 
+// problematic false triggering of their hard limit switches, but it WILL NOT fix issues with 
+// electrical interference on the signal cables from external sources. It's recommended to first
+// use shielded signal cables with their shielding connected to ground (old USB/computer cables 
+// work well and are cheap to find) and wire in a low-pass circuit into each limit pin.
+// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable.
+
+// Configures the position after a probing cycle during Grbl's check mode. Disabled sets
+// the position to the probe target, when enabled sets the position to the start position.
+// #define SET_CHECK_MODE_PROBE_TO_START // Default disabled. Uncomment to enable.
+
+// Force Grbl to check the state of the hard limit switches when the processor detects a pin
+// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits
+// alarm upon any pin change, since bouncing switches can cause a state check like this to
+// misread the pin. When hard limits are triggered, they should be 100% reliable, which is the
+// reason that this option is disabled by default. Only if your system/electronics can guarantee
+// that the switches don't bounce, we recommend enabling this option. This will help prevent
+// triggering a hard limit when the machine disengages from the switch.
+// NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled.
+// #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable.
+
+// Adjusts homing cycle search and locate scalars. These are the multipliers used by Grbl's
+// homing cycle to ensure the limit switches are engaged and cleared through each phase of
+// the cycle. The search phase uses the axes max-travel setting times the SEARCH_SCALAR to
+// determine distance to look for the limit switch. Once found, the locate phase begins and
+// uses the homing pull-off distance setting times the LOCATE_SCALAR to pull-off and re-engage
+// the limit switch.
+// NOTE: Both of these values must be greater than 1.0 to ensure proper function.
+// #define HOMING_AXIS_SEARCH_SCALAR  1.5f // Uncomment to override defaults in limits.c.
+// #define HOMING_AXIS_LOCATE_SCALAR  10.0f // Uncomment to override defaults in limits.c.
+
+// Enable the '$RST=*', '$RST=$', and '$RST=#' eeprom restore commands. There are cases where
+// these commands may be undesirable. Simply comment the desired macro to disable it.
+// NOTE: See SETTINGS_RESTORE_ALL macro for customizing the `$RST=*` command.
+#define ENABLE_RESTORE_EEPROM_WIPE_ALL         // '$RST=*' Default enabled. Comment to disable.
+#define ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // '$RST=$' Default enabled. Comment to disable.
+#define ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // '$RST=#' Default enabled. Comment to disable.
+
+// Defines the EEPROM data restored upon a settings version change and `$RST=*` command. Whenever the
+// the settings or other EEPROM data structure changes between Grbl versions, Grbl will automatically
+// wipe and restore the EEPROM. This macro controls what data is wiped and restored. This is useful
+// particularily for OEMs that need to retain certain data. For example, the BUILD_INFO string can be
+// written into the Arduino EEPROM via a seperate .INO sketch to contain product data. Altering this
+// macro to not restore the build info EEPROM will ensure this data is retained after firmware upgrades.
+// NOTE: Uncomment to override defaults in settings.h
+// #define SETTINGS_RESTORE_ALL (SETTINGS_RESTORE_DEFAULTS | SETTINGS_RESTORE_PARAMETERS | SETTINGS_RESTORE_STARTUP_LINES | SETTINGS_RESTORE_BUILD_INFO)
+
+// Enable the '$I=(string)' build info write command. If disabled, any existing build info data must
+// be placed into EEPROM via external means with a valid checksum value. This macro option is useful
+// to prevent this data from being over-written by a user, when used to store OEM product data.
+// NOTE: If disabled and to ensure Grbl can never alter the build info line, you'll also need to enable
+// the SETTING_RESTORE_ALL macro above and remove SETTINGS_RESTORE_BUILD_INFO from the mask.
+// NOTE: See the included grblWrite_BuildInfo.ino example file to write this string seperately.
+#define ENABLE_BUILD_INFO_WRITE_COMMAND // '$I=' Default enabled. Comment to disable.
+
+// AVR processors require all interrupts to be disabled during an EEPROM write. This includes both
+// the stepper ISRs and serial comm ISRs. In the event of a long EEPROM write, this ISR pause can
+// cause active stepping to lose position and serial receive data to be lost. This configuration
+// option forces the planner buffer to completely empty whenever the EEPROM is written to prevent
+// any chance of lost steps.
+// However, this doesn't prevent issues with lost serial RX data during an EEPROM write, especially
+// if a GUI is premptively filling up the serial RX buffer simultaneously. It's highly advised for
+// GUIs to flag these gcodes (G10,G28.1,G30.1) to always wait for an 'ok' after a block containing
+// one of these commands before sending more data to eliminate this issue.
+// NOTE: Most EEPROM write commands are implicitly blocked during a job (all '$' commands). However,
+// coordinate set g-code commands (G10,G28/30.1) are not, since they are part of an active streaming
+// job. At this time, this option only forces a planner buffer sync with these g-code commands.
+#define FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // Default enabled. Comment to disable.
+
+// In Grbl v0.9 and prior, there is an old outstanding bug where the `WPos:` work position reported
+// may not correlate to what is executing, because `WPos:` is based on the g-code parser state, which
+// can be several motions behind. This option forces the planner buffer to empty, sync, and stop
+// motion whenever there is a command that alters the work coordinate offsets `G10,G43.1,G92,G54-59`.
+// This is the simplest way to ensure `WPos:` is always correct. Fortunately, it's exceedingly rare
+// that any of these commands are used need continuous motions through them.
+#define FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // Default enabled. Comment to disable.
+
+// By default, Grbl disables feed rate overrides for all G38.x probe cycle commands. Although this
+// may be different than some pro-class machine control, it's arguable that it should be this way. 
+// Most probe sensors produce different levels of error that is dependent on rate of speed. By 
+// keeping probing cycles to their programmed feed rates, the probe sensor should be a lot more
+// repeatable. If needed, you can disable this behavior by uncommenting the define below.
+// #define ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES // Default disabled. Uncomment to enable.
+
+// Enables and configures parking motion methods upon a safety door state. Primarily for OEMs
+// that desire this feature for their integrated machines. At the moment, Grbl assumes that
+// the parking motion only involves one axis, although the parking implementation was written
+// to be easily refactored for any number of motions on different axes by altering the parking
+// source code. At this time, Grbl only supports parking one axis (typically the Z-axis) that
+// moves in the positive direction upon retracting and negative direction upon restoring position.
+// The motion executes with a slow pull-out retraction motion, power-down, and a fast park.
+// Restoring to the resume position follows these set motions in reverse: fast restore to
+// pull-out position, power-up with a time-out, and plunge back to the original position at the
+// slower pull-out rate.
+// NOTE: Still a work-in-progress. Machine coordinates must be in all negative space and
+// does not work with HOMING_FORCE_SET_ORIGIN enabled. Parking motion also moves only in
+// positive direction.
+// #define PARKING_ENABLE  // Default disabled. Uncomment to enable
+
+// Configure options for the parking motion, if enabled.
+#define PARKING_AXIS Z_AXIS // Define which axis that performs the parking motion
+#define PARKING_TARGET -5.0f // Parking axis target. In mm, as machine coordinate [-max_travel,0].
+#define PARKING_RATE 500.0f // Parking fast rate after pull-out in mm/min.
+#define PARKING_PULLOUT_RATE 100.0f // Pull-out/plunge slow feed rate in mm/min.
+#define PARKING_PULLOUT_INCREMENT 5.0f // Spindle pull-out and plunge distance in mm. Incremental distance.
+                                      // Must be positive value or equal to zero.
+
+// Enables a special set of M-code commands that enables and disables the parking motion. 
+// These are controlled by `M56`, `M56 P1`, or `M56 Px` to enable and `M56 P0` to disable. 
+// The command is modal and will be set after a planner sync. Since it is g-code, it is 
+// executed in sync with g-code commands. It is not a real-time command.
+// NOTE: PARKING_ENABLE is required. By default, M56 is active upon initialization. Use 
+// DEACTIVATE_PARKING_UPON_INIT to set M56 P0 as the power-up default.
+// #define ENABLE_PARKING_OVERRIDE_CONTROL   // Default disabled. Uncomment to enable
+// #define DEACTIVATE_PARKING_UPON_INIT // Default disabled. Uncomment to enable.
+
+// This option will automatically disable the laser during a feed hold by invoking a spindle stop
+// override immediately after coming to a stop. However, this also means that the laser still may
+// be reenabled by disabling the spindle stop override, if needed. This is purely a safety feature
+// to ensure the laser doesn't inadvertently remain powered while at a stop and cause a fire.
+#define DISABLE_LASER_DURING_HOLD // Default enabled. Comment to disable.
+
+/* ---------------------------------------------------------------------------------------
+   OEM Single File Configuration Option
+
+   Instructions: Paste the cpu_map and default setting definitions below without an enclosing
+   #ifdef. Comment out the CPU_MAP_xxx and DEFAULT_xxx defines at the top of this file, and
+   the compiler will ignore the contents of defaults.h and cpu_map.h and use the definitions
+   below.
+*/
+
+// Paste CPU_MAP definitions here.
+
+// Paste default settings definitions here.
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/coolant_control.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,198 @@
+/*
+  coolant_control.c - coolant control methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+void coolant_init()
+{
+#ifdef AVRTARGET
+  COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT); // Configure as output pin
+  #ifdef ENABLE_M7
+    COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT);
+  #endif
+#endif
+#ifdef STM32F103C8
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_COOLANT_FLOOD_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_InitStructure.GPIO_Pin = 1 << COOLANT_FLOOD_BIT;
+	GPIO_Init(COOLANT_FLOOD_PORT, &GPIO_InitStructure);
+
+	RCC_APB2PeriphClockCmd(RCC_COOLANT_MIST_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_InitStructure.GPIO_Pin = 1 << COOLANT_MIST_BIT;
+	GPIO_Init(COOLANT_MIST_PORT, &GPIO_InitStructure);
+#endif
+  coolant_stop();
+}
+
+
+// Returns current coolant output state. Overrides may alter it from programmed state.
+uint8_t coolant_get_state()
+{
+  uint8_t cl_state = COOLANT_STATE_DISABLE;
+#if defined(AVRTARGET) || defined(STM32F103C8)
+  #ifdef INVERT_COOLANT_FLOOD_PIN
+    if (bit_isfalse(
+#ifdef AVRTARGET
+		COOLANT_FLOOD_PORT
+#else
+		GPIO_ReadOutputData(COOLANT_FLOOD_PORT)
+#endif
+		,(1 << COOLANT_FLOOD_BIT))) {
+  #else
+    if (bit_istrue(
+#ifdef AVRTARGET
+		COOLANT_FLOOD_PORT
+#else
+		GPIO_ReadOutputData(COOLANT_FLOOD_PORT)
+#endif
+		,(1 << COOLANT_FLOOD_BIT))) {
+  #endif
+    cl_state |= COOLANT_STATE_FLOOD;
+  }
+  #ifdef ENABLE_M7
+    #ifdef INVERT_COOLANT_MIST_PIN
+      if (bit_isfalse(
+#ifdef AVRTARGET
+		  COOLANT_MIST_PORT
+#else
+		  GPIO_ReadOutputData(COOLANT_MIST_PORT)
+#endif
+		  ,(1 << COOLANT_MIST_BIT))) {
+    #else
+      if (bit_istrue(
+#ifdef AVRTARGET
+		  COOLANT_MIST_PORT
+#else
+		  GPIO_ReadOutputData(COOLANT_MIST_PORT)
+#endif
+		  ,(1 << COOLANT_MIST_BIT))) {
+    #endif
+      cl_state |= COOLANT_STATE_MIST;
+    }
+  #endif
+#endif
+  return(cl_state);
+}
+
+
+// Directly called by coolant_init(), coolant_set_state(), and mc_reset(), which can be at
+// an interrupt-level. No report flag set, but only called by routines that don't need it.
+void coolant_stop()
+{
+#if defined(AVRTARGET) || defined(STM32F103C8)
+  #ifdef INVERT_COOLANT_FLOOD_PIN
+#ifdef AVRTARGET
+    COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
+#else
+	GPIO_SetBits(COOLANT_FLOOD_PORT,1 << COOLANT_FLOOD_BIT);
+#endif
+  #else
+#ifdef AVRTARGET
+	COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
+#else
+	GPIO_ResetBits(COOLANT_FLOOD_PORT,1 << COOLANT_FLOOD_BIT);
+#endif
+  #endif
+  #ifdef ENABLE_M7
+    #ifdef INVERT_COOLANT_MIST_PIN
+#ifdef AVRTARGET
+      COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
+#else
+	GPIO_SetBits(COOLANT_MIST_PORT, 1 << COOLANT_MIST_BIT);
+#endif
+    #else
+#ifdef AVRTARGET
+	COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
+#else
+	GPIO_ResetBits(COOLANT_MIST_PORT, 1 << COOLANT_MIST_BIT);
+#endif
+    #endif
+  #endif
+#endif
+}
+
+
+// Main program only. Immediately sets flood coolant running state and also mist coolant, 
+// if enabled. Also sets a flag to report an update to a coolant state.
+// Called by coolant toggle override, parking restore, parking retract, sleep mode, g-code
+// parser program end, and g-code parser coolant_sync().
+void coolant_set_state(uint8_t mode)
+{
+  if (sys.abort) { return; } // Block during abort.  
+  
+  if (mode == COOLANT_DISABLE) {
+  
+    coolant_stop(); 
+  
+  } else {
+  
+#if defined(AVRTARGET) || defined(STM32F103C8)
+	  if (mode & COOLANT_FLOOD_ENABLE) {
+      #ifdef INVERT_COOLANT_FLOOD_PIN
+#ifdef AVRTARGET
+        COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
+#else
+		GPIO_ResetBits(COOLANT_FLOOD_PORT,1 << COOLANT_FLOOD_BIT);
+#endif
+      #else
+#ifdef AVRTARGET
+		COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
+#else
+		GPIO_SetBits(COOLANT_FLOOD_PORT,1 << COOLANT_FLOOD_BIT);
+#endif
+      #endif
+    }
+  
+    #ifdef ENABLE_M7
+      if (mode & COOLANT_MIST_ENABLE) {
+        #ifdef INVERT_COOLANT_MIST_PIN
+#ifdef AVRTARGET
+		  COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
+#else
+	GPIO_ResetBits(COOLANT_MIST_PORT, 1 << COOLANT_MIST_BIT);
+#endif
+        #else
+#ifdef AVRTARGET
+		  COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
+#else
+		  GPIO_SetBits(COOLANT_MIST_PORT, 1 << COOLANT_MIST_BIT);
+#endif
+        #endif
+      }
+    #endif
+#endif  
+  }
+  sys.report_ovr_counter = 0; // Set to report change immediately
+}
+
+
+// G-code parser entry-point for setting coolant state. Forces a planner buffer sync and bails 
+// if an abort or check-mode is active.
+void coolant_sync(uint8_t mode)
+{
+  if (sys.state == STATE_CHECK_MODE) { return; }
+  protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program.
+  coolant_set_state(mode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/coolant_control.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,47 @@
+/*
+  coolant_control.h - spindle control methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef coolant_control_h
+#define coolant_control_h
+
+#define COOLANT_NO_SYNC     false
+#define COOLANT_FORCE_SYNC  true
+
+#define COOLANT_STATE_DISABLE   0  // Must be zero
+#define COOLANT_STATE_FLOOD     bit(0)
+#define COOLANT_STATE_MIST      bit(1)
+
+
+// Initializes coolant control pins.
+void coolant_init();
+
+// Returns current coolant output state. Overrides may alter it from programmed state.
+uint8_t coolant_get_state();
+
+// Immediately disables coolant pins.
+void coolant_stop();
+
+// Sets the coolant pins according to state specified.
+void coolant_set_state(uint8_t mode);
+
+// G-code parser entry-point for setting coolant states. Checks for and executes additional conditions.
+void coolant_sync(uint8_t mode);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/cpu_map.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,411 @@
+/*
+  cpu_map.h - CPU and pin mapping configuration file
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The cpu_map.h files serve as a central pin mapping selection file for different
+   processor types or alternative pin layouts. This version of Grbl officially supports
+   only the Arduino Mega328p. */
+
+
+#ifndef cpu_map_h
+#define cpu_map_h
+
+
+#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl.
+
+  // Define serial port pins and interrupt vectors.
+  #define SERIAL_RX     USART_RX_vect
+  #define SERIAL_UDRE   USART_UDRE_vect
+
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+  #define STEP_DDR        DDRD
+  #define STEP_PORT       PORTD
+  #define X_STEP_BIT      2  // Uno Digital Pin 2
+  #define Y_STEP_BIT      3  // Uno Digital Pin 3
+  #define Z_STEP_BIT      4  // Uno Digital Pin 4
+  #define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+  #define DIRECTION_DDR     DDRD
+  #define DIRECTION_PORT    PORTD
+  #define X_DIRECTION_BIT   5  // Uno Digital Pin 5
+  #define Y_DIRECTION_BIT   6  // Uno Digital Pin 6
+  #define Z_DIRECTION_BIT   7  // Uno Digital Pin 7
+  #define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+  #define STEPPERS_DISABLE_DDR    DDRB
+  #define STEPPERS_DISABLE_PORT   PORTB
+  #define STEPPERS_DISABLE_BIT    0  // Uno Digital Pin 8
+  #define STEPPERS_DISABLE_MASK   (1<<STEPPERS_DISABLE_BIT)
+  #define SetStepperDisableBit() STEPPERS_DISABLE_PORT |= (1 << STEPPERS_DISABLE_BIT)
+  #define ResetStepperDisableBit() STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT)
+  #define EnableStepperDisabeBit()  STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors.
+  // NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (CONTROL).
+  #define LIMIT_DDR        DDRB
+  #define LIMIT_PIN        PINB
+  #define LIMIT_PORT       PORTB
+  #define X_LIMIT_BIT      1  // Uno Digital Pin 9
+  #define Y_LIMIT_BIT      2  // Uno Digital Pin 10
+  #ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
+    #define Z_LIMIT_BIT	   4 // Uno Digital Pin 12
+  #else
+    #define Z_LIMIT_BIT    3  // Uno Digital Pin 11
+  #endif
+  #define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+  #define LIMIT_INT        PCIE0  // Pin change interrupt enable pin
+  #define LIMIT_INT_vect   PCINT0_vect
+  #define LIMIT_PCMSK      PCMSK0 // Pin change interrupt register
+
+  // Define spindle enable and spindle direction output pins.
+  #define SPINDLE_ENABLE_DDR    DDRB
+  #define SPINDLE_ENABLE_PORT   PORTB
+  // Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11.
+  #ifdef VARIABLE_SPINDLE
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      // If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11.
+      #define SPINDLE_ENABLE_BIT    5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+    #else
+      #define SPINDLE_ENABLE_BIT    3  // Uno Digital Pin 11
+    #endif
+  #else
+    #define SPINDLE_ENABLE_BIT    4  // Uno Digital Pin 12
+  #endif
+  #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+    #define SPINDLE_DIRECTION_DDR   DDRB
+    #define SPINDLE_DIRECTION_PORT  PORTB
+    #define SPINDLE_DIRECTION_BIT   5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+  #endif
+#define SetSpindleEnablebit()       SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);  // Set pin to high
+#define ResetSpindleEnablebit()     SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); // Set pin to low
+#define SetSpindleDirectionBit()    SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
+#define ResetSpindleDirectionBit()  SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
+
+
+  // Define flood and mist coolant enable output pins.
+  #define COOLANT_FLOOD_DDR   DDRC
+  #define COOLANT_FLOOD_PORT  PORTC
+  #define COOLANT_FLOOD_BIT   3  // Uno Analog Pin 3
+  #define COOLANT_MIST_DDR   DDRC
+  #define COOLANT_MIST_PORT  PORTC
+  #define COOLANT_MIST_BIT   4  // Uno Analog Pin 4
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+  #define CONTROL_DDR       DDRC
+  #define CONTROL_PIN       PINC
+  #define CONTROL_PORT      PORTC
+  #define CONTROL_RESET_BIT         0  // Uno Analog Pin 0
+  #define CONTROL_FEED_HOLD_BIT     1  // Uno Analog Pin 1
+  #define CONTROL_CYCLE_START_BIT   2  // Uno Analog Pin 2
+  #define CONTROL_SAFETY_DOOR_BIT   1  // Uno Analog Pin 1 NOTE: Safety door is shared with feed hold. Enabled by config define.
+  #define CONTROL_INT       PCIE1  // Pin change interrupt enable pin
+  #define CONTROL_INT_vect  PCINT1_vect
+  #define CONTROL_PCMSK     PCMSK1 // Pin change interrupt register
+  #define CONTROL_MASK      ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+  #define CONTROL_INVERT_MASK   CONTROL_MASK // May be re-defined to only invert certain control pins.
+
+  // Define probe switch input pin.
+  #define PROBE_DDR       DDRC
+  #define PROBE_PIN       PINC
+  #define PROBE_PORT      PORTC
+  #define PROBE_BIT       5  // Uno Analog Pin 5
+  #define PROBE_MASK      (1<<PROBE_BIT)
+
+  // Variable spindle configuration below. Do not change unless you know what you are doing.
+  // NOTE: Only used when variable spindle is enabled.
+  #define SPINDLE_PWM_MAX_VALUE     255 // Don't change. 328p fast PWM mode fixes top value as 255.
+  #ifndef SPINDLE_PWM_MIN_VALUE
+    #define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+  #endif
+  #define SPINDLE_PWM_OFF_VALUE     0
+  #define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+  #define SPINDLE_TCCRA_REGISTER	  TCCR2A
+  #define SPINDLE_TCCRB_REGISTER	  TCCR2B
+  #define SPINDLE_OCR_REGISTER      OCR2A
+  #define SPINDLE_COMB_BIT	        COM2A1
+
+  // Prescaled, 8-bit Fast PWM mode.
+  #define SPINDLE_TCCRA_INIT_MASK   ((1<<WGM20) | (1<<WGM21))  // Configures fast PWM mode.
+  // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS20)               // Disable prescaler -> 62.5kHz
+  // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS21)               // 1/8 prescaler -> 7.8kHz (Used in v0.9)
+  // #define SPINDLE_TCCRB_INIT_MASK   ((1<<CS21) | (1<<CS20)) // 1/32 prescaler -> 1.96kHz
+  #define SPINDLE_TCCRB_INIT_MASK      (1<<CS22)               // 1/64 prescaler -> 0.98kHz (J-tech laser)
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+  #define SPINDLE_PWM_DDR	  DDRB
+  #define SPINDLE_PWM_PORT  PORTB
+  #define SPINDLE_PWM_BIT	  3    // Uno Digital Pin 11
+
+#endif
+
+  // Define serial port pins and interrupt vectors.
+#ifdef CPU_MAP_WIN32
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+#define STEP_DDR        DDRD
+#define STEP_PORT       PORTD
+#define X_STEP_BIT      2  
+#define Y_STEP_BIT      3  
+#define Z_STEP_BIT      4  
+#define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+#define DIRECTION_DDR     DDRD
+#define DIRECTION_PORT    PORTD
+#define X_DIRECTION_BIT   5  
+#define Y_DIRECTION_BIT   6  
+#define Z_DIRECTION_BIT   7  
+#define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+#define SetStepperDisableBit() 
+#define ResetStepperDisableBit() 
+
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors. 
+  // NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (CONTROL).
+#define LIMIT_DDR        DDRB
+#define LIMIT_PIN        PINB
+#define LIMIT_PORT       PORTB
+#define X_LIMIT_BIT      1  
+#define Y_LIMIT_BIT      2  
+#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.  
+#define Z_LIMIT_BIT	   4 
+#else
+#define Z_LIMIT_BIT    3  
+#endif
+#define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+#define LIMIT_INT        PCIE0  // Pin change interrupt enable pin
+#define LIMIT_INT_vect   PCINT0_vect 
+#define LIMIT_PCMSK      PCMSK0 // Pin change interrupt register
+
+  // Define spindle enable and spindle direction output pins.
+#define SPINDLE_ENABLE_DDR    DDRB
+#define SPINDLE_ENABLE_PORT   PORTB
+  // Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11.
+#ifdef VARIABLE_SPINDLE 
+#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+  // If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11.
+#define SPINDLE_ENABLE_BIT    5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+#else
+#define SPINDLE_ENABLE_BIT    3  // Uno Digital Pin 11
+#endif
+#else
+#define SPINDLE_ENABLE_BIT    4  // Uno Digital Pin 12
+#endif
+#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#define SPINDLE_DIRECTION_DDR   DDRB
+#define SPINDLE_DIRECTION_PORT  PORTB
+#define SPINDLE_DIRECTION_BIT   5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+#endif
+
+  // Define flood and mist coolant enable output pins.
+  // NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
+  // a later date if flash and memory space allows.
+#define COOLANT_FLOOD_DDR   DDRC
+#define COOLANT_FLOOD_PORT  PORTC
+#define COOLANT_FLOOD_BIT   3  // Uno Analog Pin 3
+#ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable.
+#define COOLANT_MIST_DDR   DDRC
+#define COOLANT_MIST_PORT  PORTC
+#define COOLANT_MIST_BIT   4 // Uno Analog Pin 4
+#endif  
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+#define CONTROL_DDR       DDRC
+#define CONTROL_PIN       PINC
+#define CONTROL_PORT      PORTC
+#define CONTROL_RESET_BIT         0  // MEGA2560 Analog Pin 8
+#define CONTROL_FEED_HOLD_BIT     1  // MEGA2560 Analog Pin 9
+#define CONTROL_CYCLE_START_BIT   2  // MEGA2560 Analog Pin 10
+#define CONTROL_SAFETY_DOOR_BIT   3  // MEGA2560 Analog Pin 11
+#define CONTROL_INT       PCIE2  // Pin change interrupt enable pin
+#define CONTROL_INT_vect  PCINT2_vect
+#define CONTROL_PCMSK     PCMSK2 // Pin change interrupt register
+#define CONTROL_MASK      ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+
+  // Define probe switch input pin.
+#define PROBE_DDR       DDRC
+#define PROBE_PIN       PINC
+#define PROBE_PORT      PORTC
+#define PROBE_BIT       5  // Uno Analog Pin 5
+#define PROBE_MASK      (1<<PROBE_BIT)
+
+  // Start of PWM & Stepper Enabled Spindle
+#ifdef VARIABLE_SPINDLE
+  // Advanced Configuration Below You should not need to touch these variables
+#define PWM_MAX_VALUE    255.0
+#define TCCRA_REGISTER	 TCCR2A
+#define TCCRB_REGISTER	 TCCR2B
+#define OCR_REGISTER     OCR2A
+
+#define COMB_BIT	     COM2A1
+#define WAVE0_REGISTER	 WGM20
+#define WAVE1_REGISTER	 WGM21
+#define WAVE2_REGISTER	 WGM22
+#define WAVE3_REGISTER	 WGM23
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+#define SPINDLE_PWM_DDR	  DDRB
+#define SPINDLE_PWM_PORT  PORTB
+#define SPINDLE_PWM_BIT	  3    // Uno Digital Pin 11
+#endif // End of VARIABLE_SPINDLE
+#define SPINDLE_PWM_MAX_VALUE     255 // Don't change. 328p fast PWM mode fixes top value as 255.
+#ifndef SPINDLE_PWM_MIN_VALUE
+#define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+#endif
+#define SPINDLE_PWM_OFF_VALUE     0
+#define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+
+#define SetSpindleEnablebit()         // Set pin to high
+#define ResetSpindleEnablebit()      // Set pin to low
+#define SetSpindleDirectionBit()
+#define ResetSpindleDirectionBit()
+
+#endif
+
+#ifdef CPU_MAP_STM32F103
+
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+#define STEP_PORT       GPIOA
+#define RCC_STEP_PORT   RCC_APB2Periph_GPIOA
+#define X_STEP_BIT      0  
+#define Y_STEP_BIT      1  
+#define Z_STEP_BIT      2
+#define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+#define DIRECTION_PORT      GPIOA
+#define RCC_DIRECTION_PORT   RCC_APB2Periph_GPIOA
+#define X_DIRECTION_BIT   3  
+#define Y_DIRECTION_BIT   4  
+#define Z_DIRECTION_BIT   5
+#define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+#define STEPPERS_DISABLE_PORT   GPIOA
+#define RCC_STEPPERS_DISABLE_PORT RCC_APB2Periph_GPIOA
+#define STEPPERS_DISABLE_BIT    6  
+#define STEPPERS_DISABLE_MASK   (1<<STEPPERS_DISABLE_BIT)
+#define SetStepperDisableBit() GPIO_SetBits(STEPPERS_DISABLE_PORT,STEPPERS_DISABLE_MASK)
+#define ResetStepperDisableBit() GPIO_ResetBits(STEPPERS_DISABLE_PORT,STEPPERS_DISABLE_MASK)
+
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors. 
+  // NOTE: All limit bit pins must be on the same port
+#define LIMIT_PIN        GPIOB
+#define LIMIT_PORT       GPIOB
+#define RCC_LIMIT_PORT   RCC_APB2Periph_GPIOB
+#define GPIO_LIMIT_PORT  GPIO_PortSourceGPIOB
+#define X_LIMIT_BIT      10  
+#define Y_LIMIT_BIT      11  
+#define Z_LIMIT_BIT      12  
+
+#define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+
+  // Define spindle enable and spindle direction output pins.
+#define SPINDLE_ENABLE_PORT   GPIOB
+#define RCC_SPINDLE_ENABLE_PORT RCC_APB2Periph_GPIOB
+#define SPINDLE_ENABLE_BIT    13  // 
+#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#define SPINDLE_DIRECTION_DDR   GPIOB
+#define SPINDLE_DIRECTION_PORT  GPIOB
+#define SPINDLE_DIRECTION_BIT   14  // 
+#endif
+#define SetSpindleEnablebit()       GPIO_WriteBit(SPINDLE_ENABLE_PORT, 1 << SPINDLE_ENABLE_BIT, Bit_SET)
+#define ResetSpindleEnablebit()     GPIO_WriteBit(SPINDLE_ENABLE_PORT, 1 << SPINDLE_ENABLE_BIT, Bit_RESET)
+#define SetSpindleDirectionBit()    GPIO_WriteBit(SPINDLE_DIRECTION_PORT, 1 << SPINDLE_DIRECTION_BIT,Bit_SET)
+#define ResetSpindleDirectionBit()  GPIO_WriteBit(SPINDLE_DIRECTION_PORT, 1 << SPINDLE_DIRECTION_BIT,Bit_RESET)
+
+
+  // Define flood and mist coolant enable output pins.
+  // a later date if flash and memory space allows.
+#define COOLANT_FLOOD_PORT            GPIOB
+#define RCC_COOLANT_FLOOD_PORT        RCC_APB2Periph_GPIOB
+#define COOLANT_FLOOD_BIT             3  
+#define COOLANT_MIST_PORT             GPIOB
+#define RCC_COOLANT_MIST_PORT         RCC_APB2Periph_GPIOB
+#define COOLANT_MIST_BIT              4 
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+#define CONTROL_PIN_PORT              GPIOB
+#define CONTROL_PORT                  GPIOB
+#define RCC_CONTROL_PORT              RCC_APB2Periph_GPIOB
+#define GPIO_CONTROL_PORT             GPIO_PortSourceGPIOB
+#define CONTROL_RESET_BIT             5  
+#define CONTROL_FEED_HOLD_BIT         6  
+#define CONTROL_CYCLE_START_BIT       7  
+#define CONTROL_SAFETY_DOOR_BIT       8  
+#define CONTROL_MASK                 ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+
+  // Define probe switch input pin.
+#define PROBE_PORT                    GPIOA
+#define RCC_PROBE_PORT                RCC_APB2Periph_GPIOA
+#define PROBE_BIT                     15 
+#define PROBE_MASK                    (1<<PROBE_BIT)
+
+  // Start of PWM & Stepper Enabled Spindle
+#ifdef VARIABLE_SPINDLE
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+#define SPINDLE_PWM_FREQUENCY       10000                   // KHz
+#define SPINDLE_PWM_DDR	            GPIOA
+#define SPINDLE_PWM_PORT            GPIOA
+#define RCC_SPINDLE_PWM_PORT        RCC_APB2Periph_GPIOA
+#define SPINDLE_PWM_BIT	            8    
+#endif // End of VARIABLE_SPINDLE
+#define SPINDLE_PWM_MAX_VALUE       (1000000 / SPINDLE_PWM_FREQUENCY)
+#ifndef SPINDLE_PWM_MIN_VALUE
+#define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+#endif
+#define SPINDLE_PWM_OFF_VALUE     0
+#define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+
+  //  Port A                                         Port B
+  //   0      X_STEP_BIT                             
+  //   1      Y_STEP_BIT                            
+  //   2      Z_STEP_BIT                               
+  //   3      X_DIRECTION_BIT                       COOLANT_FLOOD_BIT
+  //   4      Y_DIRECTION_BIT                       COOLANT_MIST_BIT
+  //   5      Z_DIRECTION_BIT                       CONTROL_RESET_BIT
+  //   6      STEPPERS_DISABLE_BIT                  CONTROL_FEED_HOLD_BIT    
+  //   7                                            CONTROL_CYCLE_START_BIT
+  //   8      SPINDLE_PWM_BIT                       CONTROL_SAFETY_DOOR_BIT    
+  //   9                             
+  //   10                                            X_LIMIT_BIT
+  //   11                                            Y_LIMIT_BIT
+  //   12                                            Z_LIMIT_BIT
+  //   13 14 SWD																		SPINDLE_ENABLE_BIT
+//     14																						SPINDLE_DIRECTION_BIT
+  //   15     PROBE_BIT					
+
+#endif
+/*
+#ifdef CPU_MAP_CUSTOM_PROC
+  // For a custom pin map or different processor, copy and edit one of the available cpu
+  // map files and modify it to your needs. Make sure the defined name is also changed in
+  // the config.h file.
+#endif
+*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/cpu_map.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,410 @@
+/*
+  cpu_map.h - CPU and pin mapping configuration file
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The cpu_map.h files serve as a central pin mapping selection file for different
+   processor types or alternative pin layouts. This version of Grbl officially supports
+   only the Arduino Mega328p. */
+
+
+#ifndef cpu_map_h
+#define cpu_map_h
+
+
+#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl.
+
+  // Define serial port pins and interrupt vectors.
+  #define SERIAL_RX     USART_RX_vect
+  #define SERIAL_UDRE   USART_UDRE_vect
+
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+  #define STEP_DDR        DDRD
+  #define STEP_PORT       PORTD
+  #define X_STEP_BIT      2  // Uno Digital Pin 2
+  #define Y_STEP_BIT      3  // Uno Digital Pin 3
+  #define Z_STEP_BIT      4  // Uno Digital Pin 4
+  #define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+  #define DIRECTION_DDR     DDRD
+  #define DIRECTION_PORT    PORTD
+  #define X_DIRECTION_BIT   5  // Uno Digital Pin 5
+  #define Y_DIRECTION_BIT   6  // Uno Digital Pin 6
+  #define Z_DIRECTION_BIT   7  // Uno Digital Pin 7
+  #define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+  #define STEPPERS_DISABLE_DDR    DDRB
+  #define STEPPERS_DISABLE_PORT   PORTB
+  #define STEPPERS_DISABLE_BIT    0  // Uno Digital Pin 8
+  #define STEPPERS_DISABLE_MASK   (1<<STEPPERS_DISABLE_BIT)
+  #define SetStepperDisableBit() STEPPERS_DISABLE_PORT |= (1 << STEPPERS_DISABLE_BIT)
+  #define ResetStepperDisableBit() STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT)
+  #define EnableStepperDisabeBit()  STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors.
+  // NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (CONTROL).
+  #define LIMIT_DDR        DDRB
+  #define LIMIT_PIN        PINB
+  #define LIMIT_PORT       PORTB
+  #define X_LIMIT_BIT      1  // Uno Digital Pin 9
+  #define Y_LIMIT_BIT      2  // Uno Digital Pin 10
+  #ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
+    #define Z_LIMIT_BIT	   4 // Uno Digital Pin 12
+  #else
+    #define Z_LIMIT_BIT    3  // Uno Digital Pin 11
+  #endif
+  #define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+  #define LIMIT_INT        PCIE0  // Pin change interrupt enable pin
+  #define LIMIT_INT_vect   PCINT0_vect
+  #define LIMIT_PCMSK      PCMSK0 // Pin change interrupt register
+
+  // Define spindle enable and spindle direction output pins.
+  #define SPINDLE_ENABLE_DDR    DDRB
+  #define SPINDLE_ENABLE_PORT   PORTB
+  // Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11.
+  #ifdef VARIABLE_SPINDLE
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      // If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11.
+      #define SPINDLE_ENABLE_BIT    5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+    #else
+      #define SPINDLE_ENABLE_BIT    3  // Uno Digital Pin 11
+    #endif
+  #else
+    #define SPINDLE_ENABLE_BIT    4  // Uno Digital Pin 12
+  #endif
+  #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+    #define SPINDLE_DIRECTION_DDR   DDRB
+    #define SPINDLE_DIRECTION_PORT  PORTB
+    #define SPINDLE_DIRECTION_BIT   5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+  #endif
+#define SetSpindleEnablebit()       SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);  // Set pin to high
+#define ResetSpindleEnablebit()     SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); // Set pin to low
+#define SetSpindleDirectionBit()    SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
+#define ResetSpindleDirectionBit()  SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
+
+
+  // Define flood and mist coolant enable output pins.
+  #define COOLANT_FLOOD_DDR   DDRC
+  #define COOLANT_FLOOD_PORT  PORTC
+  #define COOLANT_FLOOD_BIT   3  // Uno Analog Pin 3
+  #define COOLANT_MIST_DDR   DDRC
+  #define COOLANT_MIST_PORT  PORTC
+  #define COOLANT_MIST_BIT   4  // Uno Analog Pin 4
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+  #define CONTROL_DDR       DDRC
+  #define CONTROL_PIN       PINC
+  #define CONTROL_PORT      PORTC
+  #define CONTROL_RESET_BIT         0  // Uno Analog Pin 0
+  #define CONTROL_FEED_HOLD_BIT     1  // Uno Analog Pin 1
+  #define CONTROL_CYCLE_START_BIT   2  // Uno Analog Pin 2
+  #define CONTROL_SAFETY_DOOR_BIT   1  // Uno Analog Pin 1 NOTE: Safety door is shared with feed hold. Enabled by config define.
+  #define CONTROL_INT       PCIE1  // Pin change interrupt enable pin
+  #define CONTROL_INT_vect  PCINT1_vect
+  #define CONTROL_PCMSK     PCMSK1 // Pin change interrupt register
+  #define CONTROL_MASK      ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+  #define CONTROL_INVERT_MASK   CONTROL_MASK // May be re-defined to only invert certain control pins.
+
+  // Define probe switch input pin.
+  #define PROBE_DDR       DDRC
+  #define PROBE_PIN       PINC
+  #define PROBE_PORT      PORTC
+  #define PROBE_BIT       5  // Uno Analog Pin 5
+  #define PROBE_MASK      (1<<PROBE_BIT)
+
+  // Variable spindle configuration below. Do not change unless you know what you are doing.
+  // NOTE: Only used when variable spindle is enabled.
+  #define SPINDLE_PWM_MAX_VALUE     255 // Don't change. 328p fast PWM mode fixes top value as 255.
+  #ifndef SPINDLE_PWM_MIN_VALUE
+    #define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+  #endif
+  #define SPINDLE_PWM_OFF_VALUE     0
+  #define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+  #define SPINDLE_TCCRA_REGISTER	  TCCR2A
+  #define SPINDLE_TCCRB_REGISTER	  TCCR2B
+  #define SPINDLE_OCR_REGISTER      OCR2A
+  #define SPINDLE_COMB_BIT	        COM2A1
+
+  // Prescaled, 8-bit Fast PWM mode.
+  #define SPINDLE_TCCRA_INIT_MASK   ((1<<WGM20) | (1<<WGM21))  // Configures fast PWM mode.
+  // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS20)               // Disable prescaler -> 62.5kHz
+  // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS21)               // 1/8 prescaler -> 7.8kHz (Used in v0.9)
+  // #define SPINDLE_TCCRB_INIT_MASK   ((1<<CS21) | (1<<CS20)) // 1/32 prescaler -> 1.96kHz
+  #define SPINDLE_TCCRB_INIT_MASK      (1<<CS22)               // 1/64 prescaler -> 0.98kHz (J-tech laser)
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+  #define SPINDLE_PWM_DDR	  DDRB
+  #define SPINDLE_PWM_PORT  PORTB
+  #define SPINDLE_PWM_BIT	  3    // Uno Digital Pin 11
+
+#endif
+
+  // Define serial port pins and interrupt vectors.
+#ifdef CPU_MAP_WIN32
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+#define STEP_DDR        DDRD
+#define STEP_PORT       PORTD
+#define X_STEP_BIT      2  
+#define Y_STEP_BIT      3  
+#define Z_STEP_BIT      4  
+#define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+#define DIRECTION_DDR     DDRD
+#define DIRECTION_PORT    PORTD
+#define X_DIRECTION_BIT   5  
+#define Y_DIRECTION_BIT   6  
+#define Z_DIRECTION_BIT   7  
+#define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+#define SetStepperDisableBit() 
+#define ResetStepperDisableBit() 
+
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors. 
+  // NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (CONTROL).
+#define LIMIT_DDR        DDRB
+#define LIMIT_PIN        PINB
+#define LIMIT_PORT       PORTB
+#define X_LIMIT_BIT      1  
+#define Y_LIMIT_BIT      2  
+#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.  
+#define Z_LIMIT_BIT	   4 
+#else
+#define Z_LIMIT_BIT    3  
+#endif
+#define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+#define LIMIT_INT        PCIE0  // Pin change interrupt enable pin
+#define LIMIT_INT_vect   PCINT0_vect 
+#define LIMIT_PCMSK      PCMSK0 // Pin change interrupt register
+
+  // Define spindle enable and spindle direction output pins.
+#define SPINDLE_ENABLE_DDR    DDRB
+#define SPINDLE_ENABLE_PORT   PORTB
+  // Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11.
+#ifdef VARIABLE_SPINDLE 
+#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+  // If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11.
+#define SPINDLE_ENABLE_BIT    5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+#else
+#define SPINDLE_ENABLE_BIT    3  // Uno Digital Pin 11
+#endif
+#else
+#define SPINDLE_ENABLE_BIT    4  // Uno Digital Pin 12
+#endif
+#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#define SPINDLE_DIRECTION_DDR   DDRB
+#define SPINDLE_DIRECTION_PORT  PORTB
+#define SPINDLE_DIRECTION_BIT   5  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
+#endif
+
+  // Define flood and mist coolant enable output pins.
+  // NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
+  // a later date if flash and memory space allows.
+#define COOLANT_FLOOD_DDR   DDRC
+#define COOLANT_FLOOD_PORT  PORTC
+#define COOLANT_FLOOD_BIT   3  // Uno Analog Pin 3
+#ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable.
+#define COOLANT_MIST_DDR   DDRC
+#define COOLANT_MIST_PORT  PORTC
+#define COOLANT_MIST_BIT   4 // Uno Analog Pin 4
+#endif  
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+#define CONTROL_DDR       DDRC
+#define CONTROL_PIN       PINC
+#define CONTROL_PORT      PORTC
+#define CONTROL_RESET_BIT         0  // MEGA2560 Analog Pin 8
+#define CONTROL_FEED_HOLD_BIT     1  // MEGA2560 Analog Pin 9
+#define CONTROL_CYCLE_START_BIT   2  // MEGA2560 Analog Pin 10
+#define CONTROL_SAFETY_DOOR_BIT   3  // MEGA2560 Analog Pin 11
+#define CONTROL_INT       PCIE2  // Pin change interrupt enable pin
+#define CONTROL_INT_vect  PCINT2_vect
+#define CONTROL_PCMSK     PCMSK2 // Pin change interrupt register
+#define CONTROL_MASK      ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+
+  // Define probe switch input pin.
+#define PROBE_DDR       DDRC
+#define PROBE_PIN       PINC
+#define PROBE_PORT      PORTC
+#define PROBE_BIT       5  // Uno Analog Pin 5
+#define PROBE_MASK      (1<<PROBE_BIT)
+
+  // Start of PWM & Stepper Enabled Spindle
+#ifdef VARIABLE_SPINDLE
+  // Advanced Configuration Below You should not need to touch these variables
+#define PWM_MAX_VALUE    255.0
+#define TCCRA_REGISTER	 TCCR2A
+#define TCCRB_REGISTER	 TCCR2B
+#define OCR_REGISTER     OCR2A
+
+#define COMB_BIT	     COM2A1
+#define WAVE0_REGISTER	 WGM20
+#define WAVE1_REGISTER	 WGM21
+#define WAVE2_REGISTER	 WGM22
+#define WAVE3_REGISTER	 WGM23
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+#define SPINDLE_PWM_DDR	  DDRB
+#define SPINDLE_PWM_PORT  PORTB
+#define SPINDLE_PWM_BIT	  3    // Uno Digital Pin 11
+#endif // End of VARIABLE_SPINDLE
+#define SPINDLE_PWM_MAX_VALUE     255 // Don't change. 328p fast PWM mode fixes top value as 255.
+#ifndef SPINDLE_PWM_MIN_VALUE
+#define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+#endif
+#define SPINDLE_PWM_OFF_VALUE     0
+#define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+
+#define SetSpindleEnablebit()         // Set pin to high
+#define ResetSpindleEnablebit()      // Set pin to low
+#define SetSpindleDirectionBit()
+#define ResetSpindleDirectionBit()
+
+#endif
+
+#ifdef CPU_MAP_STM32F103
+
+  // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
+#define STEP_PORT       GPIOA
+#define RCC_STEP_PORT   RCC_APB2Periph_GPIOA
+#define X_STEP_BIT      0  
+#define Y_STEP_BIT      1  
+#define Z_STEP_BIT      2
+#define STEP_MASK       ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
+
+  // Define step direction output pins. NOTE: All direction pins must be on the same port.
+#define DIRECTION_PORT      GPIOA
+#define RCC_DIRECTION_PORT   RCC_APB2Periph_GPIOA
+#define X_DIRECTION_BIT   3  
+#define Y_DIRECTION_BIT   4  
+#define Z_DIRECTION_BIT   5
+#define DIRECTION_MASK    ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
+
+  // Define stepper driver enable/disable output pin.
+#define STEPPERS_DISABLE_PORT   GPIOA
+#define RCC_STEPPERS_DISABLE_PORT RCC_APB2Periph_GPIOA
+#define STEPPERS_DISABLE_BIT    6  
+#define STEPPERS_DISABLE_MASK   (1<<STEPPERS_DISABLE_BIT)
+#define SetStepperDisableBit() GPIO_SetBits(STEPPERS_DISABLE_PORT,STEPPERS_DISABLE_MASK)
+#define ResetStepperDisableBit() GPIO_ResetBits(STEPPERS_DISABLE_PORT,STEPPERS_DISABLE_MASK)
+
+
+  // Define homing/hard limit switch input pins and limit interrupt vectors. 
+  // NOTE: All limit bit pins must be on the same port
+#define LIMIT_PIN        GPIOB
+#define LIMIT_PORT       GPIOB
+#define RCC_LIMIT_PORT   RCC_APB2Periph_GPIOB
+#define GPIO_LIMIT_PORT  GPIO_PortSourceGPIOB
+#define X_LIMIT_BIT      10  
+#define Y_LIMIT_BIT      11  
+#define Z_LIMIT_BIT      12  
+
+#define LIMIT_MASK       ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
+
+  // Define spindle enable and spindle direction output pins.
+#define SPINDLE_ENABLE_PORT   GPIOB
+#define RCC_SPINDLE_ENABLE_PORT RCC_APB2Periph_GPIOB
+#define SPINDLE_ENABLE_BIT    0  // 
+#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#define SPINDLE_DIRECTION_DDR   GPIOB
+#define SPINDLE_DIRECTION_PORT  GPIOB
+#define SPINDLE_DIRECTION_BIT   1  // 
+#endif
+#define SetSpindleEnablebit()       GPIO_WriteBit(SPINDLE_ENABLE_PORT, 1 << SPINDLE_ENABLE_BIT, Bit_SET)
+#define ResetSpindleEnablebit()     GPIO_WriteBit(SPINDLE_ENABLE_PORT, 1 << SPINDLE_ENABLE_BIT, Bit_RESET)
+#define SetSpindleDirectionBit()    GPIO_WriteBit(SPINDLE_DIRECTION_PORT, 1 << SPINDLE_DIRECTION_BIT,Bit_SET)
+#define ResetSpindleDirectionBit()  GPIO_WriteBit(SPINDLE_DIRECTION_PORT, 1 << SPINDLE_DIRECTION_BIT,Bit_RESET)
+
+
+  // Define flood and mist coolant enable output pins.
+  // a later date if flash and memory space allows.
+#define COOLANT_FLOOD_PORT            GPIOB
+#define RCC_COOLANT_FLOOD_PORT        RCC_APB2Periph_GPIOB
+#define COOLANT_FLOOD_BIT             2  
+#define COOLANT_MIST_PORT             GPIOB
+#define RCC_COOLANT_MIST_PORT         RCC_APB2Periph_GPIOB
+#define COOLANT_MIST_BIT              3 
+
+  // Define user-control controls (cycle start, reset, feed hold) input pins.
+  // NOTE: All CONTROLs pins must be on the same port and not on a port with other input pins (limits).
+#define CONTROL_PIN_PORT              GPIOB
+#define CONTROL_PORT                  GPIOB
+#define RCC_CONTROL_PORT              RCC_APB2Periph_GPIOB
+#define GPIO_CONTROL_PORT             GPIO_PortSourceGPIOB
+#define CONTROL_RESET_BIT             5  
+#define CONTROL_FEED_HOLD_BIT         6  
+#define CONTROL_CYCLE_START_BIT       7  
+#define CONTROL_SAFETY_DOOR_BIT       8  
+#define CONTROL_MASK                 ((1<<CONTROL_RESET_BIT)|(1<<CONTROL_FEED_HOLD_BIT)|(1<<CONTROL_CYCLE_START_BIT)|(1<<CONTROL_SAFETY_DOOR_BIT))
+
+  // Define probe switch input pin.
+#define PROBE_PORT                    GPIOA
+#define RCC_PROBE_PORT                RCC_APB2Periph_GPIOA
+#define PROBE_BIT                     15 
+#define PROBE_MASK                    (1<<PROBE_BIT)
+
+  // Start of PWM & Stepper Enabled Spindle
+#ifdef VARIABLE_SPINDLE
+
+  // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
+#define SPINDLE_PWM_FREQUENCY       10000                   // KHz
+#define SPINDLE_PWM_DDR	            GPIOA
+#define SPINDLE_PWM_PORT            GPIOA
+#define RCC_SPINDLE_PWM_PORT        RCC_APB2Periph_GPIOA
+#define SPINDLE_PWM_BIT	            8    
+#endif // End of VARIABLE_SPINDLE
+#define SPINDLE_PWM_MAX_VALUE       (1000000 / SPINDLE_PWM_FREQUENCY)
+#ifndef SPINDLE_PWM_MIN_VALUE
+#define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
+#endif
+#define SPINDLE_PWM_OFF_VALUE     0
+#define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
+
+  //  Port A                                         Port B
+  //   0      X_STEP_BIT                            SPINDLE_ENABLE_BIT 
+  //   1      Y_STEP_BIT                            SPINDLE_DIRECTION_BIT
+  //   2      Z_STEP_BIT                            COOLANT_FLOOD_BIT   
+  //   3      X_DIRECTION_BIT                       COOLANT_MIST_BIT
+  //   4      Y_DIRECTION_BIT                       
+  //   5      Z_DIRECTION_BIT                       CONTROL_RESET_BIT
+  //   6      STEPPERS_DISABLE_BIT                  CONTROL_FEED_HOLD_BIT    
+  //   7                                            CONTROL_CYCLE_START_BIT
+  //   8      SPINDLE_PWM_BIT                       CONTROL_SAFETY_DOOR_BIT    
+  //   9                             
+  //   10                                            X_LIMIT_BIT
+  //   11                                            Y_LIMIT_BIT
+  //   12                                            Z_LIMIT_BIT
+  //   13 14 SWD
+  //   15     PROBE_BIT
+
+#endif
+/*
+#ifdef CPU_MAP_CUSTOM_PROC
+  // For a custom pin map or different processor, copy and edit one of the available cpu
+  // map files and modify it to your needs. Make sure the defined name is also changed in
+  // the config.h file.
+#endif
+*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/defaults.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,527 @@
+/*
+  defaults.h - defaults settings configuration file
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The defaults.h file serves as a central default settings selector for different machine
+   types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings
+   files listed here are supplied by users, so your results may vary. However, this should
+   give you a good starting point as you get to know your machine and tweak the settings for
+   your nefarious needs.
+   NOTE: Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */
+
+#ifndef defaults_h
+
+#ifdef DEFAULTS_GENERIC
+  // Grbl generic default settings. Should work across different machines.
+  #define DEFAULT_X_STEPS_PER_MM 250.0f
+  #define DEFAULT_Y_STEPS_PER_MM 250.0f
+  #define DEFAULT_Z_STEPS_PER_MM 250.0f
+  #define DEFAULT_X_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_Y_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_X_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0f // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0f // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01f // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002f // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0f // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0f // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0f // mm
+#endif
+
+#ifdef DEFAULTS_SHERLINE_5400
+  // Description: Sherline 5400 mill with three NEMA 23 Keling  KL23H256-21-8B 185 oz-in stepper motors,
+  // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding.
+  #define MICROSTEPS 2
+  #define STEPS_PER_REV 200.0
+  #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm)
+  #define DEFAULT_Y_MAX_RATE 635.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 635.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 2800.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // true
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 50.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 635.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+#ifdef DEFAULTS_POCKETNC_FR4
+	// Description: Pocket NC FR4 CNC mill.
+#define DEFAULT_X_STEPS_PER_MM 800.0
+#define DEFAULT_Y_STEPS_PER_MM 800.0
+#define DEFAULT_Z_STEPS_PER_MM 800.0
+#define DEFAULT_X_MAX_RATE 300.0 // mm/min
+#define DEFAULT_Y_MAX_RATE 300.0 // mm/min
+#define DEFAULT_Z_MAX_RATE 300.0 // mm/min
+#define DEFAULT_X_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_Y_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_Z_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_SPINDLE_RPM_MAX 7000.0 // rpm
+#define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+#define DEFAULT_STEP_PULSE_MICROSECONDS 10
+#define DEFAULT_STEPPING_INVERT_MASK 0
+#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+#define DEFAULT_STEPPER_IDLE_LOCK_TIME 250 // msec (0-254, 255 keeps steppers enabled)
+#define DEFAULT_STATUS_REPORT_MASK 3 // WPos enabled
+#define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+#define DEFAULT_ARC_TOLERANCE 0.002 // mm
+#define DEFAULT_REPORT_INCHES 0 // false
+#define DEFAULT_INVERT_ST_ENABLE 1 // false
+#define DEFAULT_INVERT_LIMIT_PINS 0 // false
+#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+#define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+#define DEFAULT_INVERT_PROBE_PIN 0 // false
+#define DEFAULT_LASER_MODE 0 // false
+#define DEFAULT_HOMING_ENABLE 1  // false
+#define DEFAULT_HOMING_DIR_MASK 1 // move positive dir
+#define DEFAULT_HOMING_FEED_RATE 100.0 // mm/min
+#define DEFAULT_HOMING_SEEK_RATE 300.0 // mm/min
+#define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+#define DEFAULT_HOMING_PULLOFF 3.0 // mm
+#endif
+#ifdef DEFAULTS_SHAPEOKO
+  // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos
+  // grblShield with a 24V, 4.2A power supply.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 400
+  #define MM_PER_REV_XY (0.08*18*MM_PER_INCH) // 0.08 in belt pitch, 18 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 400
+  #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SHAPEOKO_2
+  // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos
+  // grblShield at 28V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SHAPEOKO_3
+  // Description: Shapeoko CNC mill with three NEMA 23 stepper motors, driven by CarbideMotion
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 8
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 425.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 465.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.01 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 100.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 1000.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 25 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 5.0 // mm
+#endif
+
+#ifdef DEFAULTS_X_CARVE_500MM
+  // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos
+  // grblShield at 24V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 3 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 750.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_X_CARVE_1000MM
+  // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos
+  // grblShield at 24V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 740.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 790.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 3 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 750.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_ZEN_TOOLWORKS_7x7
+  // Description: Zen Toolworks 7x7 mill with three Shinano SST43D2121 65oz-in NEMA 17 stepper motors.
+  // Leadscrew is different from some ZTW kits, where most are 1.25mm/rev rather than 8.0mm/rev here.
+  // Driven by 30V, 6A power supply and TI DRV8811 stepper motor drivers.
+  #define MICROSTEPS 8
+  #define STEPS_PER_REV 200.0
+  #define MM_PER_REV 8.0 // 8 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_X_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 190.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 180.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 150.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_OXCNC
+  // Grbl settings for OpenBuilds OX CNC Machine
+  // http://www.openbuilds.com/builds/openbuilds-ox-cnc-machine.341/
+  #define DEFAULT_X_STEPS_PER_MM 26.670
+  #define DEFAULT_Y_STEPS_PER_MM 26.670
+  #define DEFAULT_Z_STEPS_PER_MM 50
+  #define DEFAULT_X_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 500.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 750.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SIMULATOR
+  // Settings only for Grbl Simulator (www.github.com/grbl/grbl-sim)
+  // Grbl generic default settings. Should work across different machines.
+  #define DEFAULT_X_STEPS_PER_MM 1000.0
+  #define DEFAULT_Y_STEPS_PER_MM 1000.0
+  #define DEFAULT_Z_STEPS_PER_MM 1000.0
+  #define DEFAULT_X_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULT_CNC3020
+#define DEFAULT_X_STEPS_PER_MM 400.0f
+#define DEFAULT_Y_STEPS_PER_MM 400.0f
+#define DEFAULT_Z_STEPS_PER_MM 400.0f
+#define DEFAULT_X_MAX_RATE 600.0f // mm/min
+#define DEFAULT_Y_MAX_RATE 600.0f // mm/min
+#define DEFAULT_Z_MAX_RATE 600.0f // mm/min
+#define DEFAULT_X_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_Y_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_Z_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_X_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_Y_MAX_TRAVEL 300.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_Z_MAX_TRAVEL 50.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_SPINDLE_RPM_MAX 100.0f // rpm
+#define DEFAULT_SPINDLE_RPM_MIN 0.0f // rpm
+#define DEFAULT_STEP_PULSE_MICROSECONDS 10
+#define DEFAULT_STEPPING_INVERT_MASK 7
+#define DEFAULT_DIRECTION_INVERT_MASK 7
+#define DEFAULT_STEPPER_IDLE_LOCK_TIME 0 // msec (0-254, 255 keeps steppers enabled)
+#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+#define DEFAULT_JUNCTION_DEVIATION 0.01f // mm
+#define DEFAULT_ARC_TOLERANCE 0.002f // mm
+#define DEFAULT_REPORT_INCHES 0 // false
+#define DEFAULT_INVERT_ST_ENABLE 0 // false
+#define DEFAULT_INVERT_LIMIT_PINS 0 // false
+#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+#define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+#define DEFAULT_INVERT_PROBE_PIN 0 // false
+#define DEFAULT_LASER_MODE 0 // false
+#define DEFAULT_HOMING_ENABLE 1  // false
+#define DEFAULT_HOMING_DIR_MASK 3 // move positive dir
+#define DEFAULT_HOMING_FEED_RATE 25.0f // mm/min
+#define DEFAULT_HOMING_SEEK_RATE 500.0f // mm/min
+#define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+#define DEFAULT_HOMING_PULLOFF 1.5f // mm
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/defaults.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,527 @@
+/*
+  defaults.h - defaults settings configuration file
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The defaults.h file serves as a central default settings selector for different machine
+   types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings
+   files listed here are supplied by users, so your results may vary. However, this should
+   give you a good starting point as you get to know your machine and tweak the settings for
+   your nefarious needs.
+   NOTE: Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */
+
+#ifndef defaults_h
+
+#ifdef DEFAULTS_GENERIC
+  // Grbl generic default settings. Should work across different machines.
+  #define DEFAULT_X_STEPS_PER_MM 250.0f
+  #define DEFAULT_Y_STEPS_PER_MM 250.0f
+  #define DEFAULT_Z_STEPS_PER_MM 250.0f
+  #define DEFAULT_X_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_Y_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0f // mm/min
+  #define DEFAULT_X_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (10.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0f // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0f // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01f // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002f // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0f // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0f // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0f // mm
+#endif
+
+#ifdef DEFAULTS_SHERLINE_5400
+  // Description: Sherline 5400 mill with three NEMA 23 Keling  KL23H256-21-8B 185 oz-in stepper motors,
+  // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding.
+  #define MICROSTEPS 2
+  #define STEPS_PER_REV 200.0
+  #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm)
+  #define DEFAULT_Y_MAX_RATE 635.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 635.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 2800.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // true
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 50.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 635.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+#ifdef DEFAULTS_POCKETNC_FR4
+	// Description: Pocket NC FR4 CNC mill.
+#define DEFAULT_X_STEPS_PER_MM 800.0
+#define DEFAULT_Y_STEPS_PER_MM 800.0
+#define DEFAULT_Z_STEPS_PER_MM 800.0
+#define DEFAULT_X_MAX_RATE 300.0 // mm/min
+#define DEFAULT_Y_MAX_RATE 300.0 // mm/min
+#define DEFAULT_Z_MAX_RATE 300.0 // mm/min
+#define DEFAULT_X_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_Y_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_Z_ACCELERATION (30.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+#define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value.
+#define DEFAULT_SPINDLE_RPM_MAX 7000.0 // rpm
+#define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+#define DEFAULT_STEP_PULSE_MICROSECONDS 10
+#define DEFAULT_STEPPING_INVERT_MASK 0
+#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+#define DEFAULT_STEPPER_IDLE_LOCK_TIME 250 // msec (0-254, 255 keeps steppers enabled)
+#define DEFAULT_STATUS_REPORT_MASK 3 // WPos enabled
+#define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+#define DEFAULT_ARC_TOLERANCE 0.002 // mm
+#define DEFAULT_REPORT_INCHES 0 // false
+#define DEFAULT_INVERT_ST_ENABLE 1 // false
+#define DEFAULT_INVERT_LIMIT_PINS 0 // false
+#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+#define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+#define DEFAULT_INVERT_PROBE_PIN 0 // false
+#define DEFAULT_LASER_MODE 0 // false
+#define DEFAULT_HOMING_ENABLE 1  // false
+#define DEFAULT_HOMING_DIR_MASK 1 // move positive dir
+#define DEFAULT_HOMING_FEED_RATE 100.0 // mm/min
+#define DEFAULT_HOMING_SEEK_RATE 300.0 // mm/min
+#define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+#define DEFAULT_HOMING_PULLOFF 3.0 // mm
+#endif
+#ifdef DEFAULTS_SHAPEOKO
+  // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos
+  // grblShield with a 24V, 4.2A power supply.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 400
+  #define MM_PER_REV_XY (0.08*18*MM_PER_INCH) // 0.08 in belt pitch, 18 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 400
+  #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SHAPEOKO_2
+  // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos
+  // grblShield at 28V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SHAPEOKO_3
+  // Description: Shapeoko CNC mill with three NEMA 23 stepper motors, driven by CarbideMotion
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 8
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 5000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 425.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 465.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.01 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 100.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 1000.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 25 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 5.0 // mm
+#endif
+
+#ifdef DEFAULTS_X_CARVE_500MM
+  // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos
+  // grblShield at 24V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 3 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 750.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_X_CARVE_1000MM
+  // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos
+  // grblShield at 24V.
+  #define MICROSTEPS_XY 8
+  #define STEP_REVS_XY 200
+  #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
+  #define MICROSTEPS_Z 2
+  #define STEP_REVS_Z 200
+  #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
+  #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
+  #define DEFAULT_X_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 740.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 790.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 3 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 750.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_ZEN_TOOLWORKS_7x7
+  // Description: Zen Toolworks 7x7 mill with three Shinano SST43D2121 65oz-in NEMA 17 stepper motors.
+  // Leadscrew is different from some ZTW kits, where most are 1.25mm/rev rather than 8.0mm/rev here.
+  // Driven by 30V, 6A power supply and TI DRV8811 stepper motor drivers.
+  #define MICROSTEPS 8
+  #define STEPS_PER_REV 200.0
+  #define MM_PER_REV 8.0 // 8 mm/rev leadscrew
+  #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV)
+  #define DEFAULT_X_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 6000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 190.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 180.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 150.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 10000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS))
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 250.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_OXCNC
+  // Grbl settings for OpenBuilds OX CNC Machine
+  // http://www.openbuilds.com/builds/openbuilds-ox-cnc-machine.341/
+  #define DEFAULT_X_STEPS_PER_MM 26.670
+  #define DEFAULT_Y_STEPS_PER_MM 26.670
+  #define DEFAULT_Z_STEPS_PER_MM 50
+  #define DEFAULT_X_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 500.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 500.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 750.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULTS_SIMULATOR
+  // Settings only for Grbl Simulator (www.github.com/grbl/grbl-sim)
+  // Grbl generic default settings. Should work across different machines.
+  #define DEFAULT_X_STEPS_PER_MM 1000.0
+  #define DEFAULT_Y_STEPS_PER_MM 1000.0
+  #define DEFAULT_Z_STEPS_PER_MM 1000.0
+  #define DEFAULT_X_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min
+  #define DEFAULT_X_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Y_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_Z_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+  #define DEFAULT_X_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Y_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_Z_MAX_TRAVEL 1000.0 // mm NOTE: Must be a positive value.
+  #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm
+  #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
+  #define DEFAULT_STEP_PULSE_MICROSECONDS 10
+  #define DEFAULT_STEPPING_INVERT_MASK 0
+  #define DEFAULT_DIRECTION_INVERT_MASK 0
+  #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
+  #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+  #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
+  #define DEFAULT_ARC_TOLERANCE 0.002 // mm
+  #define DEFAULT_REPORT_INCHES 0 // false
+  #define DEFAULT_INVERT_ST_ENABLE 0 // false
+  #define DEFAULT_INVERT_LIMIT_PINS 0 // false
+  #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+  #define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+  #define DEFAULT_INVERT_PROBE_PIN 0 // false
+  #define DEFAULT_LASER_MODE 0 // false
+  #define DEFAULT_HOMING_ENABLE 0  // false
+  #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+  #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min
+  #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min
+  #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+  #define DEFAULT_HOMING_PULLOFF 1.0 // mm
+#endif
+
+#ifdef DEFAULT_CNC3020
+#define DEFAULT_X_STEPS_PER_MM 400.0f
+#define DEFAULT_Y_STEPS_PER_MM 400.0f
+#define DEFAULT_Z_STEPS_PER_MM 400.0f
+#define DEFAULT_X_MAX_RATE 600.0f // mm/min
+#define DEFAULT_Y_MAX_RATE 600.0f // mm/min
+#define DEFAULT_Z_MAX_RATE 600.0f // mm/min
+#define DEFAULT_X_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_Y_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_Z_ACCELERATION (45.0f*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
+#define DEFAULT_X_MAX_TRAVEL 200.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_Y_MAX_TRAVEL 300.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_Z_MAX_TRAVEL 50.0f // mm NOTE: Must be a positive value.
+#define DEFAULT_SPINDLE_RPM_MAX 1000.0f // rpm
+#define DEFAULT_SPINDLE_RPM_MIN 0.0f // rpm
+#define DEFAULT_STEP_PULSE_MICROSECONDS 10
+#define DEFAULT_STEPPING_INVERT_MASK 7
+#define DEFAULT_DIRECTION_INVERT_MASK 7
+#define DEFAULT_STEPPER_IDLE_LOCK_TIME 0 // msec (0-254, 255 keeps steppers enabled)
+#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
+#define DEFAULT_JUNCTION_DEVIATION 0.01f // mm
+#define DEFAULT_ARC_TOLERANCE 0.002f // mm
+#define DEFAULT_REPORT_INCHES 0 // false
+#define DEFAULT_INVERT_ST_ENABLE 0 // false
+#define DEFAULT_INVERT_LIMIT_PINS 0 // false
+#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
+#define DEFAULT_HARD_LIMIT_ENABLE 0  // false
+#define DEFAULT_INVERT_PROBE_PIN 0 // false
+#define DEFAULT_LASER_MODE 0 // false
+#define DEFAULT_HOMING_ENABLE 0  // false
+#define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
+#define DEFAULT_HOMING_FEED_RATE 25.0f // mm/min
+#define DEFAULT_HOMING_SEEK_RATE 500.0f // mm/min
+#define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k)
+#define DEFAULT_HOMING_PULLOFF 1.0f // mm
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/eeprom.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,271 @@
+// This file has been prepared for Doxygen automatic documentation generation.
+/*! \file ********************************************************************
+*
+* Atmel Corporation
+*
+* \li File:               eeprom.c
+* \li Compiler:           IAR EWAAVR 3.10c
+* \li Support mail:       avr@atmel.com
+*
+* \li Supported devices:  All devices with split EEPROM erase/write
+*                         capabilities can be used.
+*                         The example is written for ATmega48.
+*
+* \li AppNote:            AVR103 - Using the EEPROM Programming Modes.
+*
+* \li Description:        Example on how to use the split EEPROM erase/write
+*                         capabilities in e.g. ATmega48. All EEPROM
+*                         programming modes are tested, i.e. Erase+Write,
+*                         Erase-only and Write-only.
+*
+*                         $Revision: 1.6 $
+*                         $Date: Friday, February 11, 2005 07:16:44 UTC $
+****************************************************************************/
+#include "grbl.h"
+#ifdef AVRTARGET
+#include <avr/io.h>
+#include <avr/interrupt.h>
+/* These EEPROM bits have different names on different devices. */
+#ifndef EEPE
+		#define EEPE  EEWE  //!< EEPROM program/write enable.
+		#define EEMPE EEMWE //!< EEPROM master program/write enable.
+#endif
+
+/* These two are unfortunately not defined in the device include files. */
+#define EEPM1 5 //!< EEPROM Programming Mode Bit 1.
+#define EEPM0 4 //!< EEPROM Programming Mode Bit 0.
+
+/* Define to reduce code size. */
+#define EEPROM_IGNORE_SELFPROG //!< Remove SPM flag polling.
+#endif
+#ifdef WIN32
+#include <stdio.h>
+#include <string.h>
+#endif
+#ifdef STM32F103C8
+#include <string.h>
+#include "stm32eeprom.h"
+#include "settings.h"
+#endif
+#if defined(WIN32) || defined (STM32F103C8)
+unsigned char EE_Buffer[0x400];
+#endif
+#if defined(WIN32)
+#ifndef NOEEPROMSUPPORT
+void eeprom_flush()
+{
+	FILE *out = fopen("eeprom.bin", "wb");
+	fwrite(EE_Buffer, 1, 0x400, out);
+	fclose(out);
+}
+#endif
+void eeprom_init()
+{
+#ifndef NOEEPROMSUPPORT
+	FILE *in = fopen("eeprom.bin", "rb");
+	if (in != NULL)
+	{
+		fread(EE_Buffer, 1, 0x400, in);
+		fclose(in);
+	}
+	else
+	{
+		memset(EE_Buffer, 0xff, 0x400);
+	}
+#else
+	memset(EE_Buffer, 0x0, 0x400);
+#endif
+}
+#endif
+
+#ifdef STM32F103C8
+#ifndef NOEEPROMSUPPORT
+void eeprom_flush()
+{
+	uint32_t nAddress = EEPROM_START_ADDRESS;
+	uint16_t *pBuffer = (uint16_t *)EE_Buffer;
+	uint16_t nSize = PAGE_SIZE;
+
+	FLASH_Status FlashStatus = FLASH_COMPLETE;
+
+	/* Erase Page0 */
+	FlashStatus = FLASH_ErasePage(EEPROM_START_ADDRESS);
+
+	/* If erase operation was failed, a Flash error code is returned */
+	if (FlashStatus != FLASH_COMPLETE)
+	{
+		return;
+	}
+
+	while (nSize > 0)
+	{
+		if (*pBuffer != 0xffff)
+		{
+			FLASH_ProgramHalfWord(nAddress, *pBuffer++);
+		}
+		else
+		{
+			pBuffer++;
+		}
+		if (*pBuffer != 0xffff)
+		{
+			FLASH_ProgramHalfWord(nAddress + 2, *pBuffer++);
+		}
+		else
+		{
+			pBuffer++;
+		}
+		nSize -= 4;
+		nAddress += 4;
+	}
+}
+void eeprom_init()
+{
+	uint16_t VarIdx = 0;
+	uint8_t *pTmp = EE_Buffer;
+
+	for (VarIdx = 0; VarIdx < PAGE_SIZE; VarIdx++)
+	{
+		*pTmp++ = (*(__IO uint8_t*)(EEPROM_START_ADDRESS + VarIdx));
+	}
+
+	if (EE_Buffer[0] != SETTINGS_VERSION)
+	{
+		pTmp = EE_Buffer;
+
+		for (VarIdx = 0; VarIdx < PAGE_SIZE; VarIdx++)
+		{
+			*pTmp++ = 0xFF;
+		}
+	}
+}
+#endif
+#endif
+
+/*! \brief  Read byte from EEPROM.
+ *
+ *  This function reads one byte from a given EEPROM address.
+ *
+ *  \note  The CPU is halted for 4 clock cycles during EEPROM read.
+ *
+ *  \param  addr  EEPROM address to read from.
+ *  \return  The byte read from the EEPROM address.
+ */
+unsigned char eeprom_get_char( unsigned int addr )
+{
+#ifdef AVRTARGET
+	do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write.
+	EEAR = addr; // Set EEPROM address register.
+	EECR = (1<<EERE); // Start EEPROM read operation.
+	return EEDR; // Return the byte read from EEPROM.
+#endif
+#if defined(WIN32) || defined(STM32F103C8)
+	return EE_Buffer[addr];
+#endif
+}
+
+/*! \brief  Write byte to EEPROM.
+ *
+ *  This function writes one byte to a given EEPROM address.
+ *  The differences between the existing byte and the new value is used
+ *  to select the most efficient EEPROM programming mode.
+ *
+ *  \note  The CPU is halted for 2 clock cycles during EEPROM programming.
+ *
+ *  \note  When this function returns, the new EEPROM value is not available
+ *         until the EEPROM programming time has passed. The EEPE bit in EECR
+ *         should be polled to check whether the programming is finished.
+ *
+ *  \note  The EEPROM_GetChar() function checks the EEPE bit automatically.
+ *
+ *  \param  addr  EEPROM address to write to.
+ *  \param  new_value  New EEPROM value.
+ */
+void eeprom_put_char( unsigned int addr, unsigned char new_value )
+{
+#ifdef AVRTARGET
+	char old_value; // Old EEPROM value.
+	char diff_mask; // Difference mask, i.e. old value XOR new value.
+
+	cli(); // Ensure atomic operation for the write operation.
+	
+	do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write.
+	#ifndef EEPROM_IGNORE_SELFPROG
+	do {} while( SPMCSR & (1<<SELFPRGEN) ); // Wait for completion of SPM.
+	#endif
+	
+	EEAR = addr; // Set EEPROM address register.
+	EECR = (1<<EERE); // Start EEPROM read operation.
+	old_value = EEDR; // Get old EEPROM value.
+	diff_mask = old_value ^ new_value; // Get bit differences.
+	
+	// Check if any bits are changed to '1' in the new value.
+	if( diff_mask & new_value ) {
+		// Now we know that _some_ bits need to be erased to '1'.
+		
+		// Check if any bits in the new value are '0'.
+		if( new_value != 0xff ) {
+			// Now we know that some bits need to be programmed to '0' also.
+			
+			EEDR = new_value; // Set EEPROM data register.
+			EECR = (1<<EEMPE) | // Set Master Write Enable bit...
+			       (0<<EEPM1) | (0<<EEPM0); // ...and Erase+Write mode.
+			EECR |= (1<<EEPE);  // Start Erase+Write operation.
+		} else {
+			// Now we know that all bits should be erased.
+
+			EECR = (1<<EEMPE) | // Set Master Write Enable bit...
+			       (1<<EEPM0);  // ...and Erase-only mode.
+			EECR |= (1<<EEPE);  // Start Erase-only operation.
+		}
+	} else {
+		// Now we know that _no_ bits need to be erased to '1'.
+		
+		// Check if any bits are changed from '1' in the old value.
+		if( diff_mask ) {
+			// Now we know that _some_ bits need to the programmed to '0'.
+			
+			EEDR = new_value;   // Set EEPROM data register.
+			EECR = (1<<EEMPE) | // Set Master Write Enable bit...
+			       (1<<EEPM1);  // ...and Write-only mode.
+			EECR |= (1<<EEPE);  // Start Write-only operation.
+		}
+	}
+	
+	sei(); // Restore interrupt flag state.
+#endif
+#if defined(WIN32) || defined(STM32F103C8)
+	EE_Buffer[addr] = new_value;
+#endif
+}
+
+// Extensions added as part of Grbl 
+
+
+void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size) {
+  unsigned char checksum = 0;
+  for(; size > 0; size--) { 
+    checksum = (checksum << 1) || (checksum >> 7);
+    checksum += *source;
+    eeprom_put_char(destination++, *(source++)); 
+  }
+  eeprom_put_char(destination, checksum);
+#if defined(WIN32) || defined(STM32F103C8)
+#ifndef NOEEPROMSUPPORT
+  eeprom_flush();
+#endif
+#endif
+}
+
+int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) {
+  unsigned char data, checksum = 0;
+  for(; size > 0; size--) { 
+    data = eeprom_get_char(source++);
+    checksum = (checksum << 1) || (checksum >> 7);
+    checksum += data;    
+    *(destination++) = data; 
+  }
+  return(checksum == eeprom_get_char(source));
+}
+
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/eeprom.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,31 @@
+/*
+  eeprom.h - EEPROM methods
+  Part of Grbl
+
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef eeprom_h
+#define eeprom_h
+#if defined(WIN32) || defined (STM32F103C8)
+void eeprom_init();
+#endif
+unsigned char eeprom_get_char(unsigned int addr);
+void eeprom_put_char(unsigned int addr, unsigned char new_value);
+void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size);
+int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/examples/grblUpload/grblUpload.ino	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,29 @@
+/***********************************************************************
+This sketch compiles and uploads Grbl to your 328p-based Arduino! 
+
+To use:
+- First make sure you have imported Grbl source code into your Arduino
+  IDE. There are details on our Github website on how to do this.
+
+- Select your Arduino Board and Serial Port in the Tools drop-down menu.
+  NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno.
+  Using other boards will likely not work!
+
+- Then just click 'Upload'. That's it!
+
+For advanced users:
+  If you'd like to see what else Grbl can do, there are some additional
+  options for customization and features you can enable or disable. 
+  Navigate your file system to where the Arduino IDE has stored the Grbl 
+  source code files, open the 'config.h' file in your favorite text 
+  editor. Inside are dozens of feature descriptions and #defines. Simply
+  comment or uncomment the #defines or alter their assigned values, save
+  your changes, and then click 'Upload' here. 
+
+Copyright (c) 2015 Sungeun K. Jeon
+Released under the MIT-license. See license.txt for details.
+***********************************************************************/
+
+#include <grbl.h>
+
+// Do not alter this file!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/examples/grblUpload/license.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Sungeun K. Jeon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,109 @@
+/***********************************************************************
+This sketch writes a `$I` build info string directly into Arduino EEPROM
+
+To use:
+- Just alter the "build_info_line" string to whatever you'd like. Then 
+  compile and upload this sketch to your Arduino.
+    
+- If your Arduino is blinking slowly, your string has already been 
+  written to your EEPROM and been verified by checksums! That's it!
+
+- If you Arduino LED is blinking fast, something went wrong and the 
+  checksums don't match. You can optionally connect to the Arduino via
+  the serial monitor, and the sketch will show what its doing.
+
+NOTE: This sketch is provided as a tool template for OEMs who may need
+to restrict users from altering their build info, so they can place
+important product information here when enabling the restriction.
+
+NOTE: When uploading Grbl to the Arduino with this sketch on it, make
+sure you see the slow blink before you start the upload process. This
+ensures you aren't flashing Grbl when it's in mid-write of the EEPROM.
+
+Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
+Released under the MIT-license. See license.txt for details.
+***********************************************************************/
+
+#include <avr/pgmspace.h>
+#include <EEPROM.h>
+
+#define SERIAL_BAUD_RATE 115200
+#define LINE_LENGTH 80U    // Grbl line length
+#define BYTE_LOCATION 942U // Grbl build info EEPROM address.
+
+
+// ----- CHANGE THIS LINE -----
+
+char build_info_line[LINE_LENGTH] = "Testing123.";
+
+// -----------------------------
+
+
+uint8_t status = false;
+int ledPin = 13;                 // LED connected to digital pin 13
+
+void setup() {
+  Serial.begin(SERIAL_BAUD_RATE);
+  delay(500);
+  
+  uint32_t address = BYTE_LOCATION;
+  uint32_t size = LINE_LENGTH;
+  char *write_pointer = (char*)build_info_line;
+  uint8_t write_checksum = 0;
+  for (; size>0; size--) { 
+    write_checksum = (write_checksum << 1) || (write_checksum >> 7);
+    write_checksum += *write_pointer;
+    EEPROM.put(address++, *(write_pointer++)); 
+  }
+  EEPROM.put(address,write_checksum);
+  
+  Serial.print(F("-> Writing line to EEPROM: '"));
+  Serial.print(build_info_line);
+  Serial.print(F("'\n\r-> Write checksum: "));
+  Serial.println(write_checksum,DEC);
+
+  size = LINE_LENGTH;
+  address = BYTE_LOCATION;
+  uint8_t data = 0;
+  char read_line[LINE_LENGTH];
+  char *read_pointer = (char*)read_line;
+  uint8_t read_checksum = 0;
+  uint8_t stored_checksum = 0;
+  for(; size > 0; size--) { 
+    data = EEPROM.read(address++);
+    read_checksum = (read_checksum << 1) || (read_checksum >> 7);
+    read_checksum += data;    
+    *(read_pointer++) = data; 
+  }
+  stored_checksum = EEPROM.read(address);
+
+  Serial.print(F("<- Reading line from EEPROM: '"));
+  Serial.print(read_line);
+  Serial.print("'\n\r<- Read checksum: ");
+  Serial.println(read_checksum,DEC);
+  
+  if ((read_checksum == write_checksum) && (read_checksum == stored_checksum)) {
+    status = true;
+    Serial.print(F("SUCCESS! All checksums match!\r\n"));
+  } else {
+    if (write_checksum != stored_checksum) {
+      Serial.println(F("ERROR! Write and stored EEPROM checksums don't match!"));
+    } else {
+      Serial.println(F("ERROR! Read and stored checksums don't match!"));
+    }
+  }
+  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
+}
+
+void loop() {
+  // Blink to let user know EEPROM write status. 
+  // Slow blink is 'ok'. Fast blink is an 'error'.
+  digitalWrite(ledPin, HIGH);   // sets the LED on
+  if (status) { delay(1500); } // Slow blink
+  else { delay(100); } // Rapid blink
+  digitalWrite(ledPin, LOW);    // sets the LED off
+  if (status) { delay(1500); }
+  else { delay(100); } 
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/examples/grblWrite_BuildInfo/license.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/gcode.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1165 @@
+/*
+  gcode.c - rs274/ngc parser.
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+// NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an
+// arbitrary value, and some GUIs may require more. So we increased it based on a max safe
+// value when converting a float (7.2 digit precision)s to an integer.
+#define MAX_LINE_NUMBER 10000000
+#define MAX_TOOL_NUMBER 255 // Limited by max unsigned 8-bit value
+
+#define AXIS_COMMAND_NONE 0
+#define AXIS_COMMAND_NON_MODAL 1
+#define AXIS_COMMAND_MOTION_MODE 2
+#define AXIS_COMMAND_TOOL_LENGTH_OFFSET 3 // *Undefined but required
+
+// Declare gc extern struct
+parser_state_t gc_state;
+parser_block_t gc_block;
+
+#define FAIL(status) return(status);
+
+
+void gc_init()
+{
+  memset(&gc_state, 0, sizeof(parser_state_t));
+
+  // Load default G54 coordinate system.
+  if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) {
+    report_status_message(STATUS_SETTING_READ_FAIL);
+  }
+}
+
+
+// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard
+// limit pull-off routines.
+void gc_sync_position()
+{
+  system_convert_array_steps_to_mpos(gc_state.position,sys_position);
+}
+
+
+// Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase
+// characters and signed floating point values (no whitespace). Comments and block delete
+// characters have been removed. In this function, all units and positions are converted and
+// exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine
+// coordinates, respectively.
+uint8_t gc_execute_line(char *line)
+{
+  /* -------------------------------------------------------------------------------------
+     STEP 1: Initialize parser block struct and copy current g-code state modes. The parser
+     updates these modes and commands as the block line is parser and will only be used and
+     executed after successful error-checking. The parser block struct also contains a block
+     values struct, word tracking variables, and a non-modal commands tracker for the new
+     block. This struct contains all of the necessary information to execute the block. */
+
+  memset(&gc_block, 0, sizeof(parser_block_t)); // Initialize the parser block struct.
+  memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes
+
+  uint8_t axis_command = AXIS_COMMAND_NONE;
+  uint8_t axis_0, axis_1, axis_linear;
+  uint8_t coord_select = 0; // Tracks G10 P coordinate selection for execution
+
+  // Initialize bitflag tracking variables for axis indices compatible operations.
+  uint8_t axis_words = 0; // XYZ tracking
+  uint8_t ijk_words = 0; // IJK tracking
+
+  // Initialize command and value words and parser flags variables.
+  uint16_t command_words = 0; // Tracks G and M command words. Also used for modal group violations.
+  uint16_t value_words = 0; // Tracks value words.
+  uint8_t gc_parser_flags = GC_PARSER_NONE;
+
+  // Determine if the line is a jogging motion or a normal g-code block.
+  if (line[0] == '$') { // NOTE: `$J=` already parsed when passed to this function.
+						// Set G1 and G94 enforced modes to ensure accurate error checks.
+    gc_parser_flags |= GC_PARSER_JOG_MOTION;
+	gc_block.modal.motion = MOTION_MODE_LINEAR;
+    gc_block.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN;
+#ifdef USE_LINE_NUMBERS
+     gc_block.values.n = JOG_LINE_NUMBER; // Initialize default line number reported during jog.
+#endif
+  }
+
+  /* -------------------------------------------------------------------------------------
+     STEP 2: Import all g-code words in the block line. A g-code word is a letter followed by
+     a number, which can either be a 'G'/'M' command or sets/assigns a command value. Also,
+     perform initial error-checks for command word modal group violations, for any repeated
+     words, and for negative values set for the value words F, N, P, T, and S. */
+
+  uint8_t word_bit; // Bit-value for assigning tracking variables
+  uint8_t char_counter;
+  char letter;
+  float value;
+  uint8_t int_value = 0;
+  uint16_t mantissa = 0;
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) { char_counter = 3; } // Start parsing after `$J=`
+  else { char_counter = 0; }
+
+  while (line[char_counter] != 0) { // Loop until no more g-code words in line.
+
+    // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out.
+    letter = line[char_counter];
+    if((letter < 'A') || (letter > 'Z')) { FAIL(STATUS_EXPECTED_COMMAND_LETTER); } // [Expected word letter]
+    char_counter++;
+    if (!read_float(line, &char_counter, &value)) { FAIL(STATUS_BAD_NUMBER_FORMAT); } // [Expected word value]
+
+    // Convert values to smaller uint8 significand and mantissa values for parsing this word.
+    // NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more
+    // accurate than the NIST gcode requirement of x10 when used for commands, but not quite
+    // accurate enough for value words that require integers to within 0.0001. This should be
+    // a good enough comprimise and catch most all non-integer errors. To make it compliant,
+    // we would simply need to change the mantissa to int16, but this add compiled flash space.
+    // Maybe update this later.
+    int_value = truncf(value);
+	mantissa = (uint16_t)lroundf(100 * (value - int_value)); // Compute mantissa for Gxx.x commands.
+    // NOTE: Rounding must be used to catch small floating point errors.
+
+    // Check if the g-code word is supported or errors due to modal group violations or has
+    // been repeated in the g-code block. If ok, update the command or record its value.
+    switch(letter) {
+
+      /* 'G' and 'M' Command Words: Parse commands and check for modal group violations.
+         NOTE: Modal group numbers are defined in Table 4 of NIST RS274-NGC v3, pg.20 */
+
+      case 'G':
+        // Determine 'G' command and its modal group
+        switch(int_value) {
+          case 10: case 28: case 30: case 92:
+            // Check for G10/28/30/92 being called with G0/1/2/3/38 on same block.
+            // * G43.1 is also an axis command but is not explicitly defined this way.
+            if (mantissa == 0) { // Ignore G28.1, G30.1, and G92.1
+              if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict]
+              axis_command = AXIS_COMMAND_NON_MODAL;
+            }
+            // No break. Continues to next line.
+          case 4: case 53:
+            word_bit = MODAL_GROUP_G0;
+            gc_block.non_modal_command = int_value;
+            if ((int_value == 28) || (int_value == 30) || (int_value == 92)) {
+              if (!((mantissa == 0) || (mantissa == 10))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); }
+              gc_block.non_modal_command += mantissa;
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            }                
+            break;
+          case 0: case 1: case 2: case 3: case 38:
+            // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block.
+            // * G43.1 is also an axis command but is not explicitly defined this way.
+            if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict]
+            axis_command = AXIS_COMMAND_MOTION_MODE;
+            // No break. Continues to next line.
+          case 80:
+            word_bit = MODAL_GROUP_G1;
+            gc_block.modal.motion = int_value;
+            if (int_value == 38){
+              if (!((mantissa == 20) || (mantissa == 30) || (mantissa == 40) || (mantissa == 50))) {
+                FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command]
+              }
+              gc_block.modal.motion += (mantissa/10)+100;
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            }  
+            break;
+          case 17: case 18: case 19:
+            word_bit = MODAL_GROUP_G2;
+            gc_block.modal.plane_select = int_value - 17;
+            break;
+          case 90: case 91:
+            if (mantissa == 0) {
+              word_bit = MODAL_GROUP_G3;
+              gc_block.modal.distance = int_value - 90;
+            } else {
+              word_bit = MODAL_GROUP_G4;
+              if ((mantissa != 10) || (int_value == 90)) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported]
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+              // Otherwise, arc IJK incremental mode is default. G91.1 does nothing.
+            }
+            break;
+          case 93: case 94:
+            word_bit = MODAL_GROUP_G5;
+            gc_block.modal.feed_rate = 94 - int_value;
+            break;
+          case 20: case 21:
+            word_bit = MODAL_GROUP_G6;
+            gc_block.modal.units = 21 - int_value;
+            break;
+          case 40:
+            word_bit = MODAL_GROUP_G7;
+            // NOTE: Not required since cutter radius compensation is always disabled. Only here
+            // to support G40 commands that often appear in g-code program headers to setup defaults.
+            // gc_block.modal.cutter_comp = CUTTER_COMP_DISABLE; // G40
+            break;
+          case 43: case 49:
+            word_bit = MODAL_GROUP_G8;
+            // NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed,
+            // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49
+            // all are explicit axis commands, regardless if they require axis words or not.
+            if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] }
+            axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET;
+            if (int_value == 49) { // G49
+              gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_CANCEL;
+            } else if (mantissa == 10) { // G43.1
+              gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC;
+            } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported G43.x command]
+            mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            break;
+          case 54: case 55: case 56: case 57: case 58: case 59:
+            // NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.)
+            word_bit = MODAL_GROUP_G12;
+            gc_block.modal.coord_select = int_value - 54; // Shift to array indexing.
+            break;
+          case 61:
+            word_bit = MODAL_GROUP_G13;
+            if (mantissa != 0) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G61.1 not supported]
+            // gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61
+            break;
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command]
+        }
+        if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [Unsupported or invalid Gxx.x command]
+        // Check for more than one command per modal group violations in the current block
+        // NOTE: Variable 'word_bit' is always assigned, if the command is valid.
+        if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); }
+        command_words |= bit(word_bit);
+        break;
+
+      case 'M':
+
+        // Determine 'M' command and its modal group
+        if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [No Mxx.x commands]
+        switch(int_value) {
+          case 0: case 1: case 2: case 30:
+            word_bit = MODAL_GROUP_M4;
+            switch(int_value) {
+              case 0: gc_block.modal.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
+              case 1: break; // Optional stop not supported. Ignore.
+              default: gc_block.modal.program_flow = int_value; // Program end and reset
+            }
+            break;
+					case 3: case 4: case 5:
+            word_bit = MODAL_GROUP_M7;
+            switch(int_value) {
+              case 3: gc_block.modal.spindle = SPINDLE_ENABLE_CW; break;
+              case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break;
+              case 5: gc_block.modal.spindle = SPINDLE_DISABLE; break;
+            }
+            break;
+          #ifdef ENABLE_M7
+            case 7: case 8: case 9:
+          #else
+            case 8: case 9:
+          #endif
+            word_bit = MODAL_GROUP_M8;
+            switch(int_value) {
+              #ifdef ENABLE_M7
+                case 7: gc_block.modal.coolant = COOLANT_MIST_ENABLE; break;
+              #endif
+              case 8: gc_block.modal.coolant = COOLANT_FLOOD_ENABLE; break;
+              case 9: gc_block.modal.coolant = COOLANT_DISABLE; break;
+            }
+            break;
+					#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+						case 56:
+							word_bit = MODAL_GROUP_M9;
+							gc_block.modal.override = OVERRIDE_PARKING_MOTION;
+							break;
+					#endif
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported M command]
+        }
+
+        // Check for more than one command per modal group violations in the current block
+        // NOTE: Variable 'word_bit' is always assigned, if the command is valid.
+        if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); }
+        command_words |= bit(word_bit);
+        break;
+
+      // NOTE: All remaining letters assign values.
+      default:
+
+        /* Non-Command Words: This initial parsing phase only checks for repeats of the remaining
+           legal g-code words and stores their value. Error-checking is performed later since some
+           words (I,J,K,L,P,R) have multiple connotations and/or depend on the issued commands. */
+        switch(letter){
+          // case 'A': // Not supported
+          // case 'B': // Not supported
+          // case 'C': // Not supported
+          // case 'D': // Not supported
+          case 'F': word_bit = WORD_F; gc_block.values.f = value; break;
+          // case 'H': // Not supported
+          case 'I': word_bit = WORD_I; gc_block.values.ijk[X_AXIS] = value; ijk_words |= (1<<X_AXIS); break;
+          case 'J': word_bit = WORD_J; gc_block.values.ijk[Y_AXIS] = value; ijk_words |= (1<<Y_AXIS); break;
+          case 'K': word_bit = WORD_K; gc_block.values.ijk[Z_AXIS] = value; ijk_words |= (1<<Z_AXIS); break;
+          case 'L': word_bit = WORD_L; gc_block.values.l = int_value; break;
+          case 'N': word_bit = WORD_N; gc_block.values.n = truncf(value); break;
+          case 'P': word_bit = WORD_P; gc_block.values.p = value; break;
+          // NOTE: For certain commands, P value must be an integer, but none of these commands are supported.
+          // case 'Q': // Not supported
+          case 'R': word_bit = WORD_R; gc_block.values.r = value; break;
+          case 'S': word_bit = WORD_S; gc_block.values.s = value; break;
+		  case 'T': word_bit = WORD_T;
+				if (value > MAX_TOOL_NUMBER) { FAIL(STATUS_GCODE_MAX_VALUE_EXCEEDED); }
+					gc_block.values.t = int_value;
+				break;
+		  case 'X': word_bit = WORD_X; gc_block.values.xyz[X_AXIS] = value; axis_words |= (1<<X_AXIS); break;
+          case 'Y': word_bit = WORD_Y; gc_block.values.xyz[Y_AXIS] = value; axis_words |= (1<<Y_AXIS); break;
+          case 'Z': word_bit = WORD_Z; gc_block.values.xyz[Z_AXIS] = value; axis_words |= (1<<Z_AXIS); break;
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND);
+        }
+
+        // NOTE: Variable 'word_bit' is always assigned, if the non-command letter is valid.
+        if (bit_istrue(value_words,bit(word_bit))) { FAIL(STATUS_GCODE_WORD_REPEATED); } // [Word repeated]
+        // Check for invalid negative values for words F, N, P, T, and S.
+        // NOTE: Negative value check is done here simply for code-efficiency.
+        if ( bit(word_bit) & (bit(WORD_F)|bit(WORD_N)|bit(WORD_P)|bit(WORD_T)|bit(WORD_S)) ) {
+          if (value < 0.0) { FAIL(STATUS_NEGATIVE_VALUE); } // [Word value cannot be negative]
+        }
+        value_words |= bit(word_bit); // Flag to indicate parameter assigned.
+
+    }
+  }
+  // Parsing complete!
+
+
+  /* -------------------------------------------------------------------------------------
+     STEP 3: Error-check all commands and values passed in this block. This step ensures all of
+     the commands are valid for execution and follows the NIST standard as closely as possible.
+     If an error is found, all commands and values in this block are dumped and will not update
+     the active system g-code modes. If the block is ok, the active system g-code modes will be
+     updated based on the commands of this block, and signal for it to be executed.
+
+     Also, we have to pre-convert all of the values passed based on the modes set by the parsed
+     block. There are a number of error-checks that require target information that can only be
+     accurately calculated if we convert these values in conjunction with the error-checking.
+     This relegates the next execution step as only updating the system g-code modes and
+     performing the programmed actions in order. The execution step should not require any
+     conversion calculations and would only require minimal checks necessary to execute.
+  */
+
+  /* NOTE: At this point, the g-code block has been parsed and the block line can be freed.
+     NOTE: It's also possible, at some future point, to break up STEP 2, to allow piece-wise
+     parsing of the block on a per-word basis, rather than the entire block. This could remove
+     the need for maintaining a large string variable for the entire block and free up some memory.
+     To do this, this would simply need to retain all of the data in STEP 1, such as the new block
+     data struct, the modal group and value bitflag tracking variables, and axis array indices
+     compatible variables. This data contains all of the information necessary to error-check the
+     new g-code block when the EOL character is received. However, this would break Grbl's startup
+     lines in how it currently works and would require some refactoring to make it compatible.
+  */
+
+  // [0. Non-specific/common error-checks and miscellaneous setup]:
+
+  // Determine implicit axis command conditions. Axis words have been passed, but no explicit axis
+  // command has been sent. If so, set axis command to current motion mode.
+  if (axis_words) {
+    if (!axis_command) { axis_command = AXIS_COMMAND_MOTION_MODE; } // Assign implicit motion-mode
+  }
+
+  // Check for valid line number N value.
+  if (bit_istrue(value_words,bit(WORD_N))) {
+    // Line number value cannot be less than zero (done) or greater than max line number.
+    if (gc_block.values.n > MAX_LINE_NUMBER) { FAIL(STATUS_GCODE_INVALID_LINE_NUMBER); } // [Exceeds max line number]
+  }
+  // bit_false(value_words,bit(WORD_N)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // Track for unused words at the end of error-checking.
+  // NOTE: Single-meaning value words are removed all at once at the end of error-checking, because
+  // they are always used when present. This was done to save a few bytes of flash. For clarity, the
+  // single-meaning value words may be removed as they are used. Also, axis words are treated in the
+  // same way. If there is an explicit/implicit axis command, XYZ words are always used and are
+  // are removed at the end of error-checking.
+
+  // [1. Comments ]: MSG's NOT SUPPORTED. Comment handling performed by protocol.
+
+  // [2. Set feed rate mode ]: G93 F word missing with G1,G2/3 active, implicitly or explicitly. Feed rate
+  //   is not defined after switching to G94 from G93.
+  // NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+    if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); }
+    if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
+  } else {
+    if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93
+      // NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here.
+      if (axis_command == AXIS_COMMAND_MOTION_MODE) {
+		if ((gc_block.modal.motion != MOTION_MODE_NONE) && (gc_block.modal.motion != MOTION_MODE_SEEK)) {
+          if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing]
+        }
+      }
+      // NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would
+      // accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each
+      // inverse time block, since the commands that use this value already perform undefined checks. This would
+      // also allow other commands, following this switch, to execute and not error out needlessly. This code is
+      // combined with the above feed rate mode and the below set feed rate error-checking.
+
+      // [3. Set feed rate ]: F is negative (done.)
+      // - In inverse time mode: Always implicitly zero the feed rate value before and after block completion.
+      // NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word
+      // value in the block. If no F word is passed with a motion command that requires a feed rate, this will error
+      // out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires
+      // a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined.
+    } else { // = G94
+      // - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value.
+      if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94
+        if (bit_istrue(value_words,bit(WORD_F))) {
+          if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
+        } else {
+          gc_block.values.f = gc_state.feed_rate; // Push last state feed rate
+        }
+      } // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value.
+    }
+  }
+  // bit_false(value_words,bit(WORD_F)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [4. Set spindle speed ]: S is negative (done.)
+  if (bit_isfalse(value_words,bit(WORD_S))) { gc_block.values.s = gc_state.spindle_speed; }
+  // bit_false(value_words,bit(WORD_S)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [5. Select tool ]: NOT SUPPORTED. Only tracks value. T is negative (done.) Not an integer. Greater than max tool value.
+  // bit_false(value_words,bit(WORD_T)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [6. Change tool ]: N/A
+  // [7. Spindle control ]: N/A
+  // [8. Coolant control ]: N/A
+	// [9. Override control ]: Not supported except for a Grbl-only parking motion override control.
+#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+	if (bit_istrue(command_words, bit(MODAL_GROUP_M9))) { // Already set as enabled in parser.
+		if (bit_istrue(value_words, bit(WORD_P))) {
+			if (gc_block.values.p == 0.0f) { gc_block.modal.override = OVERRIDE_DISABLED; }
+			bit_false(value_words, bit(WORD_P));
+		}
+	}
+#endif
+	
+  // [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below.
+  if (gc_block.non_modal_command == NON_MODAL_DWELL) {
+    if (bit_isfalse(value_words,bit(WORD_P))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P word missing]
+    bit_false(value_words,bit(WORD_P));
+  }
+
+  // [11. Set active plane ]: N/A
+  switch (gc_block.modal.plane_select) {
+    case PLANE_SELECT_XY:
+      axis_0 = X_AXIS;
+      axis_1 = Y_AXIS;
+      axis_linear = Z_AXIS;
+      break;
+    case PLANE_SELECT_ZX:
+      axis_0 = Z_AXIS;
+      axis_1 = X_AXIS;
+      axis_linear = Y_AXIS;
+      break;
+    default: // case PLANE_SELECT_YZ:
+      axis_0 = Y_AXIS;
+      axis_1 = Z_AXIS;
+      axis_linear = X_AXIS;
+  }
+
+  // [12. Set length units ]: N/A
+  // Pre-convert XYZ coordinate values to millimeters, if applicable.
+  uint8_t idx;
+  if (gc_block.modal.units == UNITS_MODE_INCHES) {
+    for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+      if (bit_istrue(axis_words,bit(idx)) ) {
+        gc_block.values.xyz[idx] *= MM_PER_INCH;
+      }
+    }
+  }
+
+  // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED. Error, if enabled while G53 is active.
+  // [G40 Errors]: G2/3 arc is programmed after a G40. The linear move after disabling is less than tool diameter.
+  //   NOTE: Since cutter radius compensation is never enabled, these G40 errors don't apply. Grbl supports G40
+  //   only for the purpose to not error when G40 is sent with a g-code program header to setup the default modes.
+
+  // [14. Cutter length compensation ]: G43 NOT SUPPORTED, but G43.1 and G49 are.
+  // [G43.1 Errors]: Motion command in same line.
+  //   NOTE: Although not explicitly stated so, G43.1 should be applied to only one valid
+  //   axis that is configured (in config.h). There should be an error if the configured axis
+  //   is absent or if any of the other axis words are present.
+  if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates called in block.
+    if (gc_block.modal.tool_length == TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC) {
+      if (axis_words ^ (1<<TOOL_LENGTH_OFFSET_AXIS)) { FAIL(STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR); }
+    }
+  }
+
+  // [15. Coordinate system selection ]: *N/A. Error, if cutter radius comp is active.
+  // TODO: An EEPROM read of the coordinate data may require a buffer sync when the cycle
+  // is active. The read pauses the processor temporarily and may cause a rare crash. For
+  // future versions on processors with enough memory, all coordinate data should be stored
+  // in memory and written to EEPROM only when there is not a cycle active.
+  float block_coord_system[N_AXIS];
+  memcpy(block_coord_system,gc_state.coord_system,sizeof(gc_state.coord_system));
+  if ( bit_istrue(command_words,bit(MODAL_GROUP_G12)) ) { // Check if called in block
+    if (gc_block.modal.coord_select > N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys]
+    if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
+      if (!(settings_read_coord_data(gc_block.modal.coord_select,block_coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); }
+    }
+  }
+
+  // [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED.
+  // [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED.
+  // [18. Set retract mode ]: NOT SUPPORTED.
+
+  // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets.
+  // NOTE: We need to separate the non-modal commands that are axis word-using (G10/G28/G30/G92), as these
+  // commands all treat axis words differently. G10 as absolute offsets or computes current position as
+  // the axis value, G92 similarly to G10 L20, and G28/30 as an intermediate target position that observes
+  // all the current coordinate system and G92 offsets.
+  switch (gc_block.non_modal_command) {
+    case NON_MODAL_SET_COORDINATE_DATA:
+      // [G10 Errors]: L missing and is not 2 or 20. P word missing. (Negative P value done.)
+      // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing.
+      // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing.
+      if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS) }; // [No axis words]
+      if (bit_isfalse(value_words,((1<<WORD_P)|(1<<WORD_L)))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P/L word missing]
+      coord_select = truncf(gc_block.values.p); // Convert p value to int.
+      if (coord_select > N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys]
+      if (gc_block.values.l != 20) {
+        if (gc_block.values.l == 2) {
+          if (bit_istrue(value_words,bit(WORD_R))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G10 L2 R not supported]
+        } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported L]
+      }
+      bit_false(value_words,(bit(WORD_L)|bit(WORD_P)));
+
+      // Determine coordinate system to change and try to load from EEPROM.
+      if (coord_select > 0) { coord_select--; } // Adjust P1-P6 index to EEPROM coordinate data indexing.
+      else { coord_select = gc_block.modal.coord_select; } // Index P0 as the active coordinate system
+      
+      // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
+      if (!settings_read_coord_data(coord_select,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); } // [EEPROM read fail]
+
+      // Pre-calculate the coordinate data changes.
+      for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+        // Update axes defined only in block. Always in machine coordinates. Can change non-active system.
+        if (bit_istrue(axis_words,bit(idx)) ) {
+          if (gc_block.values.l == 20) {
+            // L20: Update coordinate system axis at current position (with modifiers) with programmed value
+            // WPos = MPos - WCS - G92 - TLO  ->  WCS = MPos - G92 - TLO - WPos
+            gc_block.values.ijk[idx] = gc_state.position[idx]-gc_state.coord_offset[idx]-gc_block.values.xyz[idx];
+            if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.ijk[idx] -= gc_state.tool_length_offset; }
+          } else {
+            // L2: Update coordinate system axis to programmed value.
+            gc_block.values.ijk[idx] = gc_block.values.xyz[idx];
+          }
+        } // Else, keep current stored value.
+      }
+      break;
+    case NON_MODAL_SET_COORDINATE_OFFSET:
+      // [G92 Errors]: No axis words.
+      if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+
+      // Update axes defined only in block. Offsets current system to defined value. Does not update when
+      // active coordinate system is selected, but is still active unless G92.1 disables it.
+      for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+        if (bit_istrue(axis_words,bit(idx)) ) {
+          // WPos = MPos - WCS - G92 - TLO  ->  G92 = MPos - WCS - TLO - WPos
+          gc_block.values.xyz[idx] = gc_state.position[idx]-block_coord_system[idx]-gc_block.values.xyz[idx];
+          if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] -= gc_state.tool_length_offset; }
+        } else {
+          gc_block.values.xyz[idx] = gc_state.coord_offset[idx];
+        }
+      }
+      break;
+
+    default:
+
+      // At this point, the rest of the explicit axis commands treat the axis values as the traditional
+      // target position with the coordinate system offsets, G92 offsets, absolute override, and distance
+      // modes applied. This includes the motion mode commands. We can now pre-compute the target position.
+      // NOTE: Tool offsets may be appended to these conversions when/if this feature is added.
+      if (axis_command != AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // TLO block any axis command.
+        if (axis_words) {
+          for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used to save flash space.
+            if ( bit_isfalse(axis_words,bit(idx)) ) {
+              gc_block.values.xyz[idx] = gc_state.position[idx]; // No axis word in block. Keep same axis position.
+            } else {
+              // Update specified value according to distance mode or ignore if absolute override is active.
+              // NOTE: G53 is never active with G28/30 since they are in the same modal group.
+              if (gc_block.non_modal_command != NON_MODAL_ABSOLUTE_OVERRIDE) {
+                // Apply coordinate offsets based on distance mode.
+                if (gc_block.modal.distance == DISTANCE_MODE_ABSOLUTE) {
+                  gc_block.values.xyz[idx] += block_coord_system[idx] + gc_state.coord_offset[idx];
+                  if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] += gc_state.tool_length_offset; }
+                } else {  // Incremental mode
+                  gc_block.values.xyz[idx] += gc_state.position[idx];
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // Check remaining non-modal commands for errors.
+      switch (gc_block.non_modal_command) {
+        case NON_MODAL_GO_HOME_0: // G28
+        case NON_MODAL_GO_HOME_1: // G30
+          // [G28/30 Errors]: Cutter compensation is enabled.
+          // Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
+          // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
+          if (gc_block.non_modal_command == NON_MODAL_GO_HOME_0) {
+            if (!settings_read_coord_data(SETTING_INDEX_G28,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); }
+          } else { // == NON_MODAL_GO_HOME_1
+            if (!settings_read_coord_data(SETTING_INDEX_G30,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); }
+          }
+          if (axis_words) {
+            // Move only the axes specified in secondary move.
+            for (idx=0; idx<N_AXIS; idx++) {
+              if (!(axis_words & (1<<idx))) { gc_block.values.ijk[idx] = gc_state.position[idx]; }
+            }
+          } else {
+            axis_command = AXIS_COMMAND_NONE; // Set to none if no intermediate motion.
+          }
+          break;
+        case NON_MODAL_SET_HOME_0: // G28.1
+        case NON_MODAL_SET_HOME_1: // G30.1
+          // [G28.1/30.1 Errors]: Cutter compensation is enabled.
+          // NOTE: If axis words are passed here, they are interpreted as an implicit motion mode.
+          break;
+        case NON_MODAL_RESET_COORDINATE_OFFSET:
+          // NOTE: If axis words are passed here, they are interpreted as an implicit motion mode.
+          break;
+        case NON_MODAL_ABSOLUTE_OVERRIDE:
+          // [G53 Errors]: G0 and G1 are not active. Cutter compensation is enabled.
+          // NOTE: All explicit axis word commands are in this modal group. So no implicit check necessary.
+          if (!(gc_block.modal.motion == MOTION_MODE_SEEK || gc_block.modal.motion == MOTION_MODE_LINEAR)) {
+            FAIL(STATUS_GCODE_G53_INVALID_MOTION_MODE); // [G53 G0/1 not active]
+          }
+          break;
+      }
+  }
+
+  // [20. Motion modes ]:
+  if (gc_block.modal.motion == MOTION_MODE_NONE) {
+    // [G80 Errors]: Axis word are programmed while G80 is active.
+    // NOTE: Even non-modal commands or TLO that use axis words will throw this strict error.
+    if (axis_words) { FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); } // [No axis words allowed]
+
+  // Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or
+  // was explicitly commanded in the g-code block.
+  } else if ( axis_command == AXIS_COMMAND_MOTION_MODE ) {
+
+    if (gc_block.modal.motion == MOTION_MODE_SEEK) {
+      // [G0 Errors]: Axis letter not configured or without real value (done.)
+      // Axis words are optional. If missing, set axis command flag to ignore execution.
+      if (!axis_words) { axis_command = AXIS_COMMAND_NONE; }
+
+    // All remaining motion modes (all but G0 and G80), require a valid feed rate value. In units per mm mode,
+    // the value must be positive. In inverse time mode, a positive value must be passed with each block.
+    } else {
+      // Check if feed rate is defined for the motion modes that require it.
+      if (gc_block.values.f == 0.0f) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [Feed rate undefined]
+
+      switch (gc_block.modal.motion) {
+        case MOTION_MODE_LINEAR:
+          // [G1 Errors]: Feed rate undefined. Axis letter not configured or without real value.
+          // Axis words are optional. If missing, set axis command flag to ignore execution.
+          if (!axis_words) { axis_command = AXIS_COMMAND_NONE; }
+
+          break;
+        case MOTION_MODE_CW_ARC: 
+          gc_parser_flags |= GC_PARSER_ARC_IS_CLOCKWISE; // No break intentional.
+        case MOTION_MODE_CCW_ARC:
+          // [G2/3 Errors All-Modes]: Feed rate undefined.
+          // [G2/3 Radius-Mode Errors]: No axis words in selected plane. Target point is same as current.
+          // [G2/3 Offset-Mode Errors]: No axis words and/or offsets in selected plane. The radius to the current
+          //   point and the radius to the target point differs more than 0.002mm (EMC def. 0.5mm OR 0.005mm and 0.1% radius).
+          // [G2/3 Full-Circle-Mode Errors]: NOT SUPPORTED. Axis words exist. No offsets programmed. P must be an integer.
+          // NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking.
+
+          if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+          if (!(axis_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE); } // [No axis words in plane]
+
+          // Calculate the change in position along each selected axis
+          float x,y;
+          x = gc_block.values.xyz[axis_0]-gc_state.position[axis_0]; // Delta x between current position and target
+          y = gc_block.values.xyz[axis_1]-gc_state.position[axis_1]; // Delta y between current position and target
+
+          if (value_words & bit(WORD_R)) { // Arc Radius Mode
+            bit_false(value_words,bit(WORD_R));
+            if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
+
+            // Convert radius value to proper units.
+            if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.r *= MM_PER_INCH; }
+            /*  We need to calculate the center of the circle that has the designated radius and passes
+                through both the current position and the target position. This method calculates the following
+                set of equations where [x,y] is the vector from current to target position, d == magnitude of
+                that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to
+                the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the
+                length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point
+                [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc.
+
+                d^2 == x^2 + y^2
+                h^2 == r^2 - (d/2)^2
+                i == x/2 - y/d*h
+                j == y/2 + x/d*h
+
+                                                                     O <- [i,j]
+                                                                  -  |
+                                                        r      -     |
+                                                            -        |
+                                                         -           | h
+                                                      -              |
+                                        [0,0] ->  C -----------------+--------------- T  <- [x,y]
+                                                  | <------ d/2 ---->|
+
+                C - Current position
+                T - Target position
+                O - center of circle that pass through both C and T
+                d - distance from C to T
+                r - designated radius
+                h - distance from center of CT to O
+
+                Expanding the equations:
+
+                d -> sqrt(x^2 + y^2)
+                h -> sqrt(4 * r^2 - x^2 - y^2)/2
+                i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2
+                j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2
+
+                Which can be written:
+
+                i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
+                j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
+
+                Which we for size and speed reasons optimize to:
+
+                h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2)
+                i = (x - (y * h_x2_div_d))/2
+                j = (y + (x * h_x2_div_d))/2
+            */
+
+            // First, use h_x2_div_d to compute 4*h^2 to check if it is negative or r is smaller
+            // than d. If so, the sqrt of a negative number is complex and error out.
+            float h_x2_div_d = 4.0f * gc_block.values.r*gc_block.values.r - x*x - y*y;
+
+            if (h_x2_div_d < 0) { FAIL(STATUS_GCODE_ARC_RADIUS_ERROR); } // [Arc radius error]
+
+            // Finish computing h_x2_div_d.
+            h_x2_div_d = -sqrtf(h_x2_div_d)/hypot_f(x,y); // == -(h * 2 / d)
+            // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below)
+            if (gc_block.modal.motion == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; }
+
+            /* The counter clockwise circle lies to the left of the target direction. When offset is positive,
+               the left hand circle will be generated - when it is negative the right hand circle is generated.
+
+                                                                   T  <-- Target position
+
+                                                                   ^
+                        Clockwise circles with this center         |          Clockwise circles with this center will have
+                        will have > 180 deg of angular travel      |          < 180 deg of angular travel, which is a good thing!
+                                                         \         |          /
+            center of arc when h_x2_div_d is positive ->  x <----- | -----> x <- center of arc when h_x2_div_d is negative
+                                                                   |
+                                                                   |
+
+                                                                   C  <-- Current position
+            */
+            // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!),
+            // even though it is advised against ever generating such circles in a single line of g-code. By
+            // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of
+            // travel and thus we get the unadvisably long arcs as prescribed.
+            if (gc_block.values.r < 0) {
+                h_x2_div_d = -h_x2_div_d;
+                gc_block.values.r = -gc_block.values.r; // Finished with r. Set to positive for mc_arc
+            }
+            // Complete the operation by calculating the actual center of the arc
+            gc_block.values.ijk[axis_0] = 0.5f*(x-(y*h_x2_div_d));
+            gc_block.values.ijk[axis_1] = 0.5f*(y+(x*h_x2_div_d));
+
+          } else { // Arc Center Format Offset Mode
+            if (!(ijk_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_OFFSETS_IN_PLANE); } // [No offsets in plane]
+            bit_false(value_words,(bit(WORD_I)|bit(WORD_J)|bit(WORD_K)));
+
+            // Convert IJK values to proper units.
+            if (gc_block.modal.units == UNITS_MODE_INCHES) {
+              for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used to save flash space.
+                if (ijk_words & bit(idx)) { gc_block.values.ijk[idx] *= MM_PER_INCH; }
+              }
+            }
+
+            // Arc radius from center to target
+            x -= gc_block.values.ijk[axis_0]; // Delta x between circle center and target
+            y -= gc_block.values.ijk[axis_1]; // Delta y between circle center and target
+            float target_r = hypot_f(x,y);
+
+            // Compute arc radius for mc_arc. Defined from current location to center.
+            gc_block.values.r = hypot_f(gc_block.values.ijk[axis_0], gc_block.values.ijk[axis_1]);
+
+            // Compute difference between current location and target radii for final error-checks.
+            float delta_r = fabsf(target_r-gc_block.values.r);
+            if (delta_r > 0.005f) {
+              if (delta_r > 0.5f) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.5mm
+              if (delta_r > (0.001f*gc_block.values.r)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.005mm AND 0.1% radius
+            }
+          }
+          break;
+        case MOTION_MODE_PROBE_TOWARD_NO_ERROR: case MOTION_MODE_PROBE_AWAY_NO_ERROR:
+            gc_parser_flags |= GC_PARSER_PROBE_IS_NO_ERROR; // No break intentional.
+        case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_AWAY:
+            if ((gc_block.modal.motion == MOTION_MODE_PROBE_AWAY) ||
+                (gc_block.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { gc_parser_flags |= GC_PARSER_PROBE_IS_AWAY; }
+          // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate
+          //   is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning
+          //   an error, it issues an alarm to prevent further motion to the probe. It's also done there to
+          //   allow the planner buffer to empty and move off the probe trigger before another probing cycle.
+          if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+          if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
+          break;
+      }
+    }
+  }
+
+  // [21. Program flow ]: No error checks required.
+
+  // [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc
+  // radius mode, or axis words that aren't used in the block.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+      // Jogging only uses the F feed rate and XYZ value words. N is valid, but S and T are invalid.
+      bit_false(value_words, (bit(WORD_N) | bit(WORD_F)));
+  } else {
+      bit_false(value_words, (bit(WORD_N) | bit(WORD_F) | bit(WORD_S) | bit(WORD_T))); // Remove single-meaning value words.
+  }
+  if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words.
+  if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words]
+
+  /* -------------------------------------------------------------------------------------
+     STEP 4: EXECUTE!!
+     Assumes that all error-checking has been completed and no failure modes exist. We just
+     need to update the state and execute the block according to the order-of-execution.
+  */
+
+  // Initialize planner data struct for motion blocks.
+  plan_line_data_t plan_data;
+  plan_line_data_t *pl_data = &plan_data;
+  memset(pl_data,0,sizeof(plan_line_data_t)); // Zero pl_data struct
+
+                                              // Intercept jog commands and complete error checking for valid jog commands and execute.
+                                              // NOTE: G-code parser state is not updated, except the position to ensure sequential jog
+                                              // targets are computed correctly. The final parser position after a jog is updated in
+                                              // protocol_execute_realtime() when jogging completes or is canceled.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+      // Only distance and unit modal commands and G53 absolute override command are allowed.
+      // NOTE: Feed rate word and axis word checks have already been performed in STEP 3.
+      if (command_words & ~(bit(MODAL_GROUP_G3) | bit(MODAL_GROUP_G6 | bit(MODAL_GROUP_G0)))) { FAIL(STATUS_INVALID_JOG_COMMAND) };
+      if (!(gc_block.non_modal_command == NON_MODAL_ABSOLUTE_OVERRIDE || gc_block.non_modal_command == NON_MODAL_NO_ACTION)) { FAIL(STATUS_INVALID_JOG_COMMAND); }
+
+      // Initialize planner data to current spindle and coolant modal state.
+      pl_data->spindle_speed = gc_state.spindle_speed;
+      plan_data.condition = (gc_state.modal.spindle | gc_state.modal.coolant);
+
+      uint8_t status = jog_execute(&plan_data, &gc_block);
+      if (status == STATUS_OK) { memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); }
+      return(status);
+  }
+
+  // If in laser mode, setup laser power based on current and past parser conditions.
+  if (bit_istrue(settings.flags, BITFLAG_LASER_MODE)) {
+      if (!((gc_block.modal.motion == MOTION_MODE_LINEAR) || (gc_block.modal.motion == MOTION_MODE_CW_ARC)
+          || (gc_block.modal.motion == MOTION_MODE_CCW_ARC))) {
+          gc_parser_flags |= GC_PARSER_LASER_DISABLE;
+      }
+
+      // Any motion mode with axis words is allowed to be passed from a spindle speed update. 
+      // NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted.
+      // TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length).
+      if (axis_words && (axis_command == AXIS_COMMAND_MOTION_MODE)) {
+        gc_parser_flags |= GC_PARSER_LASER_ISMOTION;
+      }
+      else {
+        // M3 constant power laser requires planner syncs to update the laser when changing between
+        // a G1/2/3 motion mode state and vice versa when there is no motion in the line.
+        if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) {
+          if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC)
+            || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
+            if (bit_istrue(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+              gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode.
+            }
+          }
+          else {
+            // When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode.
+            if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+              gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC;
+            }
+          }
+        }
+      }
+  }
+
+  // [0. Non-specific/common error-checks and miscellaneous setup]:
+  // NOTE: If no line number is present, the value is zero.
+  gc_state.line_number = gc_block.values.n;
+  #ifdef USE_LINE_NUMBERS
+    pl_data->line_number = gc_state.line_number; // Record data for planner use.
+  #endif
+
+  // [1. Comments feedback ]:  NOT SUPPORTED
+
+  // [2. Set feed rate mode ]:
+  gc_state.modal.feed_rate = gc_block.modal.feed_rate;
+  if (gc_state.modal.feed_rate) { pl_data->condition |= PL_COND_FLAG_INVERSE_TIME; } // Set condition flag for planner use.
+
+  // [3. Set feed rate ]:
+  gc_state.feed_rate = gc_block.values.f; // Always copy this value. See feed rate error-checking.
+  pl_data->feed_rate = gc_state.feed_rate; // Record data for planner use.
+
+  // [4. Set spindle speed ]:
+  if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags, GC_PARSER_LASER_FORCE_SYNC)) {
+      if (gc_state.modal.spindle != SPINDLE_DISABLE) {
+#ifdef VARIABLE_SPINDLE
+        if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_ISMOTION)) {
+          if (bit_istrue(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+            spindle_sync(gc_state.modal.spindle, 0.0);
+          }
+          else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); }
+        }
+#else
+          spindle_sync(gc_state.modal.spindle, 0.0);
+#endif
+      }
+      gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state.
+  }
+  // NOTE: Pass zero spindle speed for all restricted laser motions.
+  if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+      pl_data->spindle_speed = gc_state.spindle_speed; // Record data for planner use. 
+  } // else { pl_data->spindle_speed = 0.0; } // Initialized as zero already.
+
+  // [5. Select tool ]: NOT SUPPORTED. Only tracks tool value.
+  gc_state.tool = gc_block.values.t;
+
+  // [6. Change tool ]: NOT SUPPORTED
+
+  // [7. Spindle control ]:
+  if (gc_state.modal.spindle != gc_block.modal.spindle) {
+    // Update spindle control and apply spindle speed when enabling it in this block.
+    // NOTE: All spindle state changes are synced, even in laser mode. Also, pl_data,
+    // rather than gc_state, is used to manage laser state for non-laser motions.
+    spindle_sync(gc_block.modal.spindle, pl_data->spindle_speed);
+    gc_state.modal.spindle = gc_block.modal.spindle;
+  }
+  pl_data->condition |= gc_state.modal.spindle; // Set condition flag for planner use.
+
+  // [8. Coolant control ]:
+  if (gc_state.modal.coolant != gc_block.modal.coolant) {
+    // NOTE: Coolant M-codes are modal. Only one command per line is allowed. But, multiple states
+    // can exist at the same time, while coolant disable clears all states.
+    coolant_sync(gc_block.modal.coolant);
+    if (gc_block.modal.coolant == COOLANT_DISABLE) { gc_state.modal.coolant = COOLANT_DISABLE; }
+    else { gc_state.modal.coolant |= gc_block.modal.coolant; }
+  }
+  pl_data->condition |= gc_state.modal.coolant; // Set condition flag for planner use.
+
+	// [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control.
+#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+	if (gc_state.modal.override != gc_block.modal.override) {
+		gc_state.modal.override = gc_block.modal.override;
+		mc_override_ctrl_update(gc_state.modal.override);
+	}
+#endif
+
+  // [10. Dwell ]:
+  if (gc_block.non_modal_command == NON_MODAL_DWELL) { mc_dwell(gc_block.values.p); }
+
+  // [11. Set active plane ]:
+  gc_state.modal.plane_select = gc_block.modal.plane_select;
+
+  // [12. Set length units ]:
+  gc_state.modal.units = gc_block.modal.units;
+
+  // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED
+  // gc_state.modal.cutter_comp = gc_block.modal.cutter_comp; // NOTE: Not needed since always disabled.
+
+  // [14. Cutter length compensation ]: G43.1 and G49 supported. G43 NOT SUPPORTED.
+  // NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms
+  // of execution. The error-checking step would simply load the offset value into the correct
+  // axis of the block XYZ value array.
+  if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates a change.
+    gc_state.modal.tool_length = gc_block.modal.tool_length;
+    if (gc_state.modal.tool_length == TOOL_LENGTH_OFFSET_CANCEL) { // G49
+      gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] = 0.0f;
+    } // else G43.1
+    if ( gc_state.tool_length_offset != gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] ) {
+      gc_state.tool_length_offset = gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS];
+      system_flag_wco_change();
+    }
+  }
+
+  // [15. Coordinate system selection ]:
+  if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
+    gc_state.modal.coord_select = gc_block.modal.coord_select;
+    memcpy(gc_state.coord_system,block_coord_system,N_AXIS*sizeof(float));
+    system_flag_wco_change();
+  }
+
+  // [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED
+  // gc_state.modal.control = gc_block.modal.control; // NOTE: Always default.
+
+  // [17. Set distance mode ]:
+  gc_state.modal.distance = gc_block.modal.distance;
+
+  // [18. Set retract mode ]: NOT SUPPORTED
+
+  // [19. Go to predefined position, Set G10, or Set axis offsets ]:
+  switch(gc_block.non_modal_command) {
+    case NON_MODAL_SET_COORDINATE_DATA:
+      settings_write_coord_data(coord_select,gc_block.values.ijk);
+      // Update system coordinate system if currently active.
+      if (gc_state.modal.coord_select == coord_select) {
+        memcpy(gc_state.coord_system,gc_block.values.ijk,N_AXIS*sizeof(float));
+        system_flag_wco_change();
+      }
+      break;
+    case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1:
+      // Move to intermediate position before going home. Obeys current coordinate system and offsets
+      // and absolute and incremental modes.
+      pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
+      if (axis_command) { mc_line(gc_block.values.xyz, pl_data); }
+      mc_line(gc_block.values.ijk, pl_data);
+      memcpy(gc_state.position, gc_block.values.ijk, N_AXIS*sizeof(float));
+      break;
+    case NON_MODAL_SET_HOME_0:
+      settings_write_coord_data(SETTING_INDEX_G28,gc_state.position);
+      break;
+    case NON_MODAL_SET_HOME_1:
+      settings_write_coord_data(SETTING_INDEX_G30,gc_state.position);
+      break;
+    case NON_MODAL_SET_COORDINATE_OFFSET:
+      memcpy(gc_state.coord_offset,gc_block.values.xyz,sizeof(gc_block.values.xyz));
+      system_flag_wco_change();
+      break;
+    case NON_MODAL_RESET_COORDINATE_OFFSET:
+      clear_vector(gc_state.coord_offset); // Disable G92 offsets by zeroing offset vector.
+      system_flag_wco_change();
+      break;
+  }
+
+
+  // [20. Motion modes ]:
+  // NOTE: Commands G10,G28,G30,G92 lock out and prevent axis words from use in motion modes.
+  // Enter motion modes only if there are axis words or a motion mode command word in the block.
+  gc_state.modal.motion = gc_block.modal.motion;
+  if (gc_state.modal.motion != MOTION_MODE_NONE) {
+    if (axis_command == AXIS_COMMAND_MOTION_MODE) {
+      uint8_t gc_update_pos = GC_UPDATE_POS_TARGET;
+      if (gc_state.modal.motion == MOTION_MODE_LINEAR) {
+        mc_line(gc_block.values.xyz, pl_data);
+      } else if (gc_state.modal.motion == MOTION_MODE_SEEK) {
+        pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
+        mc_line(gc_block.values.xyz, pl_data);
+      } else if ((gc_state.modal.motion == MOTION_MODE_CW_ARC) || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
+          mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
+              axis_0, axis_1, axis_linear, bit_istrue(gc_parser_flags, GC_PARSER_ARC_IS_CLOCKWISE));
+      } else {
+        // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So
+        // upon a successful probing cycle, the machine position and the returned value should be the same.
+        #ifndef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES
+          pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE;
+        #endif
+        gc_update_pos = mc_probe_cycle(gc_block.values.xyz, pl_data, gc_parser_flags);
+    }  
+     
+      // As far as the parser is concerned, the position is now == target. In reality the
+      // motion control system might still be processing the action and the real tool position
+      // in any intermediate location.
+      if (gc_update_pos == GC_UPDATE_POS_TARGET) {
+        memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[]
+      } else if (gc_update_pos == GC_UPDATE_POS_SYSTEM) {
+        gc_sync_position(); // gc_state.position[] = sys_position
+      } // == GC_UPDATE_POS_NONE
+    }     
+
+  }
+
+  // [21. Program flow ]:
+  // M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may
+  // refill and can only be resumed by the cycle start run-time command.
+  gc_state.modal.program_flow = gc_block.modal.program_flow;
+  if (gc_state.modal.program_flow) {
+    protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
+    if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) {
+      if (sys.state != STATE_CHECK_MODE) {
+        system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause.
+        protocol_execute_realtime(); // Execute suspend.
+      }
+    } else { // == PROGRAM_FLOW_COMPLETED
+      // Upon program complete, only a subset of g-codes reset to certain defaults, according to
+      // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12]
+      // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups
+      // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset.
+      gc_state.modal.motion = MOTION_MODE_LINEAR;
+      gc_state.modal.plane_select = PLANE_SELECT_XY;
+      gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE;
+      gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN;
+      // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported.
+      gc_state.modal.coord_select = 0; // G54
+      gc_state.modal.spindle = SPINDLE_DISABLE;
+      gc_state.modal.coolant = COOLANT_DISABLE;
+			#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+				#ifdef DEACTIVATE_PARKING_UPON_INIT
+					gc_state.modal.override = OVERRIDE_DISABLED;
+				#else
+					gc_state.modal.override = OVERRIDE_PARKING_MOTION;
+				#endif
+			#endif
+
+      #ifdef RESTORE_OVERRIDES_AFTER_PROGRAM_END
+        sys.f_override = DEFAULT_FEED_OVERRIDE;
+        sys.r_override = DEFAULT_RAPID_OVERRIDE;
+        sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE;
+      #endif
+
+      // Execute coordinate change and spindle/coolant stop.
+      if (sys.state != STATE_CHECK_MODE) {
+        if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); }
+        system_flag_wco_change(); // Set to refresh immediately just in case something altered.
+        spindle_set_state(SPINDLE_DISABLE,0.0f);
+        coolant_set_state(COOLANT_DISABLE);
+      }
+      report_feedback_message(MESSAGE_PROGRAM_END);
+    }
+    gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow.
+  }
+
+  // TODO: % to denote start of program.
+
+  return(STATUS_OK);
+}
+
+
+/*
+  Not supported:
+
+  - Canned cycles
+  - Tool radius compensation
+  - A,B,C-axes
+  - Evaluation of expressions
+  - Variables
+  - Override control (TBD)
+  - Tool changes
+  - Switches
+
+   (*) Indicates optional parameter, enabled through config.h and re-compile
+   group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets)
+   group 1 = {G81 - G89} (Motion modes: Canned cycles)
+   group 4 = {M1} (Optional stop, ignored)
+   group 6 = {M6} (Tool change)
+   group 7 = {G41, G42} cutter radius compensation (G40 is supported)
+   group 8 = {G43} tool length offset (G43.1/G49 are supported)
+   group 8 = {M7*} enable mist coolant (* Compile-option)
+	 group 9 = {M48, M49, M56*} enable/disable override switches (* Compile-option)
+	 group 10 = {G98, G99} return mode canned cycles
+   group 13 = {G61.1, G64} path control mode (G61 is supported)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/gcode.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1165 @@
+/*
+  gcode.c - rs274/ngc parser.
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+// NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an
+// arbitrary value, and some GUIs may require more. So we increased it based on a max safe
+// value when converting a float (7.2 digit precision)s to an integer.
+#define MAX_LINE_NUMBER 10000000
+#define MAX_TOOL_NUMBER 255 // Limited by max unsigned 8-bit value
+
+#define AXIS_COMMAND_NONE 0
+#define AXIS_COMMAND_NON_MODAL 1
+#define AXIS_COMMAND_MOTION_MODE 2
+#define AXIS_COMMAND_TOOL_LENGTH_OFFSET 3 // *Undefined but required
+
+// Declare gc extern struct
+parser_state_t gc_state;
+parser_block_t gc_block;
+
+#define FAIL(status) return(status);
+
+
+void gc_init()
+{
+  memset(&gc_state, 0, sizeof(parser_state_t));
+
+  // Load default G54 coordinate system.
+  if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) {
+    report_status_message(STATUS_SETTING_READ_FAIL);
+  }
+}
+
+
+// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard
+// limit pull-off routines.
+void gc_sync_position()
+{
+  system_convert_array_steps_to_mpos(gc_state.position,sys_position);
+}
+
+
+// Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase
+// characters and signed floating point values (no whitespace). Comments and block delete
+// characters have been removed. In this function, all units and positions are converted and
+// exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine
+// coordinates, respectively.
+uint8_t gc_execute_line(char *line)
+{
+  /* -------------------------------------------------------------------------------------
+     STEP 1: Initialize parser block struct and copy current g-code state modes. The parser
+     updates these modes and commands as the block line is parser and will only be used and
+     executed after successful error-checking. The parser block struct also contains a block
+     values struct, word tracking variables, and a non-modal commands tracker for the new
+     block. This struct contains all of the necessary information to execute the block. */
+
+  memset(&gc_block, 0, sizeof(parser_block_t)); // Initialize the parser block struct.
+  memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes
+
+  uint8_t axis_command = AXIS_COMMAND_NONE;
+  uint8_t axis_0, axis_1, axis_linear;
+  uint8_t coord_select = 0; // Tracks G10 P coordinate selection for execution
+
+  // Initialize bitflag tracking variables for axis indices compatible operations.
+  uint8_t axis_words = 0; // XYZ tracking
+  uint8_t ijk_words = 0; // IJK tracking
+
+  // Initialize command and value words and parser flags variables.
+  uint16_t command_words = 0; // Tracks G and M command words. Also used for modal group violations.
+  uint16_t value_words = 0; // Tracks value words.
+  uint8_t gc_parser_flags = GC_PARSER_NONE;
+
+  // Determine if the line is a jogging motion or a normal g-code block.
+  if (line[0] == '$') { // NOTE: `$J=` already parsed when passed to this function.
+						// Set G1 and G94 enforced modes to ensure accurate error checks.
+    gc_parser_flags |= GC_PARSER_JOG_MOTION;
+	gc_block.modal.motion = MOTION_MODE_LINEAR;
+    gc_block.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN;
+#ifdef USE_LINE_NUMBERS
+     gc_block.values.n = JOG_LINE_NUMBER; // Initialize default line number reported during jog.
+#endif
+  }
+
+  /* -------------------------------------------------------------------------------------
+     STEP 2: Import all g-code words in the block line. A g-code word is a letter followed by
+     a number, which can either be a 'G'/'M' command or sets/assigns a command value. Also,
+     perform initial error-checks for command word modal group violations, for any repeated
+     words, and for negative values set for the value words F, N, P, T, and S. */
+
+  uint8_t word_bit; // Bit-value for assigning tracking variables
+  uint8_t char_counter;
+  char letter;
+  float value;
+  uint8_t int_value = 0;
+  uint16_t mantissa = 0;
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) { char_counter = 3; } // Start parsing after `$J=`
+  else { char_counter = 0; }
+
+  while (line[char_counter] != 0) { // Loop until no more g-code words in line.
+
+    // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out.
+    letter = line[char_counter];
+    if((letter < 'A') || (letter > 'Z')) { FAIL(STATUS_EXPECTED_COMMAND_LETTER); } // [Expected word letter]
+    char_counter++;
+    if (!read_float(line, &char_counter, &value)) { FAIL(STATUS_BAD_NUMBER_FORMAT); } // [Expected word value]
+
+    // Convert values to smaller uint8 significand and mantissa values for parsing this word.
+    // NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more
+    // accurate than the NIST gcode requirement of x10 when used for commands, but not quite
+    // accurate enough for value words that require integers to within 0.0001. This should be
+    // a good enough comprimise and catch most all non-integer errors. To make it compliant,
+    // we would simply need to change the mantissa to int16, but this add compiled flash space.
+    // Maybe update this later.
+    int_value = truncf(value);
+	mantissa = (uint16_t)lroundf(100 * (value - int_value)); // Compute mantissa for Gxx.x commands.
+    // NOTE: Rounding must be used to catch small floating point errors.
+
+    // Check if the g-code word is supported or errors due to modal group violations or has
+    // been repeated in the g-code block. If ok, update the command or record its value.
+    switch(letter) {
+
+      /* 'G' and 'M' Command Words: Parse commands and check for modal group violations.
+         NOTE: Modal group numbers are defined in Table 4 of NIST RS274-NGC v3, pg.20 */
+
+      case 'G':
+        // Determine 'G' command and its modal group
+        switch(int_value) {
+          case 10: case 28: case 30: case 92:
+            // Check for G10/28/30/92 being called with G0/1/2/3/38 on same block.
+            // * G43.1 is also an axis command but is not explicitly defined this way.
+            if (mantissa == 0) { // Ignore G28.1, G30.1, and G92.1
+              if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict]
+              axis_command = AXIS_COMMAND_NON_MODAL;
+            }
+            // No break. Continues to next line.
+          case 4: case 53:
+            word_bit = MODAL_GROUP_G0;
+            gc_block.non_modal_command = int_value;
+            if ((int_value == 28) || (int_value == 30) || (int_value == 92)) {
+              if (!((mantissa == 0) || (mantissa == 10))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); }
+              gc_block.non_modal_command += mantissa;
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            }                
+            break;
+          case 0: case 1: case 2: case 3: case 38:
+            // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block.
+            // * G43.1 is also an axis command but is not explicitly defined this way.
+            if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict]
+            axis_command = AXIS_COMMAND_MOTION_MODE;
+            // No break. Continues to next line.
+          case 80:
+            word_bit = MODAL_GROUP_G1;
+            gc_block.modal.motion = int_value;
+            if (int_value == 38){
+              if (!((mantissa == 20) || (mantissa == 30) || (mantissa == 40) || (mantissa == 50))) {
+                FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command]
+              }
+              gc_block.modal.motion += (mantissa/10)+100;
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            }  
+            break;
+          case 17: case 18: case 19:
+            word_bit = MODAL_GROUP_G2;
+            gc_block.modal.plane_select = int_value - 17;
+            break;
+          case 90: case 91:
+            if (mantissa == 0) {
+              word_bit = MODAL_GROUP_G3;
+              gc_block.modal.distance = int_value - 90;
+            } else {
+              word_bit = MODAL_GROUP_G4;
+              if ((mantissa != 10) || (int_value == 90)) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported]
+              mantissa = 0; // Set to zero to indicate valid non-integer G command.
+              // Otherwise, arc IJK incremental mode is default. G91.1 does nothing.
+            }
+            break;
+          case 93: case 94:
+            word_bit = MODAL_GROUP_G5;
+            gc_block.modal.feed_rate = 94 - int_value;
+            break;
+          case 20: case 21:
+            word_bit = MODAL_GROUP_G6;
+            gc_block.modal.units = 21 - int_value;
+            break;
+          case 40:
+            word_bit = MODAL_GROUP_G7;
+            // NOTE: Not required since cutter radius compensation is always disabled. Only here
+            // to support G40 commands that often appear in g-code program headers to setup defaults.
+            // gc_block.modal.cutter_comp = CUTTER_COMP_DISABLE; // G40
+            break;
+          case 43: case 49:
+            word_bit = MODAL_GROUP_G8;
+            // NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed,
+            // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49
+            // all are explicit axis commands, regardless if they require axis words or not.
+            if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] }
+            axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET;
+            if (int_value == 49) { // G49
+              gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_CANCEL;
+            } else if (mantissa == 10) { // G43.1
+              gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC;
+            } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported G43.x command]
+            mantissa = 0; // Set to zero to indicate valid non-integer G command.
+            break;
+          case 54: case 55: case 56: case 57: case 58: case 59:
+            // NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.)
+            word_bit = MODAL_GROUP_G12;
+            gc_block.modal.coord_select = int_value - 54; // Shift to array indexing.
+            break;
+          case 61:
+            word_bit = MODAL_GROUP_G13;
+            if (mantissa != 0) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G61.1 not supported]
+            // gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61
+            break;
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command]
+        }
+        if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [Unsupported or invalid Gxx.x command]
+        // Check for more than one command per modal group violations in the current block
+        // NOTE: Variable 'word_bit' is always assigned, if the command is valid.
+        if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); }
+        command_words |= bit(word_bit);
+        break;
+
+      case 'M':
+
+        // Determine 'M' command and its modal group
+        if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [No Mxx.x commands]
+        switch(int_value) {
+          case 0: case 1: case 2: case 30:
+            word_bit = MODAL_GROUP_M4;
+            switch(int_value) {
+              case 0: gc_block.modal.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
+              case 1: break; // Optional stop not supported. Ignore.
+              default: gc_block.modal.program_flow = int_value; // Program end and reset
+            }
+            break;
+					case 3: case 4: case 5:
+            word_bit = MODAL_GROUP_M7;
+            switch(int_value) {
+              case 3: gc_block.modal.spindle = SPINDLE_ENABLE_CW; break;
+              case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break;
+              case 5: gc_block.modal.spindle = SPINDLE_DISABLE; break;
+            }
+            break;
+          #ifdef ENABLE_M7
+            case 7: case 8: case 9:
+          #else
+            case 8: case 9:
+          #endif
+            word_bit = MODAL_GROUP_M8;
+            switch(int_value) {
+              #ifdef ENABLE_M7
+                case 7: gc_block.modal.coolant = COOLANT_MIST_ENABLE; break;
+              #endif
+              case 8: gc_block.modal.coolant = COOLANT_FLOOD_ENABLE; break;
+              case 9: gc_block.modal.coolant = COOLANT_DISABLE; break;
+            }
+            break;
+					#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+						case 56:
+							word_bit = MODAL_GROUP_M9;
+							gc_block.modal.override = OVERRIDE_PARKING_MOTION;
+							break;
+					#endif
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported M command]
+        }
+
+        // Check for more than one command per modal group violations in the current block
+        // NOTE: Variable 'word_bit' is always assigned, if the command is valid.
+        if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); }
+        command_words |= bit(word_bit);
+        break;
+
+      // NOTE: All remaining letters assign values.
+      default:
+
+        /* Non-Command Words: This initial parsing phase only checks for repeats of the remaining
+           legal g-code words and stores their value. Error-checking is performed later since some
+           words (I,J,K,L,P,R) have multiple connotations and/or depend on the issued commands. */
+        switch(letter){
+          // case 'A': // Not supported
+          // case 'B': // Not supported
+          // case 'C': // Not supported
+          // case 'D': // Not supported
+          case 'F': word_bit = WORD_F; gc_block.values.f = value; break;
+          // case 'H': // Not supported
+          case 'I': word_bit = WORD_I; gc_block.values.ijk[X_AXIS] = value; ijk_words |= (1<<X_AXIS); break;
+          case 'J': word_bit = WORD_J; gc_block.values.ijk[Y_AXIS] = value; ijk_words |= (1<<Y_AXIS); break;
+          case 'K': word_bit = WORD_K; gc_block.values.ijk[Z_AXIS] = value; ijk_words |= (1<<Z_AXIS); break;
+          case 'L': word_bit = WORD_L; gc_block.values.l = int_value; break;
+          case 'N': word_bit = WORD_N; gc_block.values.n = truncf(value); break;
+          case 'P': word_bit = WORD_P; gc_block.values.p = value; break;
+          // NOTE: For certain commands, P value must be an integer, but none of these commands are supported.
+          // case 'Q': // Not supported
+          case 'R': word_bit = WORD_R; gc_block.values.r = value; break;
+          case 'S': word_bit = WORD_S; gc_block.values.s = value; break;
+          case 'T': word_bit = WORD_T; 
+					  if (value > MAX_TOOL_NUMBER) { FAIL(STATUS_GCODE_MAX_VALUE_EXCEEDED); }
+            gc_block.values.t = int_value;
+						break;
+          case 'X': word_bit = WORD_X; gc_block.values.xyz[X_AXIS] = value; axis_words |= (1<<X_AXIS); break;
+          case 'Y': word_bit = WORD_Y; gc_block.values.xyz[Y_AXIS] = value; axis_words |= (1<<Y_AXIS); break;
+          case 'Z': word_bit = WORD_Z; gc_block.values.xyz[Z_AXIS] = value; axis_words |= (1<<Z_AXIS); break;
+          default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND);
+        }
+
+        // NOTE: Variable 'word_bit' is always assigned, if the non-command letter is valid.
+        if (bit_istrue(value_words,bit(word_bit))) { FAIL(STATUS_GCODE_WORD_REPEATED); } // [Word repeated]
+        // Check for invalid negative values for words F, N, P, T, and S.
+        // NOTE: Negative value check is done here simply for code-efficiency.
+        if ( bit(word_bit) & (bit(WORD_F)|bit(WORD_N)|bit(WORD_P)|bit(WORD_T)|bit(WORD_S)) ) {
+          if (value < 0.0) { FAIL(STATUS_NEGATIVE_VALUE); } // [Word value cannot be negative]
+        }
+        value_words |= bit(word_bit); // Flag to indicate parameter assigned.
+
+    }
+  }
+  // Parsing complete!
+
+
+  /* -------------------------------------------------------------------------------------
+     STEP 3: Error-check all commands and values passed in this block. This step ensures all of
+     the commands are valid for execution and follows the NIST standard as closely as possible.
+     If an error is found, all commands and values in this block are dumped and will not update
+     the active system g-code modes. If the block is ok, the active system g-code modes will be
+     updated based on the commands of this block, and signal for it to be executed.
+
+     Also, we have to pre-convert all of the values passed based on the modes set by the parsed
+     block. There are a number of error-checks that require target information that can only be
+     accurately calculated if we convert these values in conjunction with the error-checking.
+     This relegates the next execution step as only updating the system g-code modes and
+     performing the programmed actions in order. The execution step should not require any
+     conversion calculations and would only require minimal checks necessary to execute.
+  */
+
+  /* NOTE: At this point, the g-code block has been parsed and the block line can be freed.
+     NOTE: It's also possible, at some future point, to break up STEP 2, to allow piece-wise
+     parsing of the block on a per-word basis, rather than the entire block. This could remove
+     the need for maintaining a large string variable for the entire block and free up some memory.
+     To do this, this would simply need to retain all of the data in STEP 1, such as the new block
+     data struct, the modal group and value bitflag tracking variables, and axis array indices
+     compatible variables. This data contains all of the information necessary to error-check the
+     new g-code block when the EOL character is received. However, this would break Grbl's startup
+     lines in how it currently works and would require some refactoring to make it compatible.
+  */
+
+  // [0. Non-specific/common error-checks and miscellaneous setup]:
+
+  // Determine implicit axis command conditions. Axis words have been passed, but no explicit axis
+  // command has been sent. If so, set axis command to current motion mode.
+  if (axis_words) {
+    if (!axis_command) { axis_command = AXIS_COMMAND_MOTION_MODE; } // Assign implicit motion-mode
+  }
+
+  // Check for valid line number N value.
+  if (bit_istrue(value_words,bit(WORD_N))) {
+    // Line number value cannot be less than zero (done) or greater than max line number.
+    if (gc_block.values.n > MAX_LINE_NUMBER) { FAIL(STATUS_GCODE_INVALID_LINE_NUMBER); } // [Exceeds max line number]
+  }
+  // bit_false(value_words,bit(WORD_N)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // Track for unused words at the end of error-checking.
+  // NOTE: Single-meaning value words are removed all at once at the end of error-checking, because
+  // they are always used when present. This was done to save a few bytes of flash. For clarity, the
+  // single-meaning value words may be removed as they are used. Also, axis words are treated in the
+  // same way. If there is an explicit/implicit axis command, XYZ words are always used and are
+  // are removed at the end of error-checking.
+
+  // [1. Comments ]: MSG's NOT SUPPORTED. Comment handling performed by protocol.
+
+  // [2. Set feed rate mode ]: G93 F word missing with G1,G2/3 active, implicitly or explicitly. Feed rate
+  //   is not defined after switching to G94 from G93.
+  // NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+    if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); }
+    if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
+  } else {
+    if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93
+      // NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here.
+      if (axis_command == AXIS_COMMAND_MOTION_MODE) {
+				if ((gc_block.modal.motion != MOTION_MODE_NONE) && (gc_block.modal.motion != MOTION_MODE_SEEK)) {
+					if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing]
+        }
+      }
+      // NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would
+      // accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each
+      // inverse time block, since the commands that use this value already perform undefined checks. This would
+      // also allow other commands, following this switch, to execute and not error out needlessly. This code is
+      // combined with the above feed rate mode and the below set feed rate error-checking.
+
+      // [3. Set feed rate ]: F is negative (done.)
+      // - In inverse time mode: Always implicitly zero the feed rate value before and after block completion.
+      // NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word
+      // value in the block. If no F word is passed with a motion command that requires a feed rate, this will error
+      // out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires
+      // a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined.
+    } else { // = G94
+      // - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value.
+      if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94
+        if (bit_istrue(value_words,bit(WORD_F))) {
+          if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
+        } else {
+          gc_block.values.f = gc_state.feed_rate; // Push last state feed rate
+        }
+      } // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value.
+    }
+  }
+  // bit_false(value_words,bit(WORD_F)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [4. Set spindle speed ]: S is negative (done.)
+  if (bit_isfalse(value_words,bit(WORD_S))) { gc_block.values.s = gc_state.spindle_speed; }
+  // bit_false(value_words,bit(WORD_S)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [5. Select tool ]: NOT SUPPORTED. Only tracks value. T is negative (done.) Not an integer. Greater than max tool value.
+  // bit_false(value_words,bit(WORD_T)); // NOTE: Single-meaning value word. Set at end of error-checking.
+
+  // [6. Change tool ]: N/A
+  // [7. Spindle control ]: N/A
+  // [8. Coolant control ]: N/A
+	// [9. Override control ]: Not supported except for a Grbl-only parking motion override control.
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		if (bit_istrue(command_words, bit(MODAL_GROUP_M9))) { // Already set as enabled in parser.
+			if (bit_istrue(value_words, bit(WORD_P))) {
+				if (gc_block.values.p == 0.0) { gc_block.modal.override = OVERRIDE_DISABLED; }
+				bit_false(value_words, bit(WORD_P));
+			}
+		}
+	#endif
+
+  // [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below.
+  if (gc_block.non_modal_command == NON_MODAL_DWELL) {
+    if (bit_isfalse(value_words,bit(WORD_P))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P word missing]
+    bit_false(value_words,bit(WORD_P));
+  }
+
+  // [11. Set active plane ]: N/A
+  switch (gc_block.modal.plane_select) {
+    case PLANE_SELECT_XY:
+      axis_0 = X_AXIS;
+      axis_1 = Y_AXIS;
+      axis_linear = Z_AXIS;
+      break;
+    case PLANE_SELECT_ZX:
+      axis_0 = Z_AXIS;
+      axis_1 = X_AXIS;
+      axis_linear = Y_AXIS;
+      break;
+    default: // case PLANE_SELECT_YZ:
+      axis_0 = Y_AXIS;
+      axis_1 = Z_AXIS;
+      axis_linear = X_AXIS;
+  }
+
+  // [12. Set length units ]: N/A
+  // Pre-convert XYZ coordinate values to millimeters, if applicable.
+  uint8_t idx;
+  if (gc_block.modal.units == UNITS_MODE_INCHES) {
+    for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+      if (bit_istrue(axis_words,bit(idx)) ) {
+        gc_block.values.xyz[idx] *= MM_PER_INCH;
+      }
+    }
+  }
+
+  // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED. Error, if enabled while G53 is active.
+  // [G40 Errors]: G2/3 arc is programmed after a G40. The linear move after disabling is less than tool diameter.
+  //   NOTE: Since cutter radius compensation is never enabled, these G40 errors don't apply. Grbl supports G40
+  //   only for the purpose to not error when G40 is sent with a g-code program header to setup the default modes.
+
+  // [14. Cutter length compensation ]: G43 NOT SUPPORTED, but G43.1 and G49 are.
+  // [G43.1 Errors]: Motion command in same line.
+  //   NOTE: Although not explicitly stated so, G43.1 should be applied to only one valid
+  //   axis that is configured (in config.h). There should be an error if the configured axis
+  //   is absent or if any of the other axis words are present.
+  if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates called in block.
+    if (gc_block.modal.tool_length == TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC) {
+      if (axis_words ^ (1<<TOOL_LENGTH_OFFSET_AXIS)) { FAIL(STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR); }
+    }
+  }
+
+  // [15. Coordinate system selection ]: *N/A. Error, if cutter radius comp is active.
+  // TODO: An EEPROM read of the coordinate data may require a buffer sync when the cycle
+  // is active. The read pauses the processor temporarily and may cause a rare crash. For
+  // future versions on processors with enough memory, all coordinate data should be stored
+  // in memory and written to EEPROM only when there is not a cycle active.
+  float block_coord_system[N_AXIS];
+  memcpy(block_coord_system,gc_state.coord_system,sizeof(gc_state.coord_system));
+  if ( bit_istrue(command_words,bit(MODAL_GROUP_G12)) ) { // Check if called in block
+    if (gc_block.modal.coord_select > N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys]
+    if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
+      if (!(settings_read_coord_data(gc_block.modal.coord_select,block_coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); }
+    }
+  }
+
+  // [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED.
+  // [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED.
+  // [18. Set retract mode ]: NOT SUPPORTED.
+
+  // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets.
+  // NOTE: We need to separate the non-modal commands that are axis word-using (G10/G28/G30/G92), as these
+  // commands all treat axis words differently. G10 as absolute offsets or computes current position as
+  // the axis value, G92 similarly to G10 L20, and G28/30 as an intermediate target position that observes
+  // all the current coordinate system and G92 offsets.
+  switch (gc_block.non_modal_command) {
+    case NON_MODAL_SET_COORDINATE_DATA:
+      // [G10 Errors]: L missing and is not 2 or 20. P word missing. (Negative P value done.)
+      // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing.
+      // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing.
+      if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS) }; // [No axis words]
+      if (bit_isfalse(value_words,((1<<WORD_P)|(1<<WORD_L)))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P/L word missing]
+      coord_select = truncf(gc_block.values.p); // Convert p value to int.
+      if (coord_select > N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys]
+      if (gc_block.values.l != 20) {
+        if (gc_block.values.l == 2) {
+          if (bit_istrue(value_words,bit(WORD_R))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G10 L2 R not supported]
+        } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported L]
+      }
+      bit_false(value_words,(bit(WORD_L)|bit(WORD_P)));
+
+      // Determine coordinate system to change and try to load from EEPROM.
+      if (coord_select > 0) { coord_select--; } // Adjust P1-P6 index to EEPROM coordinate data indexing.
+      else { coord_select = gc_block.modal.coord_select; } // Index P0 as the active coordinate system
+      
+      // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
+      if (!settings_read_coord_data(coord_select,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); } // [EEPROM read fail]
+
+      // Pre-calculate the coordinate data changes.
+      for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+        // Update axes defined only in block. Always in machine coordinates. Can change non-active system.
+        if (bit_istrue(axis_words,bit(idx)) ) {
+          if (gc_block.values.l == 20) {
+            // L20: Update coordinate system axis at current position (with modifiers) with programmed value
+            // WPos = MPos - WCS - G92 - TLO  ->  WCS = MPos - G92 - TLO - WPos
+            gc_block.values.ijk[idx] = gc_state.position[idx]-gc_state.coord_offset[idx]-gc_block.values.xyz[idx];
+            if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.ijk[idx] -= gc_state.tool_length_offset; }
+          } else {
+            // L2: Update coordinate system axis to programmed value.
+            gc_block.values.ijk[idx] = gc_block.values.xyz[idx];
+          }
+        } // Else, keep current stored value.
+      }
+      break;
+    case NON_MODAL_SET_COORDINATE_OFFSET:
+      // [G92 Errors]: No axis words.
+      if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+
+      // Update axes defined only in block. Offsets current system to defined value. Does not update when
+      // active coordinate system is selected, but is still active unless G92.1 disables it.
+      for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
+        if (bit_istrue(axis_words,bit(idx)) ) {
+          // WPos = MPos - WCS - G92 - TLO  ->  G92 = MPos - WCS - TLO - WPos
+          gc_block.values.xyz[idx] = gc_state.position[idx]-block_coord_system[idx]-gc_block.values.xyz[idx];
+          if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] -= gc_state.tool_length_offset; }
+        } else {
+          gc_block.values.xyz[idx] = gc_state.coord_offset[idx];
+        }
+      }
+      break;
+
+    default:
+
+      // At this point, the rest of the explicit axis commands treat the axis values as the traditional
+      // target position with the coordinate system offsets, G92 offsets, absolute override, and distance
+      // modes applied. This includes the motion mode commands. We can now pre-compute the target position.
+      // NOTE: Tool offsets may be appended to these conversions when/if this feature is added.
+      if (axis_command != AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // TLO block any axis command.
+        if (axis_words) {
+          for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used to save flash space.
+            if ( bit_isfalse(axis_words,bit(idx)) ) {
+              gc_block.values.xyz[idx] = gc_state.position[idx]; // No axis word in block. Keep same axis position.
+            } else {
+              // Update specified value according to distance mode or ignore if absolute override is active.
+              // NOTE: G53 is never active with G28/30 since they are in the same modal group.
+              if (gc_block.non_modal_command != NON_MODAL_ABSOLUTE_OVERRIDE) {
+                // Apply coordinate offsets based on distance mode.
+                if (gc_block.modal.distance == DISTANCE_MODE_ABSOLUTE) {
+                  gc_block.values.xyz[idx] += block_coord_system[idx] + gc_state.coord_offset[idx];
+                  if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] += gc_state.tool_length_offset; }
+                } else {  // Incremental mode
+                  gc_block.values.xyz[idx] += gc_state.position[idx];
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // Check remaining non-modal commands for errors.
+      switch (gc_block.non_modal_command) {
+        case NON_MODAL_GO_HOME_0: // G28
+        case NON_MODAL_GO_HOME_1: // G30
+          // [G28/30 Errors]: Cutter compensation is enabled.
+          // Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
+          // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
+          if (gc_block.non_modal_command == NON_MODAL_GO_HOME_0) {
+            if (!settings_read_coord_data(SETTING_INDEX_G28,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); }
+          } else { // == NON_MODAL_GO_HOME_1
+            if (!settings_read_coord_data(SETTING_INDEX_G30,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); }
+          }
+          if (axis_words) {
+            // Move only the axes specified in secondary move.
+            for (idx=0; idx<N_AXIS; idx++) {
+              if (!(axis_words & (1<<idx))) { gc_block.values.ijk[idx] = gc_state.position[idx]; }
+            }
+          } else {
+            axis_command = AXIS_COMMAND_NONE; // Set to none if no intermediate motion.
+          }
+          break;
+        case NON_MODAL_SET_HOME_0: // G28.1
+        case NON_MODAL_SET_HOME_1: // G30.1
+          // [G28.1/30.1 Errors]: Cutter compensation is enabled.
+          // NOTE: If axis words are passed here, they are interpreted as an implicit motion mode.
+          break;
+        case NON_MODAL_RESET_COORDINATE_OFFSET:
+          // NOTE: If axis words are passed here, they are interpreted as an implicit motion mode.
+          break;
+        case NON_MODAL_ABSOLUTE_OVERRIDE:
+          // [G53 Errors]: G0 and G1 are not active. Cutter compensation is enabled.
+          // NOTE: All explicit axis word commands are in this modal group. So no implicit check necessary.
+          if (!(gc_block.modal.motion == MOTION_MODE_SEEK || gc_block.modal.motion == MOTION_MODE_LINEAR)) {
+            FAIL(STATUS_GCODE_G53_INVALID_MOTION_MODE); // [G53 G0/1 not active]
+          }
+          break;
+      }
+  }
+
+  // [20. Motion modes ]:
+  if (gc_block.modal.motion == MOTION_MODE_NONE) {
+    // [G80 Errors]: Axis word are programmed while G80 is active.
+    // NOTE: Even non-modal commands or TLO that use axis words will throw this strict error.
+    if (axis_words) { FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); } // [No axis words allowed]
+
+  // Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or
+  // was explicitly commanded in the g-code block.
+  } else if ( axis_command == AXIS_COMMAND_MOTION_MODE ) {
+
+    if (gc_block.modal.motion == MOTION_MODE_SEEK) {
+      // [G0 Errors]: Axis letter not configured or without real value (done.)
+      // Axis words are optional. If missing, set axis command flag to ignore execution.
+      if (!axis_words) { axis_command = AXIS_COMMAND_NONE; }
+
+    // All remaining motion modes (all but G0 and G80), require a valid feed rate value. In units per mm mode,
+    // the value must be positive. In inverse time mode, a positive value must be passed with each block.
+    } else {
+      // Check if feed rate is defined for the motion modes that require it.
+      if (gc_block.values.f == 0.0f) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [Feed rate undefined]
+
+      switch (gc_block.modal.motion) {
+        case MOTION_MODE_LINEAR:
+          // [G1 Errors]: Feed rate undefined. Axis letter not configured or without real value.
+          // Axis words are optional. If missing, set axis command flag to ignore execution.
+          if (!axis_words) { axis_command = AXIS_COMMAND_NONE; }
+
+          break;
+        case MOTION_MODE_CW_ARC: 
+          gc_parser_flags |= GC_PARSER_ARC_IS_CLOCKWISE; // No break intentional.
+        case MOTION_MODE_CCW_ARC:
+          // [G2/3 Errors All-Modes]: Feed rate undefined.
+          // [G2/3 Radius-Mode Errors]: No axis words in selected plane. Target point is same as current.
+          // [G2/3 Offset-Mode Errors]: No axis words and/or offsets in selected plane. The radius to the current
+          //   point and the radius to the target point differs more than 0.002mm (EMC def. 0.5mm OR 0.005mm and 0.1% radius).
+          // [G2/3 Full-Circle-Mode Errors]: NOT SUPPORTED. Axis words exist. No offsets programmed. P must be an integer.
+          // NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking.
+
+          if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+          if (!(axis_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE); } // [No axis words in plane]
+
+          // Calculate the change in position along each selected axis
+          float x,y;
+          x = gc_block.values.xyz[axis_0]-gc_state.position[axis_0]; // Delta x between current position and target
+          y = gc_block.values.xyz[axis_1]-gc_state.position[axis_1]; // Delta y between current position and target
+
+          if (value_words & bit(WORD_R)) { // Arc Radius Mode
+            bit_false(value_words,bit(WORD_R));
+            if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
+
+            // Convert radius value to proper units.
+            if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.r *= MM_PER_INCH; }
+            /*  We need to calculate the center of the circle that has the designated radius and passes
+                through both the current position and the target position. This method calculates the following
+                set of equations where [x,y] is the vector from current to target position, d == magnitude of
+                that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to
+                the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the
+                length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point
+                [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc.
+
+                d^2 == x^2 + y^2
+                h^2 == r^2 - (d/2)^2
+                i == x/2 - y/d*h
+                j == y/2 + x/d*h
+
+                                                                     O <- [i,j]
+                                                                  -  |
+                                                        r      -     |
+                                                            -        |
+                                                         -           | h
+                                                      -              |
+                                        [0,0] ->  C -----------------+--------------- T  <- [x,y]
+                                                  | <------ d/2 ---->|
+
+                C - Current position
+                T - Target position
+                O - center of circle that pass through both C and T
+                d - distance from C to T
+                r - designated radius
+                h - distance from center of CT to O
+
+                Expanding the equations:
+
+                d -> sqrt(x^2 + y^2)
+                h -> sqrt(4 * r^2 - x^2 - y^2)/2
+                i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2
+                j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2
+
+                Which can be written:
+
+                i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
+                j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
+
+                Which we for size and speed reasons optimize to:
+
+                h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2)
+                i = (x - (y * h_x2_div_d))/2
+                j = (y + (x * h_x2_div_d))/2
+            */
+
+            // First, use h_x2_div_d to compute 4*h^2 to check if it is negative or r is smaller
+            // than d. If so, the sqrt of a negative number is complex and error out.
+            float h_x2_div_d = 4.0f * gc_block.values.r*gc_block.values.r - x*x - y*y;
+
+            if (h_x2_div_d < 0) { FAIL(STATUS_GCODE_ARC_RADIUS_ERROR); } // [Arc radius error]
+
+            // Finish computing h_x2_div_d.
+            h_x2_div_d = -sqrtf(h_x2_div_d)/hypot_f(x,y); // == -(h * 2 / d)
+            // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below)
+            if (gc_block.modal.motion == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; }
+
+            /* The counter clockwise circle lies to the left of the target direction. When offset is positive,
+               the left hand circle will be generated - when it is negative the right hand circle is generated.
+
+                                                                   T  <-- Target position
+
+                                                                   ^
+                        Clockwise circles with this center         |          Clockwise circles with this center will have
+                        will have > 180 deg of angular travel      |          < 180 deg of angular travel, which is a good thing!
+                                                         \         |          /
+            center of arc when h_x2_div_d is positive ->  x <----- | -----> x <- center of arc when h_x2_div_d is negative
+                                                                   |
+                                                                   |
+
+                                                                   C  <-- Current position
+            */
+            // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!),
+            // even though it is advised against ever generating such circles in a single line of g-code. By
+            // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of
+            // travel and thus we get the unadvisably long arcs as prescribed.
+            if (gc_block.values.r < 0) {
+                h_x2_div_d = -h_x2_div_d;
+                gc_block.values.r = -gc_block.values.r; // Finished with r. Set to positive for mc_arc
+            }
+            // Complete the operation by calculating the actual center of the arc
+            gc_block.values.ijk[axis_0] = 0.5f*(x-(y*h_x2_div_d));
+            gc_block.values.ijk[axis_1] = 0.5f*(y+(x*h_x2_div_d));
+
+          } else { // Arc Center Format Offset Mode
+            if (!(ijk_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_OFFSETS_IN_PLANE); } // [No offsets in plane]
+            bit_false(value_words,(bit(WORD_I)|bit(WORD_J)|bit(WORD_K)));
+
+            // Convert IJK values to proper units.
+            if (gc_block.modal.units == UNITS_MODE_INCHES) {
+              for (idx=0; idx<N_AXIS; idx++) { // Axes indices are consistent, so loop may be used to save flash space.
+                if (ijk_words & bit(idx)) { gc_block.values.ijk[idx] *= MM_PER_INCH; }
+              }
+            }
+
+            // Arc radius from center to target
+            x -= gc_block.values.ijk[axis_0]; // Delta x between circle center and target
+            y -= gc_block.values.ijk[axis_1]; // Delta y between circle center and target
+            float target_r = hypot_f(x,y);
+
+            // Compute arc radius for mc_arc. Defined from current location to center.
+            gc_block.values.r = hypot_f(gc_block.values.ijk[axis_0], gc_block.values.ijk[axis_1]);
+
+            // Compute difference between current location and target radii for final error-checks.
+            float delta_r = fabsf(target_r-gc_block.values.r);
+            if (delta_r > 0.005f) {
+              if (delta_r > 0.5f) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.5mm
+              if (delta_r > (0.001f*gc_block.values.r)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.005mm AND 0.1% radius
+            }
+          }
+          break;
+        case MOTION_MODE_PROBE_TOWARD_NO_ERROR: case MOTION_MODE_PROBE_AWAY_NO_ERROR:
+            gc_parser_flags |= GC_PARSER_PROBE_IS_NO_ERROR; // No break intentional.
+        case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_AWAY:
+            if ((gc_block.modal.motion == MOTION_MODE_PROBE_AWAY) ||
+                (gc_block.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { gc_parser_flags |= GC_PARSER_PROBE_IS_AWAY; }
+          // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate
+          //   is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning
+          //   an error, it issues an alarm to prevent further motion to the probe. It's also done there to
+          //   allow the planner buffer to empty and move off the probe trigger before another probing cycle.
+          if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
+          if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
+          break;
+      }
+    }
+  }
+
+  // [21. Program flow ]: No error checks required.
+
+  // [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc
+  // radius mode, or axis words that aren't used in the block.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+      // Jogging only uses the F feed rate and XYZ value words. N is valid, but S and T are invalid.
+      bit_false(value_words, (bit(WORD_N) | bit(WORD_F)));
+  } else {
+      bit_false(value_words, (bit(WORD_N) | bit(WORD_F) | bit(WORD_S) | bit(WORD_T))); // Remove single-meaning value words.
+  }
+  if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words.
+  if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words]
+
+  /* -------------------------------------------------------------------------------------
+     STEP 4: EXECUTE!!
+     Assumes that all error-checking has been completed and no failure modes exist. We just
+     need to update the state and execute the block according to the order-of-execution.
+  */
+
+  // Initialize planner data struct for motion blocks.
+  plan_line_data_t plan_data;
+  plan_line_data_t *pl_data = &plan_data;
+  memset(pl_data,0,sizeof(plan_line_data_t)); // Zero pl_data struct
+
+                                              // Intercept jog commands and complete error checking for valid jog commands and execute.
+                                              // NOTE: G-code parser state is not updated, except the position to ensure sequential jog
+                                              // targets are computed correctly. The final parser position after a jog is updated in
+                                              // protocol_execute_realtime() when jogging completes or is canceled.
+  if (gc_parser_flags & GC_PARSER_JOG_MOTION) {
+      // Only distance and unit modal commands and G53 absolute override command are allowed.
+      // NOTE: Feed rate word and axis word checks have already been performed in STEP 3.
+      if (command_words & ~(bit(MODAL_GROUP_G3) | bit(MODAL_GROUP_G6 | bit(MODAL_GROUP_G0)))) { FAIL(STATUS_INVALID_JOG_COMMAND) };
+      if (!(gc_block.non_modal_command == NON_MODAL_ABSOLUTE_OVERRIDE || gc_block.non_modal_command == NON_MODAL_NO_ACTION)) { FAIL(STATUS_INVALID_JOG_COMMAND); }
+
+      // Initialize planner data to current spindle and coolant modal state.
+      pl_data->spindle_speed = gc_state.spindle_speed;
+      plan_data.condition = (gc_state.modal.spindle | gc_state.modal.coolant);
+
+      uint8_t status = jog_execute(&plan_data, &gc_block);
+      if (status == STATUS_OK) { memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); }
+      return(status);
+  }
+
+  // If in laser mode, setup laser power based on current and past parser conditions.
+  if (bit_istrue(settings.flags, BITFLAG_LASER_MODE)) {
+      if (!((gc_block.modal.motion == MOTION_MODE_LINEAR) || (gc_block.modal.motion == MOTION_MODE_CW_ARC)
+          || (gc_block.modal.motion == MOTION_MODE_CCW_ARC))) {
+          gc_parser_flags |= GC_PARSER_LASER_DISABLE;
+      }
+
+      // Any motion mode with axis words is allowed to be passed from a spindle speed update. 
+      // NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted.
+      // TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length).
+      if (axis_words && (axis_command == AXIS_COMMAND_MOTION_MODE)) {
+        gc_parser_flags |= GC_PARSER_LASER_ISMOTION;
+      }
+      else {
+        // M3 constant power laser requires planner syncs to update the laser when changing between
+        // a G1/2/3 motion mode state and vice versa when there is no motion in the line.
+        if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) {
+          if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC)
+            || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
+            if (bit_istrue(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+              gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode.
+            }
+          }
+          else {
+            // When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode.
+            if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+              gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC;
+            }
+          }
+        }
+      }
+  }
+
+  // [0. Non-specific/common error-checks and miscellaneous setup]:
+  // NOTE: If no line number is present, the value is zero.
+  gc_state.line_number = gc_block.values.n;
+  #ifdef USE_LINE_NUMBERS
+    pl_data->line_number = gc_state.line_number; // Record data for planner use.
+  #endif
+
+  // [1. Comments feedback ]:  NOT SUPPORTED
+
+  // [2. Set feed rate mode ]:
+  gc_state.modal.feed_rate = gc_block.modal.feed_rate;
+  if (gc_state.modal.feed_rate) { pl_data->condition |= PL_COND_FLAG_INVERSE_TIME; } // Set condition flag for planner use.
+
+  // [3. Set feed rate ]:
+  gc_state.feed_rate = gc_block.values.f; // Always copy this value. See feed rate error-checking.
+  pl_data->feed_rate = gc_state.feed_rate; // Record data for planner use.
+
+  // [4. Set spindle speed ]:
+  if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags, GC_PARSER_LASER_FORCE_SYNC)) {
+      if (gc_state.modal.spindle != SPINDLE_DISABLE) {
+#ifdef VARIABLE_SPINDLE
+        if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_ISMOTION)) {
+          if (bit_istrue(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+            spindle_sync(gc_state.modal.spindle, 0.0);
+          }
+          else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); }
+        }
+#else
+          spindle_sync(gc_state.modal.spindle, 0.0);
+#endif
+      }
+      gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state.
+  }
+  // NOTE: Pass zero spindle speed for all restricted laser motions.
+  if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_DISABLE)) {
+      pl_data->spindle_speed = gc_state.spindle_speed; // Record data for planner use. 
+  } // else { pl_data->spindle_speed = 0.0; } // Initialized as zero already.
+
+  // [5. Select tool ]: NOT SUPPORTED. Only tracks tool value.
+  gc_state.tool = gc_block.values.t;
+
+  // [6. Change tool ]: NOT SUPPORTED
+
+  // [7. Spindle control ]:
+  if (gc_state.modal.spindle != gc_block.modal.spindle) {
+    // Update spindle control and apply spindle speed when enabling it in this block.
+    // NOTE: All spindle state changes are synced, even in laser mode. Also, pl_data,
+    // rather than gc_state, is used to manage laser state for non-laser motions.
+    spindle_sync(gc_block.modal.spindle, pl_data->spindle_speed);
+    gc_state.modal.spindle = gc_block.modal.spindle;
+  }
+  pl_data->condition |= gc_state.modal.spindle; // Set condition flag for planner use.
+
+  // [8. Coolant control ]:
+  if (gc_state.modal.coolant != gc_block.modal.coolant) {
+    // NOTE: Coolant M-codes are modal. Only one command per line is allowed. But, multiple states
+    // can exist at the same time, while coolant disable clears all states.
+    coolant_sync(gc_block.modal.coolant);
+    if (gc_block.modal.coolant == COOLANT_DISABLE) { gc_state.modal.coolant = COOLANT_DISABLE; }
+    else { gc_state.modal.coolant |= gc_block.modal.coolant; }
+  }
+  pl_data->condition |= gc_state.modal.coolant; // Set condition flag for planner use.
+
+																								// [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control.
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		if (gc_state.modal.override != gc_block.modal.override) {
+			gc_state.modal.override = gc_block.modal.override;
+			mc_override_ctrl_update(gc_state.modal.override);
+		}
+	#endif
+	
+  // [10. Dwell ]:
+  if (gc_block.non_modal_command == NON_MODAL_DWELL) { mc_dwell(gc_block.values.p); }
+
+  // [11. Set active plane ]:
+  gc_state.modal.plane_select = gc_block.modal.plane_select;
+
+  // [12. Set length units ]:
+  gc_state.modal.units = gc_block.modal.units;
+
+  // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED
+  // gc_state.modal.cutter_comp = gc_block.modal.cutter_comp; // NOTE: Not needed since always disabled.
+
+  // [14. Cutter length compensation ]: G43.1 and G49 supported. G43 NOT SUPPORTED.
+  // NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms
+  // of execution. The error-checking step would simply load the offset value into the correct
+  // axis of the block XYZ value array.
+  if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates a change.
+    gc_state.modal.tool_length = gc_block.modal.tool_length;
+    if (gc_state.modal.tool_length == TOOL_LENGTH_OFFSET_CANCEL) { // G49
+      gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] = 0.0f;
+    } // else G43.1
+    if ( gc_state.tool_length_offset != gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] ) {
+      gc_state.tool_length_offset = gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS];
+      system_flag_wco_change();
+    }
+  }
+
+  // [15. Coordinate system selection ]:
+  if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
+    gc_state.modal.coord_select = gc_block.modal.coord_select;
+    memcpy(gc_state.coord_system,block_coord_system,N_AXIS*sizeof(float));
+    system_flag_wco_change();
+  }
+
+  // [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED
+  // gc_state.modal.control = gc_block.modal.control; // NOTE: Always default.
+
+  // [17. Set distance mode ]:
+  gc_state.modal.distance = gc_block.modal.distance;
+
+  // [18. Set retract mode ]: NOT SUPPORTED
+
+  // [19. Go to predefined position, Set G10, or Set axis offsets ]:
+  switch(gc_block.non_modal_command) {
+    case NON_MODAL_SET_COORDINATE_DATA:
+      settings_write_coord_data(coord_select,gc_block.values.ijk);
+      // Update system coordinate system if currently active.
+      if (gc_state.modal.coord_select == coord_select) {
+        memcpy(gc_state.coord_system,gc_block.values.ijk,N_AXIS*sizeof(float));
+        system_flag_wco_change();
+      }
+      break;
+    case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1:
+      // Move to intermediate position before going home. Obeys current coordinate system and offsets
+      // and absolute and incremental modes.
+      pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
+      if (axis_command) { mc_line(gc_block.values.xyz, pl_data); }
+      mc_line(gc_block.values.ijk, pl_data);
+      memcpy(gc_state.position, gc_block.values.ijk, N_AXIS*sizeof(float));
+      break;
+    case NON_MODAL_SET_HOME_0:
+      settings_write_coord_data(SETTING_INDEX_G28,gc_state.position);
+      break;
+    case NON_MODAL_SET_HOME_1:
+      settings_write_coord_data(SETTING_INDEX_G30,gc_state.position);
+      break;
+    case NON_MODAL_SET_COORDINATE_OFFSET:
+      memcpy(gc_state.coord_offset,gc_block.values.xyz,sizeof(gc_block.values.xyz));
+      system_flag_wco_change();
+      break;
+    case NON_MODAL_RESET_COORDINATE_OFFSET:
+      clear_vector(gc_state.coord_offset); // Disable G92 offsets by zeroing offset vector.
+      system_flag_wco_change();
+      break;
+  }
+
+
+  // [20. Motion modes ]:
+  // NOTE: Commands G10,G28,G30,G92 lock out and prevent axis words from use in motion modes.
+  // Enter motion modes only if there are axis words or a motion mode command word in the block.
+  gc_state.modal.motion = gc_block.modal.motion;
+  if (gc_state.modal.motion != MOTION_MODE_NONE) {
+    if (axis_command == AXIS_COMMAND_MOTION_MODE) {
+      uint8_t gc_update_pos = GC_UPDATE_POS_TARGET;
+      if (gc_state.modal.motion == MOTION_MODE_LINEAR) {
+        mc_line(gc_block.values.xyz, pl_data);
+      } else if (gc_state.modal.motion == MOTION_MODE_SEEK) {
+        pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
+        mc_line(gc_block.values.xyz, pl_data);
+      } else if ((gc_state.modal.motion == MOTION_MODE_CW_ARC) || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
+          mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
+              axis_0, axis_1, axis_linear, bit_istrue(gc_parser_flags, GC_PARSER_ARC_IS_CLOCKWISE));
+      } else {
+        // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So
+        // upon a successful probing cycle, the machine position and the returned value should be the same.
+        #ifndef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES
+          pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE;
+        #endif
+        gc_update_pos = mc_probe_cycle(gc_block.values.xyz, pl_data, gc_parser_flags);
+    }  
+     
+      // As far as the parser is concerned, the position is now == target. In reality the
+      // motion control system might still be processing the action and the real tool position
+      // in any intermediate location.
+      if (gc_update_pos == GC_UPDATE_POS_TARGET) {
+        memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[]
+      } else if (gc_update_pos == GC_UPDATE_POS_SYSTEM) {
+        gc_sync_position(); // gc_state.position[] = sys_position
+      } // == GC_UPDATE_POS_NONE
+    }     
+
+  }
+
+  // [21. Program flow ]:
+  // M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may
+  // refill and can only be resumed by the cycle start run-time command.
+  gc_state.modal.program_flow = gc_block.modal.program_flow;
+  if (gc_state.modal.program_flow) {
+    protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
+    if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) {
+      if (sys.state != STATE_CHECK_MODE) {
+        system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause.
+        protocol_execute_realtime(); // Execute suspend.
+      }
+    } else { // == PROGRAM_FLOW_COMPLETED
+      // Upon program complete, only a subset of g-codes reset to certain defaults, according to
+      // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12]
+      // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups
+      // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset.
+      gc_state.modal.motion = MOTION_MODE_LINEAR;
+      gc_state.modal.plane_select = PLANE_SELECT_XY;
+      gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE;
+      gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN;
+      // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported.
+      gc_state.modal.coord_select = 0; // G54
+      gc_state.modal.spindle = SPINDLE_DISABLE;
+      gc_state.modal.coolant = COOLANT_DISABLE;
+			#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+				#ifdef DEACTIVATE_PARKING_UPON_INIT
+					gc_state.modal.override = OVERRIDE_DISABLED;
+				#else
+					gc_state.modal.override = OVERRIDE_PARKING_MOTION;
+				#endif
+			#endif
+			
+      #ifdef RESTORE_OVERRIDES_AFTER_PROGRAM_END
+        sys.f_override = DEFAULT_FEED_OVERRIDE;
+        sys.r_override = DEFAULT_RAPID_OVERRIDE;
+        sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE;
+      #endif
+
+      // Execute coordinate change and spindle/coolant stop.
+      if (sys.state != STATE_CHECK_MODE) {
+        if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); }
+        system_flag_wco_change(); // Set to refresh immediately just in case something altered.
+        spindle_set_state(SPINDLE_DISABLE,0.0f);
+        coolant_set_state(COOLANT_DISABLE);
+      }
+      report_feedback_message(MESSAGE_PROGRAM_END);
+    }
+    gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow.
+  }
+
+  // TODO: % to denote start of program.
+
+  return(STATUS_OK);
+}
+
+
+/*
+  Not supported:
+
+  - Canned cycles
+  - Tool radius compensation
+  - A,B,C-axes
+  - Evaluation of expressions
+  - Variables
+  - Override control (TBD)
+  - Tool changes
+  - Switches
+
+   (*) Indicates optional parameter, enabled through config.h and re-compile
+   group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets)
+   group 1 = {G81 - G89} (Motion modes: Canned cycles)
+   group 4 = {M1} (Optional stop, ignored)
+   group 6 = {M6} (Tool change)
+   group 7 = {G41, G42} cutter radius compensation (G40 is supported)
+   group 8 = {G43} tool length offset (G43.1/G49 are supported)
+   group 8 = {M7*} enable mist coolant (* Compile-option)
+	 group 9 = {M48, M49, M56*} enable/disable override switches (* Compile-option)
+	 group 10 = {G98, G99} return mode canned cycles
+   group 13 = {G61.1, G64} path control mode (G61 is supported)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/gcode.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,248 @@
+/*
+  gcode.h - rs274/ngc parser.
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef gcode_h
+#define gcode_h
+
+
+// Define modal group internal numbers for checking multiple command violations and tracking the
+// type of command that is called in the block. A modal group is a group of g-code commands that are
+// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
+// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
+// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
+// NOTE: Modal group define values must be sequential and starting from zero.
+#define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal
+#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion
+#define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection
+#define MODAL_GROUP_G3 3 // [G90,G91] Distance mode
+#define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode
+#define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode
+#define MODAL_GROUP_G6 6 // [G20,G21] Units
+#define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED.
+#define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset
+#define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
+#define MODAL_GROUP_G13 10 // [G61] Control mode
+
+#define MODAL_GROUP_M4 11  // [M0,M1,M2,M30] Stopping
+#define MODAL_GROUP_M7 12 // [M3,M4,M5] Spindle turning
+#define MODAL_GROUP_M8 13 // [M7,M8,M9] Coolant control
+#define MODAL_GROUP_M9 14 // [M56] Override control
+
+// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
+// internally by the parser to know which command to execute.
+// NOTE: Some macro values are assigned specific values to make g-code state reporting and parsing 
+// compile a litte smaller. Necessary due to being completely out of flash on the 328p. Although not
+// ideal, just be careful with values that state 'do not alter' and check both report.c and gcode.c 
+// to see how they are used, if you need to alter them.
+
+// Modal Group G0: Non-modal actions
+#define NON_MODAL_NO_ACTION 0 // (Default: Must be zero)
+#define NON_MODAL_DWELL 4 // G4 (Do not alter value)
+#define NON_MODAL_SET_COORDINATE_DATA 10 // G10 (Do not alter value)
+#define NON_MODAL_GO_HOME_0 28 // G28 (Do not alter value)
+#define NON_MODAL_SET_HOME_0 38 // G28.1 (Do not alter value)
+#define NON_MODAL_GO_HOME_1 30 // G30 (Do not alter value)
+#define NON_MODAL_SET_HOME_1 40 // G30.1 (Do not alter value)
+#define NON_MODAL_ABSOLUTE_OVERRIDE 53 // G53 (Do not alter value)
+#define NON_MODAL_SET_COORDINATE_OFFSET 92 // G92 (Do not alter value)
+#define NON_MODAL_RESET_COORDINATE_OFFSET 102 //G92.1 (Do not alter value)
+
+// Modal Group G1: Motion modes
+#define MOTION_MODE_SEEK 0 // G0 (Default: Must be zero)
+#define MOTION_MODE_LINEAR 1 // G1 (Do not alter value)
+#define MOTION_MODE_CW_ARC 2  // G2 (Do not alter value)
+#define MOTION_MODE_CCW_ARC 3  // G3 (Do not alter value)
+#define MOTION_MODE_PROBE_TOWARD 140 // G38.2 (Do not alter value)
+#define MOTION_MODE_PROBE_TOWARD_NO_ERROR 141 // G38.3 (Do not alter value)
+#define MOTION_MODE_PROBE_AWAY 142 // G38.4 (Do not alter value)
+#define MOTION_MODE_PROBE_AWAY_NO_ERROR 143 // G38.5 (Do not alter value)
+#define MOTION_MODE_NONE 80 // G80 (Do not alter value)
+
+// Modal Group G2: Plane select
+#define PLANE_SELECT_XY 0 // G17 (Default: Must be zero)
+#define PLANE_SELECT_ZX 1 // G18 (Do not alter value)
+#define PLANE_SELECT_YZ 2 // G19 (Do not alter value)
+
+// Modal Group G3: Distance mode
+#define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero)
+#define DISTANCE_MODE_INCREMENTAL 1 // G91 (Do not alter value)
+
+// Modal Group G4: Arc IJK distance mode
+#define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero)
+
+// Modal Group M4: Program flow
+#define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero)
+#define PROGRAM_FLOW_PAUSED 3 // M0
+#define PROGRAM_FLOW_OPTIONAL_STOP 1 // M1 NOTE: Not supported, but valid and ignored.
+#define PROGRAM_FLOW_COMPLETED_M2  2 // M2 (Do not alter value)
+#define PROGRAM_FLOW_COMPLETED_M30 30 // M30 (Do not alter value)
+
+// Modal Group G5: Feed rate mode
+#define FEED_RATE_MODE_UNITS_PER_MIN  0 // G94 (Default: Must be zero)
+#define FEED_RATE_MODE_INVERSE_TIME   1 // G93 (Do not alter value)
+
+// Modal Group G6: Units mode
+#define UNITS_MODE_MM 0 // G21 (Default: Must be zero)
+#define UNITS_MODE_INCHES 1 // G20 (Do not alter value)
+
+// Modal Group G7: Cutter radius compensation mode
+#define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero)
+
+// Modal Group G13: Control mode
+#define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero)
+
+// Modal Group M7: Spindle control
+#define SPINDLE_DISABLE 0 // M5 (Default: Must be zero)
+#define SPINDLE_ENABLE_CW   PL_COND_FLAG_SPINDLE_CW // M3 (NOTE: Uses planner condition bit flag)
+#define SPINDLE_ENABLE_CCW  PL_COND_FLAG_SPINDLE_CCW // M4 (NOTE: Uses planner condition bit flag)
+
+// Modal Group M8: Coolant control
+#define COOLANT_DISABLE 0 // M9 (Default: Must be zero)
+#define COOLANT_FLOOD_ENABLE  PL_COND_FLAG_COOLANT_FLOOD // M8 (NOTE: Uses planner condition bit flag)
+#define COOLANT_MIST_ENABLE   PL_COND_FLAG_COOLANT_MIST  // M7 (NOTE: Uses planner condition bit flag)
+
+// Modal Group G8: Tool length offset
+#define TOOL_LENGTH_OFFSET_CANCEL 0 // G49 (Default: Must be zero)
+#define TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC 1 // G43.1
+
+// Modal Group M9: Override control
+#ifdef DEACTIVATE_PARKING_UPON_INIT
+	#define OVERRIDE_DISABLED  0 // (Default: Must be zero)
+	#define OVERRIDE_PARKING_MOTION 1 // M56
+#else
+	#define OVERRIDE_PARKING_MOTION 0 // M56 (Default: Must be zero)
+	#define OVERRIDE_DISABLED  1 // Parking disabled.
+#endif
+
+// Modal Group G12: Active work coordinate system
+// N/A: Stores coordinate system value (54-59) to change to.
+
+// Define parameter word mapping.
+#define WORD_F  0
+#define WORD_I  1
+#define WORD_J  2
+#define WORD_K  3
+#define WORD_L  4
+#define WORD_N  5
+#define WORD_P  6
+#define WORD_R  7
+#define WORD_S  8
+#define WORD_T  9
+#define WORD_X  10
+#define WORD_Y  11
+#define WORD_Z  12
+
+// Define g-code parser position updating flags
+#define GC_UPDATE_POS_TARGET   0 // Must be zero
+#define GC_UPDATE_POS_SYSTEM   1
+#define GC_UPDATE_POS_NONE     2
+
+// Define probe cycle exit states and assign proper position updating.
+#define GC_PROBE_FOUND      GC_UPDATE_POS_SYSTEM
+#define GC_PROBE_ABORT      GC_UPDATE_POS_NONE
+#define GC_PROBE_FAIL_INIT  GC_UPDATE_POS_NONE
+#define GC_PROBE_FAIL_END   GC_UPDATE_POS_TARGET
+#ifdef SET_CHECK_MODE_PROBE_TO_START
+  #define GC_PROBE_CHECK_MODE   GC_UPDATE_POS_NONE  
+#else
+  #define GC_PROBE_CHECK_MODE   GC_UPDATE_POS_TARGET
+#endif
+
+// Define gcode parser flags for handling special cases.
+#define GC_PARSER_NONE                  0 // Must be zero.
+#define GC_PARSER_JOG_MOTION            bit(0)
+#define GC_PARSER_CHECK_MANTISSA        bit(1)
+#define GC_PARSER_ARC_IS_CLOCKWISE      bit(2)
+#define GC_PARSER_PROBE_IS_AWAY         bit(3)
+#define GC_PARSER_PROBE_IS_NO_ERROR     bit(4)
+#define GC_PARSER_LASER_FORCE_SYNC      bit(5)
+#define GC_PARSER_LASER_DISABLE         bit(6)
+#define GC_PARSER_LASER_ISMOTION        bit(7)
+
+
+// NOTE: When this struct is zeroed, the above defines set the defaults for the system.
+typedef struct {
+  uint8_t motion;          // {G0,G1,G2,G3,G38.2,G80}
+  uint8_t feed_rate;       // {G93,G94}
+  uint8_t units;           // {G20,G21}
+  uint8_t distance;        // {G90,G91}
+  // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only default supported.
+  uint8_t plane_select;    // {G17,G18,G19}
+  // uint8_t cutter_comp;  // {G40} NOTE: Don't track. Only default supported.
+  uint8_t tool_length;     // {G43.1,G49}
+  uint8_t coord_select;    // {G54,G55,G56,G57,G58,G59}
+  // uint8_t control;      // {G61} NOTE: Don't track. Only default supported.
+  uint8_t program_flow;    // {M0,M1,M2,M30}
+  uint8_t coolant;         // {M7,M8,M9}
+  uint8_t spindle;         // {M3,M4,M5}
+	uint8_t override;        // {M56}
+} gc_modal_t;
+
+typedef struct {
+  float f;         // Feed
+  float ijk[3];    // I,J,K Axis arc offsets
+  uint8_t l;       // G10 or canned cycles parameters
+  int32_t n;       // Line number
+  float p;         // G10 or dwell parameters
+  // float q;      // G82 peck drilling
+  float r;         // Arc radius
+  float s;         // Spindle speed
+  uint8_t t;       // Tool selection
+  float xyz[3];    // X,Y,Z Translational axes
+} gc_values_t;
+
+
+typedef struct {
+  gc_modal_t modal;
+
+  float spindle_speed;          // RPM
+  float feed_rate;              // Millimeters/min
+  uint8_t tool;                 // Tracks tool number. NOT USED.
+  int32_t line_number;          // Last line number sent
+
+  float position[N_AXIS];       // Where the interpreter considers the tool to be at this point in the code
+
+  float coord_system[N_AXIS];    // Current work coordinate system (G54+). Stores offset from absolute machine
+                                 // position in mm. Loaded from EEPROM when called.
+  float coord_offset[N_AXIS];    // Retains the G92 coordinate offset (work coordinates) relative to
+                                 // machine zero in mm. Non-persistent. Cleared upon reset and boot.
+  float tool_length_offset;      // Tracks tool length offset value when enabled.
+} parser_state_t;
+extern parser_state_t gc_state;
+
+
+typedef struct {
+  uint8_t non_modal_command;
+  gc_modal_t modal;
+  gc_values_t values;
+} parser_block_t;
+
+
+// Initialize the parser
+void gc_init();
+
+// Execute one block of rs275/ngc/g-code
+uint8_t gc_execute_line(char *line);
+
+// Set g-code parser position. Input in steps.
+void gc_sync_position();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/grbl.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,162 @@
+/*
+  grbl.h - main Grbl include file
+  Part of Grbl
+
+  Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef grbl_h
+#define grbl_h
+
+// Grbl versioning system
+#define GRBL_VERSION "1.1f"
+#define GRBL_VERSION_BUILD "20170324"
+
+#if !defined(STM32F103C8) && !defined(WIN32)
+#define AVRTARGET
+#endif
+
+// Define standard libraries used by Grbl.
+#ifdef AVRTARGET
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#define PORTPINDEF uint8_t
+#endif
+#include <math.h>
+#ifdef WIN32
+#include <Windows.h>
+typedef signed char  int8_t;
+typedef signed short int16_t;
+typedef signed int   int32_t;
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+typedef signed long long   int64_t;
+typedef unsigned long long uint64_t;
+typedef int bool;
+#define false 0
+#define true 1
+#define truncf(x) (int32_t)x
+#define PSTR(x) x
+#define pgm_read_byte_near(x) *(x)
+#define _delay_ms(x) Sleep(x)
+#define M_PI 3.1415926f
+#define LOG(x,y)
+#define PORTPINDEF uint8_t
+#define printPgmString printString
+//#define NOEEPROMSUPPORT
+#endif
+#ifdef STM32F103C8
+#include "stm32f10x.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_exti.h"
+#include "stm32f10x_tim.h"
+#include "misc.h"
+#define PSTR(x) x
+#define pgm_read_byte_near(x) *(x)
+void _delay_ms(uint32_t x);
+void _delay_us(uint32_t x);
+#define false 0
+#define true 1
+#define PORTPINDEF uint16_t
+typedef int bool;
+//#define NOEEPROMSUPPORT
+#define printPgmString printString
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+// Define the Grbl system include files. NOTE: Do not alter organization.
+#include "config.h"
+#include "nuts_bolts.h"
+#include "settings.h"
+#include "system.h"
+#include "defaults.h"
+#include "cpu_map.h"
+#include "planner.h"
+#include "coolant_control.h"
+#include "eeprom.h"
+#include "gcode.h"
+#include "limits.h"
+#include "motion_control.h"
+#include "planner.h"
+#include "print.h"
+#include "probe.h"
+#include "protocol.h"
+#include "report.h"
+#include "serial.h"
+#include "spindle_control.h"
+#include "stepper.h"
+#include "jog.h"
+
+// ---------------------------------------------------------------------------------------
+// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES:
+
+#ifndef HOMING_CYCLE_0
+  #error "Required HOMING_CYCLE_0 not defined."
+#endif
+
+#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE)
+  #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled"
+#endif
+
+#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P)
+  #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
+#endif
+
+#if !defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED)
+	#error "SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED may only be used with USE_SPINDLE_DIR_AS_ENABLE_PIN enabled"
+#endif
+
+#if defined(PARKING_ENABLE)
+  #if defined(HOMING_FORCE_SET_ORIGIN)
+    #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time."
+  #endif
+#endif
+
+#if defined(ENABLE_PARKING_OVERRIDE_CONTROL)
+	#if !defined(PARKING_ENABLE)
+		#error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE."
+	#endif
+#endif
+
+#if defined(SPINDLE_PWM_MIN_VALUE)
+  #if !(SPINDLE_PWM_MIN_VALUE > 0)
+    #error "SPINDLE_PWM_MIN_VALUE must be greater than zero."
+  #endif
+#endif
+
+#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT)
+  #error "WCO busy refresh is less than idle refresh."
+#endif
+#if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT)
+  #error "Override busy refresh is less than idle refresh."
+#endif
+#if (REPORT_WCO_REFRESH_IDLE_COUNT < 2)
+  #error "WCO refresh must be greater than one."
+#endif
+#if (REPORT_OVR_REFRESH_IDLE_COUNT < 1)
+  #error "Override refresh must be greater than zero."
+#endif
+// ---------------------------------------------------------------------------------------
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/grbl.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,162 @@
+/*
+  grbl.h - main Grbl include file
+  Part of Grbl
+
+  Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef grbl_h
+#define grbl_h
+
+// Grbl versioning system
+#define GRBL_VERSION "1.1f"
+#define GRBL_VERSION_BUILD "20170324"
+
+#if !defined(STM32F103C8) && !defined(WIN32)
+#define AVRTARGET
+#endif
+
+// Define standard libraries used by Grbl.
+#ifdef AVRTARGET
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#define PORTPINDEF uint8_t
+#endif
+#include <math.h>
+#ifdef WIN32
+#include <Windows.h>
+typedef signed char  int8_t;
+typedef signed short int16_t;
+typedef signed int   int32_t;
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+typedef signed long long   int64_t;
+typedef unsigned long long uint64_t;
+typedef int bool;
+#define false 0
+#define true 1
+#define trunc(x) (int32_t)x
+#define PSTR(x) x
+#define pgm_read_byte_near(x) *(x)
+#define _delay_ms(x) Sleep(x)
+#define M_PI 3.1415926f
+#define LOG(x,y)
+#define PORTPINDEF uint8_t
+#define printPgmString printString
+//#define NOEEPROMSUPPORT
+#endif
+#ifdef STM32F103C8
+#include "stm32f10x.h"
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_exti.h"
+#include "stm32f10x_tim.h"
+#include "misc.h"
+#define PSTR(x) x
+#define pgm_read_byte_near(x) *(x)
+void _delay_ms(uint32_t x);
+void _delay_us(uint32_t x);
+#define false 0
+#define true 1
+#define PORTPINDEF uint16_t
+typedef int bool;
+//#define NOEEPROMSUPPORT
+#define printPgmString printString
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+// Define the Grbl system include files. NOTE: Do not alter organization.
+#include "config.h"
+#include "nuts_bolts.h"
+#include "settings.h"
+#include "system.h"
+#include "defaults.h"
+#include "cpu_map.h"
+#include "planner.h"
+#include "coolant_control.h"
+#include "eeprom.h"
+#include "gcode.h"
+#include "limits.h"
+#include "motion_control.h"
+#include "planner.h"
+#include "print.h"
+#include "probe.h"
+#include "protocol.h"
+#include "report.h"
+#include "serial.h"
+#include "spindle_control.h"
+#include "stepper.h"
+#include "jog.h"
+
+// ---------------------------------------------------------------------------------------
+// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES:
+
+#ifndef HOMING_CYCLE_0
+  #error "Required HOMING_CYCLE_0 not defined."
+#endif
+
+#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE)
+  #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled"
+#endif
+
+#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P)
+  #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
+#endif
+
+#if !defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED)
+	#error "SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED may only be used with USE_SPINDLE_DIR_AS_ENABLE_PIN enabled"
+#endif
+
+#if defined(PARKING_ENABLE)
+  #if defined(HOMING_FORCE_SET_ORIGIN)
+    #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time."
+  #endif
+#endif
+
+#if defined(ENABLE_PARKING_OVERRIDE_CONTROL)
+	#if !defined(PARKING_ENABLE)
+		#error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE."
+	#endif
+#endif
+
+#if defined(SPINDLE_PWM_MIN_VALUE)
+  #if !(SPINDLE_PWM_MIN_VALUE > 0)
+    #error "SPINDLE_PWM_MIN_VALUE must be greater than zero."
+  #endif
+#endif
+
+#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT)
+  #error "WCO busy refresh is less than idle refresh."
+#endif
+#if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT)
+  #error "Override busy refresh is less than idle refresh."
+#endif
+#if (REPORT_WCO_REFRESH_IDLE_COUNT < 2)
+  #error "WCO refresh must be greater than one."
+#endif
+#if (REPORT_OVR_REFRESH_IDLE_COUNT < 1)
+  #error "Override refresh must be greater than zero."
+#endif
+// ---------------------------------------------------------------------------------------
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/jog.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,50 @@
+/*
+jog.h - Jogging methods
+Part of Grbl
+
+Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
+
+Grbl is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Grbl is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
+uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block)
+{
+  // Initialize planner data struct for jogging motions.
+  // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog.
+  pl_data->feed_rate = gc_block->values.f;
+  pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE;
+#ifdef USE_LINE_NUMBERS
+  pl_data->line_number = gc_block->values.n;
+#endif
+
+  if (bit_istrue(settings.flags, BITFLAG_SOFT_LIMIT_ENABLE)) {
+    if (system_check_travel_limits(gc_block->values.xyz)) { return(STATUS_TRAVEL_EXCEEDED); }
+  }
+
+  // Valid jog command. Plan, set state, and execute.
+  mc_line(gc_block->values.xyz, pl_data);
+  if (sys.state == STATE_IDLE) {
+    if (plan_get_current_block() != NULL) { // Check if there is a block to execute.
+      sys.state = STATE_JOG;
+      st_prep_buffer();
+      st_wake_up();  // NOTE: Manual start. No state machine required.
+    }
+  }
+
+  return(STATUS_OK);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/jog.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,32 @@
+/*
+  jog.h - Jogging methods
+  Part of Grbl
+
+  Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef jog_h
+#define jog_h
+
+#include "gcode.h"
+
+// System motion line numbers must be zero.
+#define JOG_LINE_NUMBER 0
+
+// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
+uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/limits.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,432 @@
+/*
+  limits.c - code pertaining to limit-switches and performing the homing cycle
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+// Homing axis search distance multiplier. Computed by this value times the cycle travel.
+#ifndef HOMING_AXIS_SEARCH_SCALAR
+  #define HOMING_AXIS_SEARCH_SCALAR  1.5f // Must be > 1 to ensure limit switch will be engaged.
+#endif
+#ifndef HOMING_AXIS_LOCATE_SCALAR
+  #define HOMING_AXIS_LOCATE_SCALAR  5.0f // Must be > 1 to ensure limit switch is cleared.
+#endif
+
+void limits_init()
+{
+#ifdef AVRTARGET
+  LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins
+
+  #ifdef DISABLE_LIMIT_PIN_PULL_UP
+    LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down.
+  #else
+    LIMIT_PORT |= (LIMIT_MASK);  // Enable internal pull-up resistors. Normal high operation.
+  #endif
+
+  if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) {
+    LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt
+    PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt
+  } else {
+    limits_disable();
+  }
+
+  #ifdef ENABLE_SOFTWARE_DEBOUNCE
+    MCUSR &= ~(1<<WDRF);
+    WDTCSR |= (1<<WDCE) | (1<<WDE);
+    WDTCSR = (1<<WDP0); // Set time-out at ~32msec.
+  #endif
+#endif
+#ifdef STM32F103C8
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_LIMIT_PORT | RCC_APB2Periph_AFIO, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+	GPIO_InitStructure.GPIO_Pin = LIMIT_MASK;
+	GPIO_Init(LIMIT_PORT, &GPIO_InitStructure);
+
+	if (bit_istrue(settings.flags, BITFLAG_HARD_LIMIT_ENABLE))
+	{
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, X_LIMIT_BIT);
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, Y_LIMIT_BIT);
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, Z_LIMIT_BIT);
+
+		EXTI_InitTypeDef EXTI_InitStructure;
+		EXTI_InitStructure.EXTI_Line = LIMIT_MASK;    //
+		EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Interrupt mode, optional values for the interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event.
+		EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Trigger mode, can be a falling edge trigger EXTI_Trigger_Falling, the rising edge triggered EXTI_Trigger_Rising, or any level (rising edge and falling edge trigger EXTI_Trigger_Rising_Falling)
+		EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+		EXTI_Init(&EXTI_InitStructure);
+
+		NVIC_InitTypeDef NVIC_InitStructure;
+		NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //Enable keypad external interrupt channel
+		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Priority 2,
+		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Sub priority 2
+		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel
+		NVIC_Init(&NVIC_InitStructure);
+	}
+	else
+	{
+		limits_disable();
+	}
+#endif
+}
+
+
+// Disables hard limits.
+void limits_disable()
+{
+#ifdef AVRTARGET
+  LIMIT_PCMSK &= ~LIMIT_MASK;  // Disable specific pins of the Pin Change Interrupt
+  PCICR &= ~(1 << LIMIT_INT);  // Disable Pin Change Interrupt
+#endif
+#ifdef STM32F103C8
+  NVIC_DisableIRQ(EXTI15_10_IRQn);
+#endif
+}
+
+
+// Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where
+// triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their
+// number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1.
+uint8_t limits_get_state()
+{
+  uint8_t limit_state = 0;
+#if defined(AVRTARGET) || defined(STM32F103C8)
+#if defined(AVRTARGET)
+  uint8_t pin = (LIMIT_PIN & LIMIT_MASK);
+#endif
+#if defined(STM32F103C8)
+  uint16_t pin = GPIO_ReadInputData(LIMIT_PIN);
+#endif
+  #ifdef INVERT_LIMIT_PIN_MASK
+    pin ^= INVERT_LIMIT_PIN_MASK;
+  #endif
+  if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
+  if (pin) {
+    uint8_t idx;
+    for (idx=0; idx<N_AXIS; idx++) {
+      if (pin & limit_pin_mask[idx]) { limit_state |= (1 << idx); }
+    }
+  }
+#endif
+  return(limit_state);
+}
+
+
+// This is the Limit Pin Change Interrupt, which handles the hard limit feature. A bouncing
+// limit switch can cause a lot of problems, like false readings and multiple interrupt calls.
+// If a switch is triggered at all, something bad has happened and treat it as such, regardless
+// if a limit switch is being disengaged. It's impossible to reliably tell the state of a
+// bouncing pin because the Arduino microcontroller does not retain any state information when
+// detecting a pin change. If we poll the pins in the ISR, you can miss the correct reading if the 
+// switch is bouncing.
+// NOTE: Do not attach an e-stop to the limit pins, because this interrupt is disabled during
+// homing cycles and will not respond correctly. Upon user request or need, there may be a
+// special pinout for an e-stop, but it is generally recommended to just directly connect
+// your e-stop switch to the Arduino reset pin, since it is the most correct way to do this.
+#ifndef ENABLE_SOFTWARE_DEBOUNCE
+#if defined(AVRTARGET) || defined (STM32F103C8)
+#if defined(AVRTARGET) 
+ISR(LIMIT_INT_vect) // DEFAULT: Limit pin change interrupt process.
+#else
+void EXTI15_10_IRQHandler(void)
+#endif
+{
+#if defined (STM32F103C8)
+	if (EXTI_GetITStatus(1 << X_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << X_LIMIT_BIT);
+	}
+	if (EXTI_GetITStatus(1 << Y_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << Y_LIMIT_BIT);
+	}
+	if (EXTI_GetITStatus(1 << Z_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << Z_LIMIT_BIT);
+	}
+	NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
+#endif
+  // Ignore limit switches if already in an alarm state or in-process of executing an alarm.
+  // When in the alarm state, Grbl should have been reset or will force a reset, so any pending
+  // moves in the planner and serial buffers are all cleared and newly sent blocks will be
+  // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
+  // limit setting if their limits are constantly triggering after a reset and move their axes.
+  if (sys.state != STATE_ALARM) {
+    if (!(sys_rt_exec_alarm)) {
+#ifdef HARD_LIMIT_FORCE_STATE_CHECK
+      // Check limit pin state.
+      if (limits_get_state()) {
+        mc_reset(); // Initiate system kill.
+        system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+      }
+#else
+      mc_reset(); // Initiate system kill.
+      system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+#endif
+    }
+  }
+}
+#endif
+#else // OPTIONAL: Software debounce limit pin routine.
+#if defined(AVRTARGET)
+// Upon limit pin change, enable watchdog timer to create a short delay. 
+ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1 << WDIE))) { WDTCSR |= (1 << WDIE); } }
+ISR(WDT_vect) // Watchdog timer ISR
+{
+  WDTCSR &= ~(1 << WDIE); // Disable watchdog timer. 
+  if (sys.state != STATE_ALARM) {  // Ignore if already in alarm state. 
+    if (!(sys_rt_exec_alarm)) {
+      // Check limit pin state. 
+      if (limits_get_state()) {
+        mc_reset(); // Initiate system kill.
+        system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+      }
+    }
+  }
+}
+#else
+#error ENABLE_SOFTWARE_DEBOUNCE is not supported yet
+#endif
+#endif
+
+// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after
+// completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate
+// the trigger point of the limit switches. The rapid stops are handled by a system level axis lock
+// mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically
+// circumvent the processes for executing motions in normal operation.
+// NOTE: Only the abort realtime command can interrupt this process.
+// TODO: Move limit pin-specific calls to a general function for portability.
+void limits_go_home(uint8_t cycle_mask)
+{
+  if (sys.abort) { return; } // Block if system reset has been issued.
+
+  // Initialize plan data struct for homing motion. Spindle and coolant are disabled.
+  plan_line_data_t plan_data;
+  plan_line_data_t *pl_data = &plan_data;
+  memset(pl_data,0,sizeof(plan_line_data_t));
+  pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE);
+  #ifdef USE_LINE_NUMBERS
+    pl_data->line_number = HOMING_CYCLE_LINE_NUMBER;
+  #endif
+
+  // Initialize variables used for homing computations.
+  uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
+  uint8_t step_pin[N_AXIS];
+  float target[N_AXIS];
+  float max_travel = 0.0f;
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    // Initialize step pin masks
+    step_pin[idx] = step_pin_mask[idx];
+    #ifdef COREXY
+      if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (step_pin_mask[X_AXIS]| step_pin_mask[Y_AXIS]); }
+    #endif
+
+    if (bit_istrue(cycle_mask,bit(idx))) {
+      // Set target based on max_travel setting. Ensure homing switches engaged with search scalar.
+      // NOTE: settings.max_travel[] is stored as a negative value.
+      max_travel = max(max_travel,(-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]);
+    }
+  }
+
+  // Set search mode with approach at seek rate to quickly engage the specified cycle_mask limit switches.
+  bool approach = true;
+  float homing_rate = settings.homing_seek_rate;
+
+  uint8_t limit_state, axislock, n_active_axis;
+  do {
+
+    system_convert_array_steps_to_mpos(target,sys_position);
+
+    // Initialize and declare variables needed for homing routine.
+    axislock = 0;
+    n_active_axis = 0;
+    for (idx=0; idx<N_AXIS; idx++) {
+      // Set target location for active axes and setup computation for homing rate.
+      if (bit_istrue(cycle_mask,bit(idx))) {
+        n_active_axis++;
+        #ifdef COREXY
+          if (idx == X_AXIS) {
+            int32_t axis_position = system_convert_corexy_to_y_axis_steps(sys_position);
+            sys_position[A_MOTOR] = axis_position;
+            sys_position[B_MOTOR] = -axis_position;
+          } else if (idx == Y_AXIS) {
+            int32_t axis_position = system_convert_corexy_to_x_axis_steps(sys_position);
+            sys_position[A_MOTOR] = sys_position[B_MOTOR] = axis_position;
+          } else {
+            sys_position[Z_AXIS] = 0;
+          }
+        #else
+          sys_position[idx] = 0;
+        #endif
+        // Set target direction based on cycle mask and homing cycle approach state.
+        // NOTE: This happens to compile smaller than any other implementation tried.
+        if (bit_istrue(settings.homing_dir_mask,bit(idx))) {
+          if (approach) { target[idx] = -max_travel; }
+          else { target[idx] = max_travel; }
+        } else {
+          if (approach) { target[idx] = max_travel; }
+          else { target[idx] = -max_travel; }
+        }
+        // Apply axislock to the step port pins active in this cycle.
+        axislock |= step_pin[idx];
+      }
+
+    }
+    homing_rate *= sqrtf(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate.
+    sys.homing_axis_lock = axislock;
+
+    // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
+    pl_data->feed_rate = homing_rate; // Set current homing rate.
+    plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion.
+
+    sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags.
+    st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
+    st_wake_up(); // Initiate motion
+    do {
+      if (approach) {
+        // Check limit state. Lock out cycle axes when they change.
+        limit_state = limits_get_state();
+        for (idx=0; idx<N_AXIS; idx++) {
+          if (axislock & step_pin[idx]) {
+            if (limit_state & (1 << idx)) {
+              #ifdef COREXY
+                if (idx==Z_AXIS) { axislock &= ~(step_pin[Z_AXIS]); }
+                else { axislock &= ~(step_pin[A_MOTOR]|step_pin[B_MOTOR]); }
+              #else
+                axislock &= ~(step_pin[idx]);
+              #endif
+            }
+          }
+        }
+        sys.homing_axis_lock = axislock;
+      }
+
+      st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
+
+      // Exit routines: No time to run protocol_execute_realtime() in this loop.
+      if (sys_rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) {
+        uint8_t rt_exec = sys_rt_exec_state;
+        // Homing failure condition: Reset issued during cycle.
+        if (rt_exec & EXEC_RESET) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_RESET); }
+        // Homing failure condition: Safety door was opened.
+        if (rt_exec & EXEC_SAFETY_DOOR) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_DOOR); }
+        // Homing failure condition: Limit switch still engaged after pull-off motion
+        if (!approach && (limits_get_state() & cycle_mask)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_PULLOFF); }
+        // Homing failure condition: Limit switch not found during approach.
+        if (approach && (rt_exec & EXEC_CYCLE_STOP)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_APPROACH); }
+        if (sys_rt_exec_alarm) {
+          mc_reset(); // Stop motors, if they are running.
+          protocol_execute_realtime();
+          return;
+        } else {
+          // Pull-off motion complete. Disable CYCLE_STOP from executing.
+          system_clear_exec_state_flag(EXEC_CYCLE_STOP);
+          break;
+        }
+      }
+
+    } while (STEP_MASK & axislock);
+
+    st_reset(); // Immediately force kill steppers and reset step segment buffer.
+    delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
+
+    // Reverse direction and reset homing rate for locate cycle(s).
+    approach = !approach;
+
+    // After first cycle, homing enters locating phase. Shorten search to pull-off distance.
+    if (approach) {
+      max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR;
+      homing_rate = settings.homing_feed_rate;
+    } else {
+      max_travel = settings.homing_pulloff;
+      homing_rate = settings.homing_seek_rate;
+    }
+
+  } while (n_cycle-- > 0);
+
+  // The active cycle axes should now be homed and machine limits have been located. By
+  // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches
+  // can be on either side of an axes, check and set axes machine zero appropriately. Also,
+  // set up pull-off maneuver from axes limit switches that have been homed. This provides
+  // some initial clearance off the switches and should also help prevent them from falsely
+  // triggering when hard limits are enabled or when more than one axes shares a limit pin.
+  int32_t set_axis_position;
+  // Set machine positions for homed limit switches. Don't update non-homed axes.
+  for (idx=0; idx<N_AXIS; idx++) {
+    // NOTE: settings.max_travel[] is stored as a negative value.
+    if (cycle_mask & bit(idx)) {
+      #ifdef HOMING_FORCE_SET_ORIGIN
+        set_axis_position = 0;
+      #else
+        if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
+          set_axis_position = lroundf((settings.max_travel[idx]+settings.homing_pulloff)*settings.steps_per_mm[idx]);
+        } else {
+          set_axis_position = lroundf(-settings.homing_pulloff*settings.steps_per_mm[idx]);
+        }
+      #endif
+
+      #ifdef COREXY
+        if (idx==X_AXIS) {
+          int32_t off_axis_position = system_convert_corexy_to_y_axis_steps(sys_position);
+          sys_position[A_MOTOR] = set_axis_position + off_axis_position;
+          sys_position[B_MOTOR] = set_axis_position - off_axis_position;
+        } else if (idx==Y_AXIS) {
+          int32_t off_axis_position = system_convert_corexy_to_x_axis_steps(sys_position);
+          sys_position[A_MOTOR] = off_axis_position + set_axis_position;
+          sys_position[B_MOTOR] = off_axis_position - set_axis_position;
+        } else {
+          sys_position[idx] = set_axis_position;
+        }
+      #else
+        sys_position[idx] = set_axis_position;
+      #endif
+
+    }
+  }
+  sys.step_control = STEP_CONTROL_NORMAL_OP; // Return step control to normal operation.
+}
+
+
+// Performs a soft limit check. Called from mc_line() only. Assumes the machine has been homed,
+// the workspace volume is in all negative space, and the system is in normal operation.
+// NOTE: Used by jogging to limit travel within soft-limit volume.
+void limits_soft_check(float *target)
+{
+  if (system_check_travel_limits(target)) {
+    sys.soft_limit = true;
+    // Force feed hold if cycle is active. All buffered blocks are guaranteed to be within
+    // workspace volume so just come to a controlled stop so position is not lost. When complete
+    // enter alarm mode.
+    if (sys.state == STATE_CYCLE) {
+      system_set_exec_state_flag(EXEC_FEED_HOLD);
+      do {
+        protocol_execute_realtime();
+        if (sys.abort) { return; }
+      } while ( sys.state != STATE_IDLE );
+    }
+    mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
+    system_set_exec_alarm(EXEC_ALARM_SOFT_LIMIT); // Indicate soft limit critical event
+    protocol_execute_realtime(); // Execute to enter critical event loop and system abort
+    return;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/limits.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,432 @@
+/*
+  limits.c - code pertaining to limit-switches and performing the homing cycle
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+// Homing axis search distance multiplier. Computed by this value times the cycle travel.
+#ifndef HOMING_AXIS_SEARCH_SCALAR
+  #define HOMING_AXIS_SEARCH_SCALAR  1.5f // Must be > 1 to ensure limit switch will be engaged.
+#endif
+#ifndef HOMING_AXIS_LOCATE_SCALAR
+  #define HOMING_AXIS_LOCATE_SCALAR  5.0f // Must be > 1 to ensure limit switch is cleared.
+#endif
+
+void limits_init()
+{
+#ifdef AVRTARGET
+  LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins
+
+  #ifdef DISABLE_LIMIT_PIN_PULL_UP
+    LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down.
+  #else
+    LIMIT_PORT |= (LIMIT_MASK);  // Enable internal pull-up resistors. Normal high operation.
+  #endif
+
+  if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) {
+    LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt
+    PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt
+  } else {
+    limits_disable();
+  }
+
+  #ifdef ENABLE_SOFTWARE_DEBOUNCE
+    MCUSR &= ~(1<<WDRF);
+    WDTCSR |= (1<<WDCE) | (1<<WDE);
+    WDTCSR = (1<<WDP0); // Set time-out at ~32msec.
+  #endif
+#endif
+#ifdef STM32F103C8
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_LIMIT_PORT | RCC_APB2Periph_AFIO, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+	GPIO_InitStructure.GPIO_Pin = LIMIT_MASK;
+	GPIO_Init(LIMIT_PORT, &GPIO_InitStructure);
+
+	if (bit_istrue(settings.flags, BITFLAG_HARD_LIMIT_ENABLE))
+	{
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, X_LIMIT_BIT);
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, Y_LIMIT_BIT);
+		GPIO_EXTILineConfig(GPIO_LIMIT_PORT, Z_LIMIT_BIT);
+
+		EXTI_InitTypeDef EXTI_InitStructure;
+		EXTI_InitStructure.EXTI_Line = LIMIT_MASK;    //
+		EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Interrupt mode, optional values for the interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event.
+		EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Trigger mode, can be a falling edge trigger EXTI_Trigger_Falling, the rising edge triggered EXTI_Trigger_Rising, or any level (rising edge and falling edge trigger EXTI_Trigger_Rising_Falling)
+		EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+		EXTI_Init(&EXTI_InitStructure);
+
+		NVIC_InitTypeDef NVIC_InitStructure;
+		NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //Enable keypad external interrupt channel
+		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Priority 2,
+		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Sub priority 2
+		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel
+		NVIC_Init(&NVIC_InitStructure);
+	}
+	else
+	{
+		limits_disable();
+	}
+#endif
+}
+
+
+// Disables hard limits.
+void limits_disable()
+{
+#ifdef AVRTARGET
+  LIMIT_PCMSK &= ~LIMIT_MASK;  // Disable specific pins of the Pin Change Interrupt
+  PCICR &= ~(1 << LIMIT_INT);  // Disable Pin Change Interrupt
+#endif
+#ifdef STM32F103C8
+  NVIC_DisableIRQ(EXTI15_10_IRQn);
+#endif
+}
+
+
+// Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where
+// triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their
+// number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1.
+uint8_t limits_get_state()
+{
+  uint8_t limit_state = 0;
+#if defined(AVRTARGET) || defined(STM32F103C8)
+#if defined(AVRTARGET)
+  uint8_t pin = (LIMIT_PIN & LIMIT_MASK);
+#endif
+#if defined(STM32F103C8)
+  uint16_t pin = GPIO_ReadInputData(LIMIT_PIN);
+#endif
+  #ifdef INVERT_LIMIT_PIN_MASK
+    pin ^= INVERT_LIMIT_PIN_MASK;
+  #endif
+  if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
+  if (pin) {
+    uint8_t idx;
+    for (idx=0; idx<N_AXIS; idx++) {
+      if (pin & limit_pin_mask[idx]) { limit_state |= (1 << idx); }
+    }
+  }
+#endif
+  return(limit_state);
+}
+
+
+// This is the Limit Pin Change Interrupt, which handles the hard limit feature. A bouncing
+// limit switch can cause a lot of problems, like false readings and multiple interrupt calls.
+// If a switch is triggered at all, something bad has happened and treat it as such, regardless
+// if a limit switch is being disengaged. It's impossible to reliably tell the state of a
+// bouncing pin because the Arduino microcontroller does not retain any state information when
+// detecting a pin change. If we poll the pins in the ISR, you can miss the correct reading if the 
+// switch is bouncing.
+// NOTE: Do not attach an e-stop to the limit pins, because this interrupt is disabled during
+// homing cycles and will not respond correctly. Upon user request or need, there may be a
+// special pinout for an e-stop, but it is generally recommended to just directly connect
+// your e-stop switch to the Arduino reset pin, since it is the most correct way to do this.
+#ifndef ENABLE_SOFTWARE_DEBOUNCE
+#if defined(AVRTARGET) || defined (STM32F103C8)
+#if defined(AVRTARGET) 
+ISR(LIMIT_INT_vect) // DEFAULT: Limit pin change interrupt process.
+#else
+void EXTI15_10_IRQHandler(void)
+#endif
+{
+#if defined (STM32F103C8)
+	if (EXTI_GetITStatus(1 << X_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << X_LIMIT_BIT);
+	}
+	if (EXTI_GetITStatus(1 << Y_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << Y_LIMIT_BIT);
+	}
+	if (EXTI_GetITStatus(1 << Z_LIMIT_BIT) != RESET)
+	{
+		EXTI_ClearITPendingBit(1 << Z_LIMIT_BIT);
+	}
+	NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
+#endif
+  // Ignore limit switches if already in an alarm state or in-process of executing an alarm.
+  // When in the alarm state, Grbl should have been reset or will force a reset, so any pending
+  // moves in the planner and serial buffers are all cleared and newly sent blocks will be
+  // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
+  // limit setting if their limits are constantly triggering after a reset and move their axes.
+  if (sys.state != STATE_ALARM) {
+    if (!(sys_rt_exec_alarm)) {
+#ifdef HARD_LIMIT_FORCE_STATE_CHECK
+      // Check limit pin state.
+      if (limits_get_state()) {
+        mc_reset(); // Initiate system kill.
+        system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+      }
+#else
+      mc_reset(); // Initiate system kill.
+      system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+#endif
+    }
+  }
+}
+#endif
+#else // OPTIONAL: Software debounce limit pin routine.
+#if defined(AVRTARGET)
+// Upon limit pin change, enable watchdog timer to create a short delay. 
+ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1 << WDIE))) { WDTCSR |= (1 << WDIE); } }
+ISR(WDT_vect) // Watchdog timer ISR
+{
+  WDTCSR &= ~(1 << WDIE); // Disable watchdog timer. 
+  if (sys.state != STATE_ALARM) {  // Ignore if already in alarm state. 
+    if (!(sys_rt_exec_alarm)) {
+      // Check limit pin state. 
+      if (limits_get_state()) {
+        mc_reset(); // Initiate system kill.
+        system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event
+      }
+    }
+  }
+}
+#else
+#error ENABLE_SOFTWARE_DEBOUNCE is not supported yet
+#endif
+#endif
+
+// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after
+// completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate
+// the trigger point of the limit switches. The rapid stops are handled by a system level axis lock
+// mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically
+// circumvent the processes for executing motions in normal operation.
+// NOTE: Only the abort realtime command can interrupt this process.
+// TODO: Move limit pin-specific calls to a general function for portability.
+void limits_go_home(uint8_t cycle_mask)
+{
+  if (sys.abort) { return; } // Block if system reset has been issued.
+
+  // Initialize plan data struct for homing motion. Spindle and coolant are disabled.
+  plan_line_data_t plan_data;
+  plan_line_data_t *pl_data = &plan_data;
+  memset(pl_data,0,sizeof(plan_line_data_t));
+  pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE);
+  #ifdef USE_LINE_NUMBERS
+    pl_data->line_number = HOMING_CYCLE_LINE_NUMBER;
+  #endif
+
+  // Initialize variables used for homing computations.
+  uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
+  uint8_t step_pin[N_AXIS];
+  float target[N_AXIS];
+  float max_travel = 0.0f;
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    // Initialize step pin masks
+    step_pin[idx] = step_pin_mask[idx];
+    #ifdef COREXY
+      if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (step_pin_mask[X_AXIS]| step_pin_mask[Y_AXIS]); }
+    #endif
+
+    if (bit_istrue(cycle_mask,bit(idx))) {
+      // Set target based on max_travel setting. Ensure homing switches engaged with search scalar.
+      // NOTE: settings.max_travel[] is stored as a negative value.
+      max_travel = max(max_travel,(-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]);
+    }
+  }
+
+  // Set search mode with approach at seek rate to quickly engage the specified cycle_mask limit switches.
+  bool approach = true;
+  float homing_rate = settings.homing_seek_rate;
+
+  uint8_t limit_state, axislock, n_active_axis;
+  do {
+
+    system_convert_array_steps_to_mpos(target,sys_position);
+
+    // Initialize and declare variables needed for homing routine.
+    axislock = 0;
+    n_active_axis = 0;
+    for (idx=0; idx<N_AXIS; idx++) {
+      // Set target location for active axes and setup computation for homing rate.
+      if (bit_istrue(cycle_mask,bit(idx))) {
+        n_active_axis++;
+        #ifdef COREXY
+          if (idx == X_AXIS) {
+            int32_t axis_position = system_convert_corexy_to_y_axis_steps(sys_position);
+            sys_position[A_MOTOR] = axis_position;
+            sys_position[B_MOTOR] = -axis_position;
+          } else if (idx == Y_AXIS) {
+            int32_t axis_position = system_convert_corexy_to_x_axis_steps(sys_position);
+            sys_position[A_MOTOR] = sys_position[B_MOTOR] = axis_position;
+          } else {
+            sys_position[Z_AXIS] = 0;
+          }
+        #else
+          sys_position[idx] = 0;
+        #endif
+        // Set target direction based on cycle mask and homing cycle approach state.
+        // NOTE: This happens to compile smaller than any other implementation tried.
+        if (bit_istrue(settings.homing_dir_mask,bit(idx))) {
+          if (approach) { target[idx] = -max_travel; }
+          else { target[idx] = max_travel; }
+        } else {
+          if (approach) { target[idx] = max_travel; }
+          else { target[idx] = -max_travel; }
+        }
+        // Apply axislock to the step port pins active in this cycle.
+        axislock |= step_pin[idx];
+      }
+
+    }
+    homing_rate *= sqrtf(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate.
+    sys.homing_axis_lock = axislock;
+
+    // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
+    pl_data->feed_rate = homing_rate; // Set current homing rate.
+    plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion.
+
+    sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags.
+    st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
+    st_wake_up(); // Initiate motion
+    do {
+      if (approach) {
+        // Check limit state. Lock out cycle axes when they change.
+        limit_state = limits_get_state();
+        for (idx=0; idx<N_AXIS; idx++) {
+          if (axislock & step_pin[idx]) {
+            if (limit_state & (1 << idx)) {
+              #ifdef COREXY
+                if (idx==Z_AXIS) { axislock &= ~(step_pin[Z_AXIS]); }
+                else { axislock &= ~(step_pin[A_MOTOR]|step_pin[B_MOTOR]); }
+              #else
+                axislock &= ~(step_pin[idx]);
+              #endif
+            }
+          }
+        }
+        sys.homing_axis_lock = axislock;
+      }
+
+      st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
+
+      // Exit routines: No time to run protocol_execute_realtime() in this loop.
+      if (sys_rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) {
+        uint8_t rt_exec = sys_rt_exec_state;
+        // Homing failure condition: Reset issued during cycle.
+        if (rt_exec & EXEC_RESET) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_RESET); }
+        // Homing failure condition: Safety door was opened.
+        if (rt_exec & EXEC_SAFETY_DOOR) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_DOOR); }
+        // Homing failure condition: Limit switch still engaged after pull-off motion
+        if (!approach && (limits_get_state() & cycle_mask)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_PULLOFF); }
+        // Homing failure condition: Limit switch not found during approach.
+        if (approach && (rt_exec & EXEC_CYCLE_STOP)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_APPROACH); }
+        if (sys_rt_exec_alarm) {
+          mc_reset(); // Stop motors, if they are running.
+          protocol_execute_realtime();
+          return;
+        } else {
+          // Pull-off motion complete. Disable CYCLE_STOP from executing.
+          system_clear_exec_state_flag(EXEC_CYCLE_STOP);
+          break;
+        }
+      }
+
+    } while (STEP_MASK & axislock);
+
+    st_reset(); // Immediately force kill steppers and reset step segment buffer.
+    delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
+
+    // Reverse direction and reset homing rate for locate cycle(s).
+    approach = !approach;
+
+    // After first cycle, homing enters locating phase. Shorten search to pull-off distance.
+    if (approach) {
+      max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR;
+      homing_rate = settings.homing_feed_rate;
+    } else {
+      max_travel = settings.homing_pulloff;
+      homing_rate = settings.homing_seek_rate;
+    }
+
+  } while (n_cycle-- > 0);
+
+  // The active cycle axes should now be homed and machine limits have been located. By
+  // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches
+  // can be on either side of an axes, check and set axes machine zero appropriately. Also,
+  // set up pull-off maneuver from axes limit switches that have been homed. This provides
+  // some initial clearance off the switches and should also help prevent them from falsely
+  // triggering when hard limits are enabled or when more than one axes shares a limit pin.
+  int32_t set_axis_position;
+  // Set machine positions for homed limit switches. Don't update non-homed axes.
+  for (idx=0; idx<N_AXIS; idx++) {
+    // NOTE: settings.max_travel[] is stored as a negative value.
+    if (cycle_mask & bit(idx)) {
+      #ifdef HOMING_FORCE_SET_ORIGIN
+        set_axis_position = 0;
+      #else
+        if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
+          set_axis_position = lround((settings.max_travel[idx]+settings.homing_pulloff)*settings.steps_per_mm[idx]);
+        } else {
+          set_axis_position = lround(-settings.homing_pulloff*settings.steps_per_mm[idx]);
+        }
+      #endif
+
+      #ifdef COREXY
+        if (idx==X_AXIS) {
+          int32_t off_axis_position = system_convert_corexy_to_y_axis_steps(sys_position);
+          sys_position[A_MOTOR] = set_axis_position + off_axis_position;
+          sys_position[B_MOTOR] = set_axis_position - off_axis_position;
+        } else if (idx==Y_AXIS) {
+          int32_t off_axis_position = system_convert_corexy_to_x_axis_steps(sys_position);
+          sys_position[A_MOTOR] = off_axis_position + set_axis_position;
+          sys_position[B_MOTOR] = off_axis_position - set_axis_position;
+        } else {
+          sys_position[idx] = set_axis_position;
+        }
+      #else
+        sys_position[idx] = set_axis_position;
+      #endif
+
+    }
+  }
+  sys.step_control = STEP_CONTROL_NORMAL_OP; // Return step control to normal operation.
+}
+
+
+// Performs a soft limit check. Called from mc_line() only. Assumes the machine has been homed,
+// the workspace volume is in all negative space, and the system is in normal operation.
+// NOTE: Used by jogging to limit travel within soft-limit volume.
+void limits_soft_check(float *target)
+{
+  if (system_check_travel_limits(target)) {
+    sys.soft_limit = true;
+    // Force feed hold if cycle is active. All buffered blocks are guaranteed to be within
+    // workspace volume so just come to a controlled stop so position is not lost. When complete
+    // enter alarm mode.
+    if (sys.state == STATE_CYCLE) {
+      system_set_exec_state_flag(EXEC_FEED_HOLD);
+      do {
+        protocol_execute_realtime();
+        if (sys.abort) { return; }
+      } while ( sys.state != STATE_IDLE );
+    }
+    mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
+    system_set_exec_alarm(EXEC_ALARM_SOFT_LIMIT); // Indicate soft limit critical event
+    protocol_execute_realtime(); // Execute to enter critical event loop and system abort
+    return;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/limits.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,41 @@
+/*
+  limits.h - code pertaining to limit-switches and performing the homing cycle
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef limits_h
+#define limits_h
+
+
+// Initialize the limits module
+void limits_init();
+
+// Disables hard limits.
+void limits_disable();
+
+// Returns limit state as a bit-wise uint8 variable.
+uint8_t limits_get_state();
+
+// Perform one portion of the homing cycle based on the input settings.
+void limits_go_home(uint8_t cycle_mask);
+
+// Check for soft limit violations
+void limits_soft_check(float *target);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/main.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,209 @@
+/*
+  main.c - An embedded CNC Controller with rs274/ngc (g-code) support
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+// Declare system global variable structure
+system_t sys;
+int32_t sys_position[N_AXIS];      // Real-time machine (aka home) position vector in steps.
+int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
+volatile uint8_t sys_probe_state;   // Probing state value.  Used to coordinate the probing cycle with stepper ISR.
+volatile uint8_t sys_rt_exec_state;   // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
+volatile uint8_t sys_rt_exec_alarm;   // Global realtime executor bitflag variable for setting various alarms.
+volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
+volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
+
+#if defined (STM32F103C8)
+#include "usb_lib.h"
+#ifdef USEUSB
+#include "usb_desc.h"
+#endif
+#include "hw_config.h"
+#ifdef USEUSB
+#include "usb_pwr.h"
+#endif
+#include "stm32eeprom.h"
+#ifndef USEUSB
+#include "stm32f10x_usart.h"
+void USART1_Configuration(u32 BaudRate)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+	USART_InitTypeDef USART_InitStructure;
+	NVIC_InitTypeDef NVIC_InitStructure;
+	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
+	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   
+	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
+
+	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
+	NVIC_Init(&NVIC_InitStructure);                 
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
+
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+	USART_InitStructure.USART_BaudRate = BaudRate;	  
+	USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
+	USART_InitStructure.USART_StopBits = USART_StopBits_1;	 
+	USART_InitStructure.USART_Parity = USART_Parity_No;	 
+	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+	USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE);
+	USART_Init(USART1, &USART_InitStructure);
+	//	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
+	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
+	USART_Cmd(USART1, ENABLE);
+}
+#endif
+
+#endif
+
+
+#ifdef WIN32
+int main(int argc, char *argv[])
+#else
+int main(void)
+#endif
+{
+#if defined (STM32F103C8)
+    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
+#ifdef LEDBLINK
+	GPIO_InitTypeDef GPIO_InitStructure;
+
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
+	GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+	//Set_System();
+#ifndef USEUSB
+	USART1_Configuration(115200);
+#else
+	Set_USBClock();
+	USB_Interrupts_Config();
+	USB_Init();
+#endif
+
+#ifndef NOEEPROMSUPPORT
+	FLASH_Unlock();
+	eeprom_init();
+#endif
+	SysTick->CTRL &= 0xfffffffb;
+#endif
+  // Initialize system upon power-up.
+  serial_init();   // Setup serial baud rate and interrupts
+#ifdef WIN32
+  winserial_init(argv[1]);
+  eeprom_init();
+#endif
+  settings_init(); // Load Grbl settings from EEPROM
+  stepper_init();  // Configure stepper pins and interrupt timers
+  system_init();   // Configure pinout pins and pin-change interrupt
+
+  memset(sys_position,0,sizeof(sys_position)); // Clear machine position.
+#ifdef AVRTARGET
+  sei(); // Enable interrupts
+#endif
+  // Initialize system state.
+  #ifdef FORCE_INITIALIZATION_ALARM
+    // Force Grbl into an ALARM state upon a power-cycle or hard reset.
+    sys.state = STATE_ALARM;
+  #else
+    sys.state = STATE_IDLE;
+  #endif
+  
+  // Check for power-up and set system alarm if homing is enabled to force homing cycle
+  // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
+  // startup scripts, but allows access to settings and internal commands. Only a homing
+  // cycle '$H' or kill alarm locks '$X' will disable the alarm.
+  // NOTE: The startup script will run after successful completion of the homing cycle, but
+  // not after disabling the alarm locks. Prevents motion startup blocks from crashing into
+  // things uncontrollably. Very bad.
+  #ifdef HOMING_INIT_LOCK
+    if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; }
+  #endif
+
+  // Grbl initialization loop upon power-up or a system abort. For the latter, all processes
+  // will return to this loop to be cleanly re-initialized.
+  for(;;) {
+
+    // Reset system variables.
+    uint8_t prior_state = sys.state;
+    memset(&sys, 0, sizeof(system_t)); // Clear system struct variable.
+    sys.state = prior_state;
+    sys.f_override = DEFAULT_FEED_OVERRIDE;  // Set to 100%
+    sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100%
+    sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100%
+		memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position.
+    sys_probe_state = 0;
+    sys_rt_exec_state = 0;
+    sys_rt_exec_alarm = 0;
+    sys_rt_exec_motion_override = 0;
+    sys_rt_exec_accessory_override = 0;
+
+    // Reset Grbl primary systems.
+    serial_reset_read_buffer(); // Clear serial read buffer
+    gc_init(); // Set g-code parser to default state
+    spindle_init();
+    coolant_init();
+    limits_init();
+    probe_init();
+    plan_reset(); // Clear block buffer and planner variables
+    st_reset(); // Clear stepper subsystem variables.
+
+    // Sync cleared gcode and planner positions to current system position.
+    plan_sync_position();
+    gc_sync_position();
+
+    // Print welcome message. Indicates an initialization has occured at power-up or with a reset.
+    report_init_message();
+
+    // Start Grbl main loop. Processes program inputs and executes them.
+    protocol_main_loop();
+
+  }
+  return 0;   /* Never reached */
+}
+#if defined (STM32F103C8)
+void _delay_ms(uint32_t x)
+{
+	u32 temp;
+	SysTick->LOAD = (u32)72000000 / 8000;                     // Loading time
+	SysTick->VAL = 0x00;                                            // Empty the counter
+	SysTick->CTRL = 0x01;                                           // Start from bottom
+	do
+	{
+		temp = SysTick->CTRL;
+	} while (temp & 0x01 && !(temp&(1 << 16)));                             // Wait time arrive
+	SysTick->CTRL = 0x00;                                            // Close the counter
+	SysTick->VAL = 0X00;                                            // Empty the counter
+}
+void LedBlink(void)
+{
+	static BitAction nOnFlag = Bit_SET;
+	GPIO_WriteBit(GPIOC, GPIO_Pin_13, nOnFlag);
+	nOnFlag = (nOnFlag == Bit_SET) ? Bit_RESET : Bit_SET;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/main.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,208 @@
+/*
+  main.c - An embedded CNC Controller with rs274/ngc (g-code) support
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+// Declare system global variable structure
+system_t sys;
+int32_t sys_position[N_AXIS];      // Real-time machine (aka home) position vector in steps.
+int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
+volatile uint8_t sys_probe_state;   // Probing state value.  Used to coordinate the probing cycle with stepper ISR.
+volatile uint8_t sys_rt_exec_state;   // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
+volatile uint8_t sys_rt_exec_alarm;   // Global realtime executor bitflag variable for setting various alarms.
+volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
+volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
+
+#if defined (STM32F103C8)
+#include "usb_lib.h"
+#ifdef USEUSB
+#include "usb_desc.h"
+#endif
+#include "hw_config.h"
+#ifdef USEUSB
+#include "usb_pwr.h"
+#endif
+#include "stm32eeprom.h"
+#ifndef USEUSB
+#include "stm32f10x_usart.h"
+void USART1_Configuration(u32 BaudRate)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+	USART_InitTypeDef USART_InitStructure;
+	NVIC_InitTypeDef NVIC_InitStructure;
+	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
+	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   
+	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+
+	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             
+	NVIC_Init(&NVIC_InitStructure);                    
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
+
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	 	
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+	USART_InitStructure.USART_BaudRate = BaudRate;	  
+	USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
+	USART_InitStructure.USART_StopBits = USART_StopBits_1;	 
+	USART_InitStructure.USART_Parity = USART_Parity_No;	 
+	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+	USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE);
+	USART_Init(USART1, &USART_InitStructure);
+	//	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
+	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
+	USART_Cmd(USART1, ENABLE);
+}
+#endif
+
+#endif
+
+
+#ifdef WIN32
+int main(int argc, char *argv[])
+#else
+int main(void)
+#endif
+{
+#if defined (STM32F103C8)
+#ifdef LEDBLINK
+	GPIO_InitTypeDef GPIO_InitStructure;
+
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
+	GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+	//Set_System();
+#ifndef USEUSB
+	USART1_Configuration(115200);
+#else
+	Set_USBClock();
+	USB_Interrupts_Config();
+	USB_Init();
+#endif
+
+#ifndef NOEEPROMSUPPORT
+	FLASH_Unlock();
+	eeprom_init();
+#endif
+	SysTick->CTRL &= 0xfffffffb;
+#endif
+  // Initialize system upon power-up.
+  serial_init();   // Setup serial baud rate and interrupts
+#ifdef WIN32
+  winserial_init(argv[1]);
+  eeprom_init();
+#endif
+  settings_init(); // Load Grbl settings from EEPROM
+  stepper_init();  // Configure stepper pins and interrupt timers
+  system_init();   // Configure pinout pins and pin-change interrupt
+
+  memset(sys_position,0,sizeof(sys_position)); // Clear machine position.
+#ifdef AVRTARGET
+  sei(); // Enable interrupts
+#endif
+  // Initialize system state.
+  #ifdef FORCE_INITIALIZATION_ALARM
+    // Force Grbl into an ALARM state upon a power-cycle or hard reset.
+    sys.state = STATE_ALARM;
+  #else
+    sys.state = STATE_IDLE;
+  #endif
+  
+  // Check for power-up and set system alarm if homing is enabled to force homing cycle
+  // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
+  // startup scripts, but allows access to settings and internal commands. Only a homing
+  // cycle '$H' or kill alarm locks '$X' will disable the alarm.
+  // NOTE: The startup script will run after successful completion of the homing cycle, but
+  // not after disabling the alarm locks. Prevents motion startup blocks from crashing into
+  // things uncontrollably. Very bad.
+  #ifdef HOMING_INIT_LOCK
+    if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; }
+  #endif
+
+  // Grbl initialization loop upon power-up or a system abort. For the latter, all processes
+  // will return to this loop to be cleanly re-initialized.
+  for(;;) {
+
+    // Reset system variables.
+    uint8_t prior_state = sys.state;
+    memset(&sys, 0, sizeof(system_t)); // Clear system struct variable.
+    sys.state = prior_state;
+    sys.f_override = DEFAULT_FEED_OVERRIDE;  // Set to 100%
+    sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100%
+    sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100%
+		memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position.
+    sys_probe_state = 0;
+    sys_rt_exec_state = 0;
+    sys_rt_exec_alarm = 0;
+    sys_rt_exec_motion_override = 0;
+    sys_rt_exec_accessory_override = 0;
+
+    // Reset Grbl primary systems.
+    serial_reset_read_buffer(); // Clear serial read buffer
+    gc_init(); // Set g-code parser to default state
+    spindle_init();
+    coolant_init();
+    limits_init();
+    probe_init();
+    plan_reset(); // Clear block buffer and planner variables
+    st_reset(); // Clear stepper subsystem variables.
+
+    // Sync cleared gcode and planner positions to current system position.
+    plan_sync_position();
+    gc_sync_position();
+
+    // Print welcome message. Indicates an initialization has occured at power-up or with a reset.
+    report_init_message();
+
+    // Start Grbl main loop. Processes program inputs and executes them.
+    protocol_main_loop();
+
+  }
+  return 0;   /* Never reached */
+}
+#if defined (STM32F103C8)
+void _delay_ms(uint32_t x)
+{
+	u32 temp;
+	SysTick->LOAD = (u32)72000000 / 8000;                     // Loading time
+	SysTick->VAL = 0x00;                                            // Empty the counter
+	SysTick->CTRL = 0x01;                                           // Start from bottom
+	do
+	{
+		temp = SysTick->CTRL;
+	} while (temp & 0x01 && !(temp&(1 << 16)));                             // Wait time arrive
+	SysTick->CTRL = 0x00;                                            // Close the counter
+	SysTick->VAL = 0X00;                                            // Empty the counter
+}
+void LedBlink(void)
+{
+	static BitAction nOnFlag = Bit_SET;
+	GPIO_WriteBit(GPIOC, GPIO_Pin_13, nOnFlag);
+	nOnFlag = (nOnFlag == Bit_SET) ? Bit_RESET : Bit_SET;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/motion_control.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,391 @@
+/*
+  motion_control.c - high level interface for issuing motion commands
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
+// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
+// (1 minute)/feed_rate time.
+// NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line
+// segments, must pass through this routine before being passed to the planner. The seperation of
+// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being
+// in the planner and to let backlash compensation or canned cycle integration simple and direct.
+void mc_line(float *target, plan_line_data_t *pl_data)
+{
+  // If enabled, check for soft limit violations. Placed here all line motions are picked up
+  // from everywhere in Grbl.
+  if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) {
+    // NOTE: Block jog state. Jogging is a special case and soft limits are handled independently.
+    if (sys.state != STATE_JOG) { limits_soft_check(target); }
+  }
+
+  // If in check gcode mode, prevent motion by blocking planner. Soft limits still work.
+  if (sys.state == STATE_CHECK_MODE) { return; }
+
+  // NOTE: Backlash compensation may be installed here. It will need direction info to track when
+  // to insert a backlash line motion(s) before the intended line motion and will require its own
+  // plan_check_full_buffer() and check for system abort loop. Also for position reporting
+  // backlash steps will need to be also tracked, which will need to be kept at a system level.
+  // There are likely some other things that will need to be tracked as well. However, we feel
+  // that backlash compensation should NOT be handled by Grbl itself, because there are a myriad
+  // of ways to implement it and can be effective or ineffective for different CNC machines. This
+  // would be better handled by the interface as a post-processor task, where the original g-code
+  // is translated and inserts backlash motions that best suits the machine.
+  // NOTE: Perhaps as a middle-ground, all that needs to be sent is a flag or special command that
+  // indicates to Grbl what is a backlash compensation motion, so that Grbl executes the move but
+  // doesn't update the machine position values. Since the position values used by the g-code
+  // parser and planner are separate from the system machine positions, this is doable.
+
+  // If the buffer is full: good! That means we are well ahead of the robot.
+  // Remain in this loop until there is room in the buffer.
+  do {
+    protocol_execute_realtime(); // Check for any run-time commands
+    if (sys.abort) { return; } // Bail, if system abort.
+    if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // Auto-cycle start when buffer is full.
+    else { break; }
+  } while (1);
+
+  // Plan and queue motion into planner buffer
+	if (plan_buffer_line(target, pl_data) == PLAN_EMPTY_BLOCK) {
+		if (bit_istrue(settings.flags, BITFLAG_LASER_MODE)) {
+			// Correctly set spindle state, if there is a coincident position passed. Forces a buffer
+			// sync while in M3 laser mode only.
+			if (pl_data->condition & PL_COND_FLAG_SPINDLE_CW) {
+				spindle_sync(PL_COND_FLAG_SPINDLE_CW, pl_data->spindle_speed);
+			}
+		}
+	}
+}
+
+
+// Execute an arc in offset mode format. position == current xyz, target == target xyz,
+// offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is
+// the direction of helical travel, radius == circle radius, isclockwise boolean. Used
+// for vector transformation direction.
+// The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance
+// of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal
+// distance from segment to the circle when the end points both lie on the circle.
+void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius,
+  uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc)
+{
+  float center_axis0 = position[axis_0] + offset[axis_0];
+  float center_axis1 = position[axis_1] + offset[axis_1];
+  float r_axis0 = -offset[axis_0];  // Radius vector from center to current location
+  float r_axis1 = -offset[axis_1];
+  float rt_axis0 = target[axis_0] - center_axis0;
+  float rt_axis1 = target[axis_1] - center_axis1;
+
+  // CCW angle between position and target from circle center. Only one atan2() trig computation required.
+  float angular_travel = atan2f(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
+  if (is_clockwise_arc) { // Correct atan2 output per direction
+    if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel -= 2*M_PI; }
+  } else {
+    if (angular_travel <= ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel += 2*M_PI; }
+  }
+
+  // NOTE: Segment end points are on the arc, which can lead to the arc diameter being smaller by up to
+  // (2x) settings.arc_tolerance. For 99% of users, this is just fine. If a different arc segment fit
+  // is desired, i.e. least-squares, midpoint on arc, just change the mm_per_arc_segment calculation.
+  // For the intended uses of Grbl, this value shouldn't exceed 2000 for the strictest of cases.
+  uint16_t segments = (uint16_t)floorf(fabsf(0.5f*angular_travel*radius) /
+                          sqrtf(settings.arc_tolerance*(2*radius - settings.arc_tolerance)) );
+
+  if (segments) {
+    // Multiply inverse feed_rate to compensate for the fact that this movement is approximated
+    // by a number of discrete segments. The inverse feed_rate should be correct for the sum of
+    // all segments.
+    if (pl_data->condition & PL_COND_FLAG_INVERSE_TIME) { 
+      pl_data->feed_rate *= segments; 
+      bit_false(pl_data->condition,PL_COND_FLAG_INVERSE_TIME); // Force as feed absolute mode over arc segments.
+    }
+    
+    float theta_per_segment = angular_travel/segments;
+    float linear_per_segment = (target[axis_linear] - position[axis_linear])/segments;
+
+    /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
+       and phi is the angle of rotation. Solution approach by Jens Geisler.
+           r_T = [cos(phi) -sin(phi);
+                  sin(phi)  cos(phi] * r ;
+
+       For arc generation, the center of the circle is the axis of rotation and the radius vector is
+       defined from the circle center to the initial position. Each line segment is formed by successive
+       vector rotations. Single precision values can accumulate error greater than tool precision in rare
+       cases. So, exact arc path correction is implemented. This approach avoids the problem of too many very
+       expensive trig operations [sin(),cos(),tan()] which can take 100-200 usec each to compute.
+
+       Small angle approximation may be used to reduce computation overhead further. A third-order approximation
+       (second order sin() has too much error) holds for most, if not, all CNC applications. Note that this
+       approximation will begin to accumulate a numerical drift error when theta_per_segment is greater than
+       ~0.25 rad(14 deg) AND the approximation is successively used without correction several dozen times. This
+       scenario is extremely unlikely, since segment lengths and theta_per_segment are automatically generated
+       and scaled by the arc tolerance setting. Only a very large arc tolerance setting, unrealistic for CNC
+       applications, would cause this numerical drift error. However, it is best to set N_ARC_CORRECTION from a
+       low of ~4 to a high of ~20 or so to avoid trig operations while keeping arc generation accurate.
+
+       This approximation also allows mc_arc to immediately insert a line segment into the planner
+       without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
+       a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead.
+       This is important when there are successive arc motions.
+    */
+    // Computes: cos_T = 1 - theta_per_segment^2/2, sin_T = theta_per_segment - theta_per_segment^3/6) in ~52usec
+    float cos_T = 2.0f - theta_per_segment*theta_per_segment;
+    float sin_T = theta_per_segment*0.16666667f*(cos_T + 4.0f);
+    cos_T *= 0.5;
+
+    float sin_Ti;
+    float cos_Ti;
+    float r_axisi;
+    uint16_t i;
+    uint8_t count = 0;
+
+    for (i = 1; i<segments; i++) { // Increment (segments-1).
+
+      if (count < N_ARC_CORRECTION) {
+        // Apply vector rotation matrix. ~40 usec
+        r_axisi = r_axis0*sin_T + r_axis1*cos_T;
+        r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
+        r_axis1 = r_axisi;
+        count++;
+      } else {
+        // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments. ~375 usec
+        // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
+        cos_Ti = cosf(i*theta_per_segment);
+        sin_Ti = sinf(i*theta_per_segment);
+        r_axis0 = -offset[axis_0]*cos_Ti + offset[axis_1]*sin_Ti;
+        r_axis1 = -offset[axis_0]*sin_Ti - offset[axis_1]*cos_Ti;
+        count = 0;
+      }
+
+      // Update arc_target location
+      position[axis_0] = center_axis0 + r_axis0;
+      position[axis_1] = center_axis1 + r_axis1;
+      position[axis_linear] += linear_per_segment;
+
+      mc_line(position, pl_data);
+
+      // Bail mid-circle on system abort. Runtime command check already performed by mc_line.
+      if (sys.abort) { return; }
+    }
+  }
+  // Ensure last segment arrives at target location.
+  mc_line(target, pl_data);
+}
+
+
+// Execute dwell in seconds.
+void mc_dwell(float seconds)
+{
+  if (sys.state == STATE_CHECK_MODE) { return; }
+  protocol_buffer_synchronize();
+  delay_sec(seconds, DELAY_MODE_DWELL);
+}
+
+
+// Perform homing cycle to locate and set machine zero. Only '$H' executes this command.
+// NOTE: There should be no motions in the buffer and Grbl must be in an idle state before
+// executing the homing cycle. This prevents incorrect buffered plans after homing.
+void mc_homing_cycle(uint8_t cycle_mask)
+{
+  // Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems
+  // with machines with limits wired on both ends of travel to one limit pin.
+  // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function.
+  #ifdef LIMITS_TWO_SWITCHES_ON_AXES
+    if (limits_get_state()) {
+      mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
+      system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT);
+      return;
+    }
+  #endif
+
+  limits_disable(); // Disable hard limits pin change register for cycle duration
+
+  // -------------------------------------------------------------------------------------
+  // Perform homing routine. NOTE: Special motion case. Only system reset works.
+  
+  #ifdef HOMING_SINGLE_AXIS_COMMANDS
+    if (cycle_mask) { limits_go_home(cycle_mask); } // Perform homing cycle based on mask.
+    else
+  #endif
+  {
+    // Search to engage all axes limit switches at faster homing seek rate.
+    limits_go_home(HOMING_CYCLE_0);  // Homing cycle 0
+    #ifdef HOMING_CYCLE_1
+      limits_go_home(HOMING_CYCLE_1);  // Homing cycle 1
+    #endif
+    #ifdef HOMING_CYCLE_2
+      limits_go_home(HOMING_CYCLE_2);  // Homing cycle 2
+    #endif
+  }
+
+  protocol_execute_realtime(); // Check for reset and set system abort.
+  if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm.
+
+  // Homing cycle complete! Setup system for normal operation.
+  // -------------------------------------------------------------------------------------
+
+  // Sync gcode parser and planner positions to homed position.
+  gc_sync_position();
+  plan_sync_position();
+
+  // If hard limits feature enabled, re-enable hard limits pin change register after homing cycle.
+#ifdef STM32F103C8
+	EXTI_ClearITPendingBit((1 << X_LIMIT_BIT) | (1 << Y_LIMIT_BIT) | (1 << Z_LIMIT_BIT));
+	NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
+	NVIC_EnableIRQ(EXTI15_10_IRQn);
+#else
+	limits_init();
+#endif
+}
+
+
+// Perform tool length probe cycle. Requires probe switch.
+// NOTE: Upon probe failure, the program will be stopped and placed into ALARM state.
+uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags)
+{
+  // TODO: Need to update this cycle so it obeys a non-auto cycle start.
+  if (sys.state == STATE_CHECK_MODE) { return(GC_PROBE_CHECK_MODE); }
+
+  // Finish all queued commands and empty planner buffer before starting probe cycle.
+  protocol_buffer_synchronize();
+  if (sys.abort) { return(GC_PROBE_ABORT); } // Return if system reset has been issued.
+
+  // Initialize probing control variables
+  uint8_t is_probe_away = bit_istrue(parser_flags, GC_PARSER_PROBE_IS_AWAY);
+  uint8_t is_no_error = bit_istrue(parser_flags, GC_PARSER_PROBE_IS_NO_ERROR);
+  sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle.
+  probe_configure_invert_mask(is_probe_away);
+
+  // After syncing, check if probe is already triggered. If so, halt and issue alarm.
+  // NOTE: This probe initialization error applies to all probing cycles.
+  if ( probe_get_state() ) { // Check probe pin state.
+    system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_INITIAL);
+    protocol_execute_realtime();
+    probe_configure_invert_mask(false); // Re-initialize invert mask before returning.
+    return(GC_PROBE_FAIL_INIT); // Nothing else to do but bail.
+  }
+
+  // Setup and queue probing motion. Auto cycle-start should not start the cycle.
+  mc_line(target, pl_data);
+
+  // Activate the probing state monitor in the stepper module.
+  sys_probe_state = PROBE_ACTIVE;
+
+  // Perform probing cycle. Wait here until probe is triggered or motion completes.
+  system_set_exec_state_flag(EXEC_CYCLE_START);
+  do {
+    protocol_execute_realtime();
+    if (sys.abort) { return(GC_PROBE_ABORT); } // Check for system abort
+  } while (sys.state != STATE_IDLE);
+
+  // Probing cycle complete!
+
+  // Set state variables and error out, if the probe failed and cycle with error is enabled.
+  if (sys_probe_state == PROBE_ACTIVE) {
+    if (is_no_error) { memcpy(sys_probe_position, sys_position, sizeof(sys_position)); }
+    else { system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_CONTACT); }
+  } else {
+    sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully.
+  }
+  sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled.
+  probe_configure_invert_mask(false); // Re-initialize invert mask.
+  protocol_execute_realtime();   // Check and execute run-time commands
+
+  // Reset the stepper and planner buffers to remove the remainder of the probe motion.
+  st_reset(); // Reset step segment buffer.
+  plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared.
+  plan_sync_position(); // Sync planner position to current machine position.
+
+  #ifdef MESSAGE_PROBE_COORDINATES
+    // All done! Output the probe position as message.
+    report_probe_parameters();
+  #endif
+
+  if (sys.probe_succeeded) { return(GC_PROBE_FOUND); } // Successful probe cycle.
+  else { return(GC_PROBE_FAIL_END); } // Failed to trigger probe within travel. With or without error.
+}
+
+#ifdef PARKING_ENABLE
+	void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data)
+	{
+		if (sys.abort) { return; } // Block during abort.
+
+		uint8_t plan_status = plan_buffer_line(parking_target, pl_data);
+
+		if (plan_status) {
+			bit_true(sys.step_control, STEP_CONTROL_EXECUTE_SYS_MOTION);
+			bit_false(sys.step_control, STEP_CONTROL_END_MOTION); // Allow parking motion to execute, if feed hold is active.
+			st_parking_setup_buffer(); // Setup step segment buffer for special parking motion case
+			st_prep_buffer();
+			st_wake_up();
+			do {
+				protocol_exec_rt_system();
+				if (sys.abort) { return; }
+			} while (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION);
+			st_parking_restore_buffer(); // Restore step segment buffer to normal run state.
+		}
+		else {
+			bit_false(sys.step_control, STEP_CONTROL_EXECUTE_SYS_MOTION);
+			protocol_exec_rt_system();
+		}
+
+	}
+#endif
+
+
+#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+void mc_override_ctrl_update(uint8_t override_state)
+{
+	// Finish all queued commands before altering override control state
+	protocol_buffer_synchronize();
+	if (sys.abort) { return; }
+	sys.override_ctrl = override_state;
+}
+#endif
+// Method to ready the system to reset by setting the realtime reset command and killing any
+// active processes in the system. This also checks if a system reset is issued while Grbl
+// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
+// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
+// realtime abort command and hard limits. So, keep to a minimum.
+void mc_reset()
+{
+  // Only this function can set the system reset. Helps prevent multiple kill calls.
+  if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) {
+    system_set_exec_state_flag(EXEC_RESET);
+
+    // Kill spindle and coolant.
+    spindle_stop();
+    coolant_stop();
+
+    // Kill steppers only if in any motion state, i.e. cycle, actively holding, or homing.
+    // NOTE: If steppers are kept enabled via the step idle delay setting, this also keeps
+    // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is
+    // violated, by which, all bets are off.
+    if ((sys.state & (STATE_CYCLE | STATE_HOMING | STATE_JOG)) ||
+    		(sys.step_control & (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION))) {
+      if (sys.state == STATE_HOMING) {
+        if (!sys_rt_exec_alarm) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_RESET); }
+      }
+      else { system_set_exec_alarm(EXEC_ALARM_ABORT_CYCLE); }
+      st_go_idle(); // Force kill steppers. Position has likely been lost.
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/motion_control.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,66 @@
+/*
+  motion_control.h - high level interface for issuing motion commands
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef motion_control_h
+#define motion_control_h
+
+
+// System motion commands must have a line number of zero.
+#define HOMING_CYCLE_LINE_NUMBER 0
+#define PARKING_MOTION_LINE_NUMBER 0
+
+#define HOMING_CYCLE_ALL  0  // Must be zero.
+#define HOMING_CYCLE_X    bit(X_AXIS)
+#define HOMING_CYCLE_Y    bit(Y_AXIS)
+#define HOMING_CYCLE_Z    bit(Z_AXIS)
+
+
+// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
+// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
+// (1 minute)/feed_rate time.
+void mc_line(float *target, plan_line_data_t *pl_data);
+
+// Execute an arc in offset mode format. position == current xyz, target == target xyz,
+// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is
+// the direction of helical travel, radius == circle radius, is_clockwise_arc boolean. Used
+// for vector transformation direction.
+void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius,
+  uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc);
+
+// Dwell for a specific number of seconds
+void mc_dwell(float seconds);
+
+// Perform homing cycle to locate machine zero. Requires limit switches.
+void mc_homing_cycle(uint8_t cycle_mask);
+
+// Perform tool length probe cycle. Requires probe switch.
+uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags);
+
+// Handles updating the override control state.
+void mc_override_ctrl_update(uint8_t override_state);
+
+// Plans and executes the single special motion case for parking. Independent of main planner buffer.
+void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data);
+
+// Performs system reset. If in motion state, kills all motion and sets system alarm.
+void mc_reset();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/nuts_bolts.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,167 @@
+/*
+  nuts_bolts.c - Shared functions
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+#define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float)
+
+
+// Extracts a floating point value from a string. The following code is based loosely on
+// the avr-libc strtod() function by Michael Stumpf and Dmitry Xmelkov and many freely
+// available conversion method examples, but has been highly optimized for Grbl. For known
+// CNC applications, the typical decimal value is expected to be in the range of E0 to E-4.
+// Scientific notation is officially not supported by g-code, and the 'E' character may
+// be a g-code word on some CNC systems. So, 'E' notation will not be recognized.
+// NOTE: Thanks to Radu-Eosif Mihailescu for identifying the issues with using strtod().
+uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr)
+{
+  char *ptr = line + *char_counter;
+  unsigned char c;
+
+  // Grab first character and increment pointer. No spaces assumed in line.
+  c = *ptr++;
+
+  // Capture initial positive/minus character
+  bool isnegative = false;
+  if (c == '-') {
+    isnegative = true;
+    c = *ptr++;
+  } else if (c == '+') {
+    c = *ptr++;
+  }
+
+  // Extract number into fast integer. Track decimal in terms of exponent value.
+  uint32_t intval = 0;
+  int8_t exp = 0;
+  uint8_t ndigit = 0;
+  bool isdecimal = false;
+  while(1) {
+    c -= '0';
+    if (c <= 9) {
+      ndigit++;
+      if (ndigit <= MAX_INT_DIGITS) {
+        if (isdecimal) { exp--; }
+        intval = (((intval << 2) + intval) << 1) + c; // intval*10 + c
+      } else {
+        if (!(isdecimal)) { exp++; }  // Drop overflow digits
+      }
+    } else if (c == (('.'-'0') & 0xff)  &&  !(isdecimal)) {
+      isdecimal = true;
+    } else {
+      break;
+    }
+    c = *ptr++;
+  }
+
+  // Return if no digits have been read.
+  if (!ndigit) { return(false); };
+
+  // Convert integer into floating point.
+  float fval;
+  fval = (float)intval;
+
+  // Apply decimal. Should perform no more than two floating point multiplications for the
+  // expected range of E0 to E-4.
+  if (fval != 0) {
+    while (exp <= -2) {
+      fval *= 0.01f;
+      exp += 2;
+    }
+    if (exp < 0) {
+      fval *= 0.1f;
+    } else if (exp > 0) {
+      do {
+        fval *= 10.0f;
+      } while (--exp > 0);
+    }
+  }
+
+  // Assign floating point value with correct sign.
+  if (isnegative) {
+    *float_ptr = -fval;
+  } else {
+    *float_ptr = fval;
+  }
+
+  *char_counter = ptr - line - 1; // Set char_counter to next statement
+
+  return(true);
+}
+
+
+// Non-blocking delay function used for general operation and suspend features.
+void delay_sec(float seconds, uint8_t mode)
+{
+	uint16_t i = (uint16_t)ceilf(1000 / DWELL_TIME_STEP*seconds);
+	while (i-- > 0) {
+		if (sys.abort) { return; }
+		if (mode == DELAY_MODE_DWELL) {
+			protocol_execute_realtime();
+		} else { // DELAY_MODE_SYS_SUSPEND
+		  // Execute rt_system() only to avoid nesting suspend loops.
+		  protocol_exec_rt_system();
+		  if (sys.suspend & SUSPEND_RESTART_RETRACT) { return; } // Bail, if safety door reopens.
+		}
+		_delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment
+	}
+}
+
+
+// Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(),
+// which only accepts constants in future compiler releases.
+void delay_ms(uint16_t ms)
+{
+  while ( ms-- ) { _delay_ms(1); }
+}
+
+
+// Simple hypotenuse computation function.
+float hypot_f(float x, float y) { return(sqrtf(x*x + y*y)); }
+
+
+float convert_delta_vector_to_unit_vector(float *vector)
+{
+  uint8_t idx;
+  float magnitude = 0.0f;
+  for (idx=0; idx<N_AXIS; idx++) {
+    if (vector[idx] != 0.0f) {
+      magnitude += vector[idx]*vector[idx];
+    }
+  }
+  magnitude = sqrtf(magnitude);
+  float inv_magnitude = 1.0f/magnitude;
+  for (idx=0; idx<N_AXIS; idx++) { vector[idx] *= inv_magnitude; }
+  return(magnitude);
+}
+
+
+float limit_value_by_axis_maximum(float *max_value, float *unit_vec)
+{
+  uint8_t idx;
+  float limit_value = SOME_LARGE_VALUE;
+  for (idx=0; idx<N_AXIS; idx++) {
+    if (unit_vec[idx] != 0) {  // Avoid divide by zero.
+      limit_value = min(limit_value,fabsf(max_value[idx]/unit_vec[idx]));
+    }
+  }
+  return(limit_value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/nuts_bolts.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,94 @@
+/*
+  nuts_bolts.h - Header file for shared definitions, variables, and functions
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef nuts_bolts_h
+#define nuts_bolts_h
+#ifdef STM32F103C8
+#include "stm32f10x_rcc.h"
+#endif
+#include "float.h"
+#define false 0
+#define true 1
+
+#define SOME_LARGE_VALUE FLT_MAX
+
+// Axis array index values. Must start with 0 and be continuous.
+#define N_AXIS 3 // Number of axes
+#define X_AXIS 0 // Axis indexing value.
+#define Y_AXIS 1
+#define Z_AXIS 2
+// #define A_AXIS 3
+
+// CoreXY motor assignments. DO NOT ALTER.
+// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations.
+#ifdef COREXY
+ #define A_MOTOR X_AXIS // Must be X_AXIS
+ #define B_MOTOR Y_AXIS // Must be Y_AXIS
+#endif
+
+// Conversions
+#define MM_PER_INCH (25.40f)
+#define INCH_PER_MM (0.0393701f)
+#define TICKS_PER_MICROSECOND (F_CPU/1000000)
+#ifdef WIN32
+extern LARGE_INTEGER Win32Frequency;
+#define F_CPU  Win32Frequency.QuadPart
+#endif
+#ifdef STM32F103C8
+#define F_CPU SystemCoreClock
+#endif
+#define DELAY_MODE_DWELL       0
+#define DELAY_MODE_SYS_SUSPEND 1
+
+// Useful macros
+#define clear_vector(a) memset(a, 0, sizeof(a))
+#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS)
+// #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS)
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS))
+
+// Bit field and masking macros
+#define bit(n) (1 << n)
+#define bit_true(x,mask) (x) |= (mask)
+#define bit_false(x,mask) (x) &= ~(mask)
+#define bit_istrue(x,mask) ((x & mask) != 0)
+#define bit_isfalse(x,mask) ((x & mask) == 0)
+
+// Read a floating point value from a string. Line points to the input buffer, char_counter
+// is the indexer pointing to the current character of the line, while float_ptr is
+// a pointer to the result variable. Returns true when it succeeds
+uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr);
+
+// Non-blocking delay function used for general operation and suspend features.
+void delay_sec(float seconds, uint8_t mode);
+
+// Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms().
+void delay_ms(uint16_t ms);
+
+
+// Computes hypotenuse, avoiding avr-gcc's bloated version and the extra error checking.
+float hypot_f(float x, float y);
+
+float convert_delta_vector_to_unit_vector(float *vector);
+float limit_value_by_axis_maximum(float *max_value, float *unit_vec);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/nuts_bolts.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,94 @@
+/*
+  nuts_bolts.h - Header file for shared definitions, variables, and functions
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef nuts_bolts_h
+#define nuts_bolts_h
+#ifdef STM32F103C8
+#include "stm32f10x_rcc.h"
+#endif
+#include "float.h"
+#define false 0
+#define true 1
+
+#define SOME_LARGE_VALUE FLT_MAX
+
+// Axis array index values. Must start with 0 and be continuous.
+#define N_AXIS 3 // Number of axes
+#define X_AXIS 0 // Axis indexing value.
+#define Y_AXIS 1
+#define Z_AXIS 2
+// #define A_AXIS 3
+
+// CoreXY motor assignments. DO NOT ALTER.
+// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations.
+#ifdef COREXY
+ #define A_MOTOR X_AXIS // Must be X_AXIS
+ #define B_MOTOR Y_AXIS // Must be Y_AXIS
+#endif
+
+// Conversions
+#define MM_PER_INCH (25.40f)
+#define INCH_PER_MM (0.0393701f)
+#define TICKS_PER_MICROSECOND (F_CPU/1000000)
+#ifdef WIN32
+extern LARGE_INTEGER Win32Frequency;
+#define F_CPU Win32Frequency.QuadPart
+#endif
+#ifdef STM32F103C8
+#define F_CPU SystemCoreClock
+#endif
+#define DELAY_MODE_DWELL       0
+#define DELAY_MODE_SYS_SUSPEND 1
+
+// Useful macros
+#define clear_vector(a) memset(a, 0, sizeof(a))
+#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS)
+// #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS)
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS))
+
+// Bit field and masking macros
+#define bit(n) (1 << n)
+#define bit_true(x,mask) (x) |= (mask)
+#define bit_false(x,mask) (x) &= ~(mask)
+#define bit_istrue(x,mask) ((x & mask) != 0)
+#define bit_isfalse(x,mask) ((x & mask) == 0)
+
+// Read a floating point value from a string. Line points to the input buffer, char_counter
+// is the indexer pointing to the current character of the line, while float_ptr is
+// a pointer to the result variable. Returns true when it succeeds
+uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr);
+
+// Non-blocking delay function used for general operation and suspend features.
+void delay_sec(float seconds, uint8_t mode);
+
+// Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms().
+void delay_ms(uint16_t ms);
+
+
+// Computes hypotenuse, avoiding avr-gcc's bloated version and the extra error checking.
+float hypot_f(float x, float y);
+
+float convert_delta_vector_to_unit_vector(float *vector);
+float limit_value_by_axis_maximum(float *max_value, float *unit_vec);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/planner.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,523 @@
+/*
+  planner.c - buffers movement commands and manages the acceleration profile plan
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+  Copyright (c) 2011 Jens Geisler
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+static plan_block_t block_buffer[BLOCK_BUFFER_SIZE];  // A ring buffer for motion instructions
+static uint8_t block_buffer_tail;     // Index of the block to process now
+static uint8_t block_buffer_head;     // Index of the next block to be pushed
+static uint8_t next_buffer_head;      // Index of the next buffer head
+static uint8_t block_buffer_planned;  // Index of the optimally planned block
+
+// Define planner variables
+typedef struct {
+  int32_t position[N_AXIS];          // The planner position of the tool in absolute steps. Kept separate
+                                     // from g-code position for movements requiring multiple line motions,
+                                     // i.e. arcs, canned cycles, and backlash compensation.
+  float previous_unit_vec[N_AXIS];   // Unit vector of previous path line segment
+  float previous_nominal_speed;  // Nominal speed of previous path line segment
+} planner_t;
+static planner_t pl;
+
+
+// Returns the index of the next block in the ring buffer. Also called by stepper segment buffer.
+uint8_t plan_next_block_index(uint8_t block_index)
+{
+  block_index++;
+  if (block_index == BLOCK_BUFFER_SIZE) { block_index = 0; }
+  return(block_index);
+}
+
+
+// Returns the index of the previous block in the ring buffer
+static uint8_t plan_prev_block_index(uint8_t block_index)
+{
+  if (block_index == 0) { block_index = BLOCK_BUFFER_SIZE; }
+  block_index--;
+  return(block_index);
+}
+
+
+/*                            PLANNER SPEED DEFINITION
+                                     +--------+   <- current->nominal_speed
+                                    /          \
+         current->entry_speed ->   +            \
+                                   |             + <- next->entry_speed (aka exit speed)
+                                   +-------------+
+                                       time -->
+
+  Recalculates the motion plan according to the following basic guidelines:
+
+    1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
+        (i.e. current->entry_speed) such that:
+      a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
+         neighboring blocks.
+      b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
+         with a maximum allowable deceleration over the block travel distance.
+      c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
+    2. Go over every block in chronological (forward) order and dial down junction speed values if
+      a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
+         acceleration over the block travel distance.
+
+  When these stages are complete, the planner will have maximized the velocity profiles throughout the all
+  of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
+  other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
+  are possible. If a new block is added to the buffer, the plan is recomputed according to the said
+  guidelines for a new optimal plan.
+
+  To increase computational efficiency of these guidelines, a set of planner block pointers have been
+  created to indicate stop-compute points for when the planner guidelines cannot logically make any further
+  changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
+  planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
+  bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
+  added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
+  them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
+  point) are all accelerating, they are all optimal and can not be altered by a new block added to the
+  planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
+  junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
+  used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
+  recomputed as stated in the general guidelines.
+
+  Planner buffer index mapping:
+  - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
+  - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
+      the buffer is full or empty. As described for standard ring buffers, this block is always empty.
+  - next_buffer_head: Points to next planner buffer block after the buffer head block. When equal to the
+      buffer tail, this indicates the buffer is full.
+  - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
+      streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
+      planner buffer that don't change with the addition of a new block, as describe above. In addition,
+      this block can never be less than block_buffer_tail and will always be pushed forward and maintain
+      this requirement when encountered by the plan_discard_current_block() routine during a cycle.
+
+  NOTE: Since the planner only computes on what's in the planner buffer, some motions with lots of short
+  line segments, like G2/3 arcs or complex curves, may seem to move slow. This is because there simply isn't
+  enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and then
+  decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this happens and
+  becomes an annoyance, there are a few simple solutions: (1) Maximize the machine acceleration. The planner
+  will be able to compute higher velocity profiles within the same combined distance. (2) Maximize line
+  motion(s) distance per block to a desired tolerance. The more combined distance the planner has to use,
+  the faster it can go. (3) Maximize the planner buffer size. This also will increase the combined distance
+  for the planner to compute over. It also increases the number of computations the planner has to perform
+  to compute an optimal plan, so select carefully. The Arduino 328p memory is already maxed out, but future
+  ARM versions should have enough memory and speed for look-ahead blocks numbering up to a hundred or more.
+
+*/
+static void planner_recalculate()
+{
+  // Initialize block index to the last block in the planner buffer.
+  uint8_t block_index = plan_prev_block_index(block_buffer_head);
+
+  // Bail. Can't do anything with one only one plan-able block.
+  if (block_index == block_buffer_planned) { return; }
+
+  // Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last
+  // block in buffer. Cease planning when the last optimal planned or tail pointer is reached.
+  // NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan.
+  float entry_speed_sqr;
+  plan_block_t *next;
+  plan_block_t *current = &block_buffer[block_index];
+
+  // Calculate maximum entry speed for last block in buffer, where the exit speed is always zero.
+  current->entry_speed_sqr = min( current->max_entry_speed_sqr, 2*current->acceleration*current->millimeters);
+
+  block_index = plan_prev_block_index(block_index);
+  if (block_index == block_buffer_planned) { // Only two plannable blocks in buffer. Reverse pass complete.
+    // Check if the first block is the tail. If so, notify stepper to update its current parameters.
+    if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); }
+  } else { // Three or more plan-able blocks
+    while (block_index != block_buffer_planned) {
+      next = current;
+      current = &block_buffer[block_index];
+      block_index = plan_prev_block_index(block_index);
+
+      // Check if next block is the tail block(=planned block). If so, update current stepper parameters.
+      if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); }
+
+      // Compute maximum entry speed decelerating over the current block from its exit speed.
+      if (current->entry_speed_sqr != current->max_entry_speed_sqr) {
+        entry_speed_sqr = next->entry_speed_sqr + 2*current->acceleration*current->millimeters;
+        if (entry_speed_sqr < current->max_entry_speed_sqr) {
+          current->entry_speed_sqr = entry_speed_sqr;
+        } else {
+          current->entry_speed_sqr = current->max_entry_speed_sqr;
+        }
+      }
+    }
+  }
+
+  // Forward Pass: Forward plan the acceleration curve from the planned pointer onward.
+  // Also scans for optimal plan breakpoints and appropriately updates the planned pointer.
+  next = &block_buffer[block_buffer_planned]; // Begin at buffer planned pointer
+  block_index = plan_next_block_index(block_buffer_planned);
+  while (block_index != block_buffer_head) {
+    current = next;
+    next = &block_buffer[block_index];
+
+    // Any acceleration detected in the forward pass automatically moves the optimal planned
+    // pointer forward, since everything before this is all optimal. In other words, nothing
+    // can improve the plan from the buffer tail to the planned pointer by logic.
+    if (current->entry_speed_sqr < next->entry_speed_sqr) {
+      entry_speed_sqr = current->entry_speed_sqr + 2*current->acceleration*current->millimeters;
+      // If true, current block is full-acceleration and we can move the planned pointer forward.
+      if (entry_speed_sqr < next->entry_speed_sqr) {
+        next->entry_speed_sqr = entry_speed_sqr; // Always <= max_entry_speed_sqr. Backward pass sets this.
+        block_buffer_planned = block_index; // Set optimal plan pointer.
+      }
+    }
+
+    // Any block set at its maximum entry speed also creates an optimal plan up to this
+    // point in the buffer. When the plan is bracketed by either the beginning of the
+    // buffer and a maximum entry speed or two maximum entry speeds, every block in between
+    // cannot logically be further improved. Hence, we don't have to recompute them anymore.
+    if (next->entry_speed_sqr == next->max_entry_speed_sqr) { block_buffer_planned = block_index; }
+    block_index = plan_next_block_index( block_index );
+  }
+}
+
+
+void plan_reset()
+{
+  memset(&pl, 0, sizeof(planner_t)); // Clear planner struct
+  plan_reset_buffer();
+}
+
+
+void plan_reset_buffer()
+{
+  block_buffer_tail = 0;
+  block_buffer_head = 0; // Empty = tail
+  next_buffer_head = 1; // plan_next_block_index(block_buffer_head)
+  block_buffer_planned = 0; // = block_buffer_tail;
+}
+
+
+void plan_discard_current_block()
+{
+  if (block_buffer_head != block_buffer_tail) { // Discard non-empty buffer.
+    uint8_t block_index = plan_next_block_index( block_buffer_tail );
+    // Push block_buffer_planned pointer, if encountered.
+    if (block_buffer_tail == block_buffer_planned) { block_buffer_planned = block_index; }
+    block_buffer_tail = block_index;
+  }
+}
+
+
+// Returns address of planner buffer block used by system motions. Called by segment generator.
+plan_block_t *plan_get_system_motion_block()
+{
+  return(&block_buffer[block_buffer_head]);
+}
+
+
+// Returns address of first planner block, if available. Called by various main program functions.
+plan_block_t *plan_get_current_block()
+{
+  if (block_buffer_head == block_buffer_tail) { return(NULL); } // Buffer empty
+  return(&block_buffer[block_buffer_tail]);
+}
+
+
+float plan_get_exec_block_exit_speed_sqr()
+{
+  uint8_t block_index = plan_next_block_index(block_buffer_tail);
+  if (block_index == block_buffer_head) { return( 0.0 ); }
+  return( block_buffer[block_index].entry_speed_sqr );
+}
+
+
+// Returns the availability status of the block ring buffer. True, if full.
+uint8_t plan_check_full_buffer()
+{
+  if (block_buffer_tail == next_buffer_head) { return(true); }
+  return(false);
+}
+
+
+// Computes and returns block nominal speed based on running condition and override values.
+// NOTE: All system motion commands, such as homing/parking, are not subject to overrides.
+float plan_compute_profile_nominal_speed(plan_block_t *block)
+{
+  float nominal_speed = block->programmed_rate;
+  if (block->condition & PL_COND_FLAG_RAPID_MOTION) { nominal_speed *= (0.01f*sys.r_override); }
+  else {
+    if (!(block->condition & PL_COND_FLAG_NO_FEED_OVERRIDE)) { nominal_speed *= (0.01f*sys.f_override); }
+    if (nominal_speed > block->rapid_rate) { nominal_speed = block->rapid_rate; }
+  }
+  if (nominal_speed > MINIMUM_FEED_RATE) { return(nominal_speed); }
+  return(MINIMUM_FEED_RATE);
+}
+
+
+// Computes and updates the max entry speed (sqr) of the block, based on the minimum of the junction's
+// previous and current nominal speeds and max junction speed.
+static void plan_compute_profile_parameters(plan_block_t *block, float nominal_speed, float prev_nominal_speed)
+{
+  // Compute the junction maximum entry based on the minimum of the junction speed and neighboring nominal speeds.
+  if (nominal_speed > prev_nominal_speed) { block->max_entry_speed_sqr = prev_nominal_speed*prev_nominal_speed; }
+  else { block->max_entry_speed_sqr = nominal_speed*nominal_speed; }
+  if (block->max_entry_speed_sqr > block->max_junction_speed_sqr) { block->max_entry_speed_sqr = block->max_junction_speed_sqr; }
+}
+
+
+// Re-calculates buffered motions profile parameters upon a motion-based override change.
+void plan_update_velocity_profile_parameters()
+{
+  uint8_t block_index = block_buffer_tail;
+  plan_block_t *block;
+  float nominal_speed;
+  float prev_nominal_speed = SOME_LARGE_VALUE; // Set high for first block nominal speed calculation.
+  while (block_index != block_buffer_head) {
+    block = &block_buffer[block_index];
+    nominal_speed = plan_compute_profile_nominal_speed(block);
+    plan_compute_profile_parameters(block, nominal_speed, prev_nominal_speed);
+    prev_nominal_speed = nominal_speed;
+    block_index = plan_next_block_index(block_index);
+  }
+  pl.previous_nominal_speed = prev_nominal_speed; // Update prev nominal speed for next incoming block.
+}
+
+
+/* Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
+   in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
+   rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
+   All position data passed to the planner must be in terms of machine position to keep the planner
+   independent of any coordinate system changes and offsets, which are handled by the g-code parser.
+   NOTE: Assumes buffer is available. Buffer checks are handled at a higher level by motion_control.
+   In other words, the buffer head is never equal to the buffer tail.  Also the feed rate input value
+   is used in three ways: as a normal feed rate if invert_feed_rate is false, as inverse time if
+   invert_feed_rate is true, or as seek/rapids rate if the feed_rate value is negative (and
+   invert_feed_rate always false).
+   The system motion condition tells the planner to plan a motion in the always unused block buffer
+   head. It avoids changing the planner state and preserves the buffer to ensure subsequent gcode
+   motions are still planned correctly, while the stepper module only points to the block buffer head
+   to execute the special system motion. */
+uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data)
+{
+  // Prepare and initialize new block. Copy relevant pl_data for block execution.
+  plan_block_t *block = &block_buffer[block_buffer_head];
+  memset(block,0,sizeof(plan_block_t)); // Zero all block values.
+  block->condition = pl_data->condition;
+  #ifdef VARIABLE_SPINDLE
+    block->spindle_speed = pl_data->spindle_speed;
+  #endif
+  #ifdef USE_LINE_NUMBERS
+    block->line_number = pl_data->line_number;
+  #endif
+
+  // Compute and store initial move distance data.
+  int32_t target_steps[N_AXIS], position_steps[N_AXIS];
+  float unit_vec[N_AXIS], delta_mm;
+  uint8_t idx;
+
+  // Copy position data based on type of motion being planned.
+  if (block->condition & PL_COND_FLAG_SYSTEM_MOTION) {
+#ifdef COREXY
+    position_steps[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position);
+    position_steps[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position);
+    position_steps[Z_AXIS] = sys_position[Z_AXIS];
+#else
+    memcpy(position_steps, sys_position, sizeof(sys_position));
+#endif
+  }
+  else { memcpy(position_steps, pl.position, sizeof(pl.position)); }
+
+  #ifdef COREXY
+    target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]);
+    target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]);
+    block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) + (target_steps[Y_AXIS]-position_steps[Y_AXIS]));
+    block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) - (target_steps[Y_AXIS]-position_steps[Y_AXIS]));
+  #endif
+
+  for (idx=0; idx<N_AXIS; idx++) {
+    // Calculate target position in absolute steps, number of steps for each axis, and determine max step events.
+    // Also, compute individual axes distance for move and prep unit vector calculations.
+    // NOTE: Computes true distance from converted step values.
+    #ifdef COREXY
+      if ( !(idx == A_MOTOR) && !(idx == B_MOTOR) ) {
+        target_steps[idx] = lroundf(target[idx]*settings.steps_per_mm[idx]);
+        block->steps[idx] = fabsf(target_steps[idx]-position_steps[idx]);
+      }
+      block->step_event_count = max(block->step_event_count, block->steps[idx]);
+      if (idx == A_MOTOR) {
+        delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] + target_steps[Y_AXIS]-position_steps[Y_AXIS])/settings.steps_per_mm[idx];
+      } else if (idx == B_MOTOR) {
+        delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] - target_steps[Y_AXIS]+position_steps[Y_AXIS])/settings.steps_per_mm[idx];
+      } else {
+        delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx];
+      }
+    #else
+      target_steps[idx] = lroundf(target[idx]*settings.steps_per_mm[idx]);
+      block->steps[idx] = fabsf(target_steps[idx]-position_steps[idx]);
+      block->step_event_count = max(block->step_event_count, block->steps[idx]);
+      delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx];
+	  #endif
+    unit_vec[idx] = delta_mm; // Store unit vector numerator
+
+    // Set direction bits. Bit enabled always means direction is negative.
+    if (delta_mm < 0.0f ) { block->direction_bits |= direction_pin_mask[idx]; }
+  }
+
+  // Bail if this is a zero-length block. Highly unlikely to occur.
+  if (block->step_event_count == 0) { return(PLAN_EMPTY_BLOCK); }
+
+  // Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled
+  // down such that no individual axes maximum values are exceeded with respect to the line direction.
+  // NOTE: This calculation assumes all axes are orthogonal (Cartesian) and works with ABC-axes,
+  // if they are also orthogonal/independent. Operates on the absolute value of the unit vector.
+  block->millimeters = convert_delta_vector_to_unit_vector(unit_vec);
+  block->acceleration = limit_value_by_axis_maximum(settings.acceleration, unit_vec);
+  block->rapid_rate = limit_value_by_axis_maximum(settings.max_rate, unit_vec);
+
+  // Store programmed rate.
+  if (block->condition & PL_COND_FLAG_RAPID_MOTION) { block->programmed_rate = block->rapid_rate; }
+  else { 
+    block->programmed_rate = pl_data->feed_rate;
+    if (block->condition & PL_COND_FLAG_INVERSE_TIME) { block->programmed_rate *= block->millimeters; }
+  }
+
+  // TODO: Need to check this method handling zero junction speeds when starting from rest.
+  if ((block_buffer_head == block_buffer_tail) || (block->condition & PL_COND_FLAG_SYSTEM_MOTION)) {
+
+    // Initialize block entry speed as zero. Assume it will be starting from rest. Planner will correct this later.
+    // If system motion, the system motion block always is assumed to start from rest and end at a complete stop.
+    block->entry_speed_sqr = 0.0f;
+    block->max_junction_speed_sqr = 0.0f; // Starting from rest. Enforce start from zero velocity.
+
+  } else {
+    // Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
+    // Let a circle be tangent to both previous and current path line segments, where the junction
+    // deviation is defined as the distance from the junction to the closest edge of the circle,
+    // colinear with the circle center. The circular segment joining the two paths represents the
+    // path of centripetal acceleration. Solve for max velocity based on max acceleration about the
+    // radius of the circle, defined indirectly by junction deviation. This may be also viewed as
+    // path width or max_jerk in the previous Grbl version. This approach does not actually deviate
+    // from path, but used as a robust way to compute cornering speeds, as it takes into account the
+    // nonlinearities of both the junction angle and junction velocity.
+    //
+    // NOTE: If the junction deviation value is finite, Grbl executes the motions in an exact path
+    // mode (G61). If the junction deviation value is zero, Grbl will execute the motion in an exact
+    // stop mode (G61.1) manner. In the future, if continuous mode (G64) is desired, the math here
+    // is exactly the same. Instead of motioning all the way to junction point, the machine will
+    // just follow the arc circle defined here. The Arduino doesn't have the CPU cycles to perform
+    // a continuous mode path, but ARM-based microcontrollers most certainly do.
+    //
+    // NOTE: The max junction speed is a fixed value, since machine acceleration limits cannot be
+    // changed dynamically during operation nor can the line move geometry. This must be kept in
+    // memory in the event of a feedrate override changing the nominal speeds of blocks, which can
+    // change the overall maximum entry speed conditions of all blocks.
+
+    float junction_unit_vec[N_AXIS];
+    float junction_cos_theta = 0.0f;
+    for (idx=0; idx<N_AXIS; idx++) {
+      junction_cos_theta -= pl.previous_unit_vec[idx]*unit_vec[idx];
+      junction_unit_vec[idx] = unit_vec[idx]-pl.previous_unit_vec[idx];
+    }
+
+    // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
+    if (junction_cos_theta > 0.999999f) {
+      //  For a 0 degree acute junction, just set minimum junction speed.
+      block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED;
+    } else {
+      if (junction_cos_theta < -0.999999f) {
+        // Junction is a straight line or 180 degrees. Junction speed is infinite.
+        block->max_junction_speed_sqr = SOME_LARGE_VALUE;
+      } else {
+        convert_delta_vector_to_unit_vector(junction_unit_vec);
+        float junction_acceleration = limit_value_by_axis_maximum(settings.acceleration, junction_unit_vec);
+        float sin_theta_d2 = sqrtf(0.5f*(1.0f-junction_cos_theta)); // Trig half angle identity. Always positive.
+        block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED,
+                       (junction_acceleration * settings.junction_deviation * sin_theta_d2)/(1.0f-sin_theta_d2) );
+      }
+    }
+  }
+
+  // Block system motion from updating this data to ensure next g-code motion is computed correctly.
+  if (!(block->condition & PL_COND_FLAG_SYSTEM_MOTION)) {
+    float nominal_speed = plan_compute_profile_nominal_speed(block);
+    plan_compute_profile_parameters(block, nominal_speed, pl.previous_nominal_speed);
+    pl.previous_nominal_speed = nominal_speed;
+
+    // Update previous path unit_vector and planner position.
+    memcpy(pl.previous_unit_vec, unit_vec, sizeof(unit_vec)); // pl.previous_unit_vec[] = unit_vec[]
+    memcpy(pl.position, target_steps, sizeof(target_steps)); // pl.position[] = target_steps[]
+
+    // New block is all set. Update buffer head and next buffer head indices.
+    block_buffer_head = next_buffer_head;
+    next_buffer_head = plan_next_block_index(block_buffer_head);
+
+    // Finish up by recalculating the plan with the new block.
+    planner_recalculate();
+  }
+  return(PLAN_OK);
+}
+
+
+// Reset the planner position vectors. Called by the system abort/initialization routine.
+void plan_sync_position()
+{
+  // TODO: For motor configurations not in the same coordinate frame as the machine position,
+  // this function needs to be updated to accomodate the difference.
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    #ifdef COREXY
+      if (idx==X_AXIS) {
+        pl.position[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position);
+      } else if (idx==Y_AXIS) {
+        pl.position[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position);
+      } else {
+        pl.position[idx] = sys_position[idx];
+      }
+    #else
+      pl.position[idx] = sys_position[idx];
+    #endif
+  }
+}
+
+
+// Returns the number of available blocks are in the planner buffer.
+uint8_t plan_get_block_buffer_available()
+{
+  if (block_buffer_head >= block_buffer_tail) { return((BLOCK_BUFFER_SIZE-1)-(block_buffer_head-block_buffer_tail)); }
+  return((block_buffer_tail-block_buffer_head-1));
+}
+
+
+// Returns the number of active blocks are in the planner buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
+uint8_t plan_get_block_buffer_count()
+{
+  if (block_buffer_head >= block_buffer_tail) { return(block_buffer_head-block_buffer_tail); }
+  return(BLOCK_BUFFER_SIZE - (block_buffer_tail-block_buffer_head));
+}
+
+
+// Re-initialize buffer plan with a partially completed block, assumed to exist at the buffer tail.
+// Called after a steppers have come to a complete stop for a feed hold and the cycle is stopped.
+void plan_cycle_reinitialize()
+{
+  // Re-plan from a complete stop. Reset planner entry speeds and buffer planned pointer.
+  st_update_plan_block_parameters();
+  block_buffer_planned = block_buffer_tail;
+  planner_recalculate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/planner.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,523 @@
+/*
+  planner.c - buffers movement commands and manages the acceleration profile plan
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+  Copyright (c) 2011 Jens Geisler
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+static plan_block_t block_buffer[BLOCK_BUFFER_SIZE];  // A ring buffer for motion instructions
+static uint8_t block_buffer_tail;     // Index of the block to process now
+static uint8_t block_buffer_head;     // Index of the next block to be pushed
+static uint8_t next_buffer_head;      // Index of the next buffer head
+static uint8_t block_buffer_planned;  // Index of the optimally planned block
+
+// Define planner variables
+typedef struct {
+  int32_t position[N_AXIS];          // The planner position of the tool in absolute steps. Kept separate
+                                     // from g-code position for movements requiring multiple line motions,
+                                     // i.e. arcs, canned cycles, and backlash compensation.
+  float previous_unit_vec[N_AXIS];   // Unit vector of previous path line segment
+  float previous_nominal_speed;  // Nominal speed of previous path line segment
+} planner_t;
+static planner_t pl;
+
+
+// Returns the index of the next block in the ring buffer. Also called by stepper segment buffer.
+uint8_t plan_next_block_index(uint8_t block_index)
+{
+  block_index++;
+  if (block_index == BLOCK_BUFFER_SIZE) { block_index = 0; }
+  return(block_index);
+}
+
+
+// Returns the index of the previous block in the ring buffer
+static uint8_t plan_prev_block_index(uint8_t block_index)
+{
+  if (block_index == 0) { block_index = BLOCK_BUFFER_SIZE; }
+  block_index--;
+  return(block_index);
+}
+
+
+/*                            PLANNER SPEED DEFINITION
+                                     +--------+   <- current->nominal_speed
+                                    /          \
+         current->entry_speed ->   +            \
+                                   |             + <- next->entry_speed (aka exit speed)
+                                   +-------------+
+                                       time -->
+
+  Recalculates the motion plan according to the following basic guidelines:
+
+    1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
+        (i.e. current->entry_speed) such that:
+      a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
+         neighboring blocks.
+      b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
+         with a maximum allowable deceleration over the block travel distance.
+      c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
+    2. Go over every block in chronological (forward) order and dial down junction speed values if
+      a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
+         acceleration over the block travel distance.
+
+  When these stages are complete, the planner will have maximized the velocity profiles throughout the all
+  of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
+  other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
+  are possible. If a new block is added to the buffer, the plan is recomputed according to the said
+  guidelines for a new optimal plan.
+
+  To increase computational efficiency of these guidelines, a set of planner block pointers have been
+  created to indicate stop-compute points for when the planner guidelines cannot logically make any further
+  changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
+  planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
+  bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
+  added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
+  them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
+  point) are all accelerating, they are all optimal and can not be altered by a new block added to the
+  planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
+  junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
+  used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
+  recomputed as stated in the general guidelines.
+
+  Planner buffer index mapping:
+  - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
+  - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
+      the buffer is full or empty. As described for standard ring buffers, this block is always empty.
+  - next_buffer_head: Points to next planner buffer block after the buffer head block. When equal to the
+      buffer tail, this indicates the buffer is full.
+  - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
+      streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
+      planner buffer that don't change with the addition of a new block, as describe above. In addition,
+      this block can never be less than block_buffer_tail and will always be pushed forward and maintain
+      this requirement when encountered by the plan_discard_current_block() routine during a cycle.
+
+  NOTE: Since the planner only computes on what's in the planner buffer, some motions with lots of short
+  line segments, like G2/3 arcs or complex curves, may seem to move slow. This is because there simply isn't
+  enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and then
+  decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this happens and
+  becomes an annoyance, there are a few simple solutions: (1) Maximize the machine acceleration. The planner
+  will be able to compute higher velocity profiles within the same combined distance. (2) Maximize line
+  motion(s) distance per block to a desired tolerance. The more combined distance the planner has to use,
+  the faster it can go. (3) Maximize the planner buffer size. This also will increase the combined distance
+  for the planner to compute over. It also increases the number of computations the planner has to perform
+  to compute an optimal plan, so select carefully. The Arduino 328p memory is already maxed out, but future
+  ARM versions should have enough memory and speed for look-ahead blocks numbering up to a hundred or more.
+
+*/
+static void planner_recalculate()
+{
+  // Initialize block index to the last block in the planner buffer.
+  uint8_t block_index = plan_prev_block_index(block_buffer_head);
+
+  // Bail. Can't do anything with one only one plan-able block.
+  if (block_index == block_buffer_planned) { return; }
+
+  // Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last
+  // block in buffer. Cease planning when the last optimal planned or tail pointer is reached.
+  // NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan.
+  float entry_speed_sqr;
+  plan_block_t *next;
+  plan_block_t *current = &block_buffer[block_index];
+
+  // Calculate maximum entry speed for last block in buffer, where the exit speed is always zero.
+  current->entry_speed_sqr = min( current->max_entry_speed_sqr, 2*current->acceleration*current->millimeters);
+
+  block_index = plan_prev_block_index(block_index);
+  if (block_index == block_buffer_planned) { // Only two plannable blocks in buffer. Reverse pass complete.
+    // Check if the first block is the tail. If so, notify stepper to update its current parameters.
+    if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); }
+  } else { // Three or more plan-able blocks
+    while (block_index != block_buffer_planned) {
+      next = current;
+      current = &block_buffer[block_index];
+      block_index = plan_prev_block_index(block_index);
+
+      // Check if next block is the tail block(=planned block). If so, update current stepper parameters.
+      if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); }
+
+      // Compute maximum entry speed decelerating over the current block from its exit speed.
+      if (current->entry_speed_sqr != current->max_entry_speed_sqr) {
+        entry_speed_sqr = next->entry_speed_sqr + 2*current->acceleration*current->millimeters;
+        if (entry_speed_sqr < current->max_entry_speed_sqr) {
+          current->entry_speed_sqr = entry_speed_sqr;
+        } else {
+          current->entry_speed_sqr = current->max_entry_speed_sqr;
+        }
+      }
+    }
+  }
+
+  // Forward Pass: Forward plan the acceleration curve from the planned pointer onward.
+  // Also scans for optimal plan breakpoints and appropriately updates the planned pointer.
+  next = &block_buffer[block_buffer_planned]; // Begin at buffer planned pointer
+  block_index = plan_next_block_index(block_buffer_planned);
+  while (block_index != block_buffer_head) {
+    current = next;
+    next = &block_buffer[block_index];
+
+    // Any acceleration detected in the forward pass automatically moves the optimal planned
+    // pointer forward, since everything before this is all optimal. In other words, nothing
+    // can improve the plan from the buffer tail to the planned pointer by logic.
+    if (current->entry_speed_sqr < next->entry_speed_sqr) {
+      entry_speed_sqr = current->entry_speed_sqr + 2*current->acceleration*current->millimeters;
+      // If true, current block is full-acceleration and we can move the planned pointer forward.
+      if (entry_speed_sqr < next->entry_speed_sqr) {
+        next->entry_speed_sqr = entry_speed_sqr; // Always <= max_entry_speed_sqr. Backward pass sets this.
+        block_buffer_planned = block_index; // Set optimal plan pointer.
+      }
+    }
+
+    // Any block set at its maximum entry speed also creates an optimal plan up to this
+    // point in the buffer. When the plan is bracketed by either the beginning of the
+    // buffer and a maximum entry speed or two maximum entry speeds, every block in between
+    // cannot logically be further improved. Hence, we don't have to recompute them anymore.
+    if (next->entry_speed_sqr == next->max_entry_speed_sqr) { block_buffer_planned = block_index; }
+    block_index = plan_next_block_index( block_index );
+  }
+}
+
+
+void plan_reset()
+{
+  memset(&pl, 0, sizeof(planner_t)); // Clear planner struct
+  plan_reset_buffer();
+}
+
+
+void plan_reset_buffer()
+{
+  block_buffer_tail = 0;
+  block_buffer_head = 0; // Empty = tail
+  next_buffer_head = 1; // plan_next_block_index(block_buffer_head)
+  block_buffer_planned = 0; // = block_buffer_tail;
+}
+
+
+void plan_discard_current_block()
+{
+  if (block_buffer_head != block_buffer_tail) { // Discard non-empty buffer.
+    uint8_t block_index = plan_next_block_index( block_buffer_tail );
+    // Push block_buffer_planned pointer, if encountered.
+    if (block_buffer_tail == block_buffer_planned) { block_buffer_planned = block_index; }
+    block_buffer_tail = block_index;
+  }
+}
+
+
+// Returns address of planner buffer block used by system motions. Called by segment generator.
+plan_block_t *plan_get_system_motion_block()
+{
+  return(&block_buffer[block_buffer_head]);
+}
+
+
+// Returns address of first planner block, if available. Called by various main program functions.
+plan_block_t *plan_get_current_block()
+{
+  if (block_buffer_head == block_buffer_tail) { return(NULL); } // Buffer empty
+  return(&block_buffer[block_buffer_tail]);
+}
+
+
+float plan_get_exec_block_exit_speed_sqr()
+{
+  uint8_t block_index = plan_next_block_index(block_buffer_tail);
+  if (block_index == block_buffer_head) { return( 0.0 ); }
+  return( block_buffer[block_index].entry_speed_sqr );
+}
+
+
+// Returns the availability status of the block ring buffer. True, if full.
+uint8_t plan_check_full_buffer()
+{
+  if (block_buffer_tail == next_buffer_head) { return(true); }
+  return(false);
+}
+
+
+// Computes and returns block nominal speed based on running condition and override values.
+// NOTE: All system motion commands, such as homing/parking, are not subject to overrides.
+float plan_compute_profile_nominal_speed(plan_block_t *block)
+{
+  float nominal_speed = block->programmed_rate;
+  if (block->condition & PL_COND_FLAG_RAPID_MOTION) { nominal_speed *= (0.01f*sys.r_override); }
+  else {
+    if (!(block->condition & PL_COND_FLAG_NO_FEED_OVERRIDE)) { nominal_speed *= (0.01f*sys.f_override); }
+    if (nominal_speed > block->rapid_rate) { nominal_speed = block->rapid_rate; }
+  }
+  if (nominal_speed > MINIMUM_FEED_RATE) { return(nominal_speed); }
+  return(MINIMUM_FEED_RATE);
+}
+
+
+// Computes and updates the max entry speed (sqr) of the block, based on the minimum of the junction's
+// previous and current nominal speeds and max junction speed.
+static void plan_compute_profile_parameters(plan_block_t *block, float nominal_speed, float prev_nominal_speed)
+{
+  // Compute the junction maximum entry based on the minimum of the junction speed and neighboring nominal speeds.
+  if (nominal_speed > prev_nominal_speed) { block->max_entry_speed_sqr = prev_nominal_speed*prev_nominal_speed; }
+  else { block->max_entry_speed_sqr = nominal_speed*nominal_speed; }
+  if (block->max_entry_speed_sqr > block->max_junction_speed_sqr) { block->max_entry_speed_sqr = block->max_junction_speed_sqr; }
+}
+
+
+// Re-calculates buffered motions profile parameters upon a motion-based override change.
+void plan_update_velocity_profile_parameters()
+{
+  uint8_t block_index = block_buffer_tail;
+  plan_block_t *block;
+  float nominal_speed;
+  float prev_nominal_speed = SOME_LARGE_VALUE; // Set high for first block nominal speed calculation.
+  while (block_index != block_buffer_head) {
+    block = &block_buffer[block_index];
+    nominal_speed = plan_compute_profile_nominal_speed(block);
+    plan_compute_profile_parameters(block, nominal_speed, prev_nominal_speed);
+    prev_nominal_speed = nominal_speed;
+    block_index = plan_next_block_index(block_index);
+  }
+  pl.previous_nominal_speed = prev_nominal_speed; // Update prev nominal speed for next incoming block.
+}
+
+
+/* Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
+   in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
+   rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
+   All position data passed to the planner must be in terms of machine position to keep the planner
+   independent of any coordinate system changes and offsets, which are handled by the g-code parser.
+   NOTE: Assumes buffer is available. Buffer checks are handled at a higher level by motion_control.
+   In other words, the buffer head is never equal to the buffer tail.  Also the feed rate input value
+   is used in three ways: as a normal feed rate if invert_feed_rate is false, as inverse time if
+   invert_feed_rate is true, or as seek/rapids rate if the feed_rate value is negative (and
+   invert_feed_rate always false).
+   The system motion condition tells the planner to plan a motion in the always unused block buffer
+   head. It avoids changing the planner state and preserves the buffer to ensure subsequent gcode
+   motions are still planned correctly, while the stepper module only points to the block buffer head
+   to execute the special system motion. */
+uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data)
+{
+  // Prepare and initialize new block. Copy relevant pl_data for block execution.
+  plan_block_t *block = &block_buffer[block_buffer_head];
+  memset(block,0,sizeof(plan_block_t)); // Zero all block values.
+  block->condition = pl_data->condition;
+  #ifdef VARIABLE_SPINDLE
+    block->spindle_speed = pl_data->spindle_speed;
+  #endif
+  #ifdef USE_LINE_NUMBERS
+    block->line_number = pl_data->line_number;
+  #endif
+
+  // Compute and store initial move distance data.
+  int32_t target_steps[N_AXIS], position_steps[N_AXIS];
+  float unit_vec[N_AXIS], delta_mm;
+  uint8_t idx;
+
+  // Copy position data based on type of motion being planned.
+  if (block->condition & PL_COND_FLAG_SYSTEM_MOTION) {
+#ifdef COREXY
+    position_steps[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position);
+    position_steps[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position);
+    position_steps[Z_AXIS] = sys_position[Z_AXIS];
+#else
+    memcpy(position_steps, sys_position, sizeof(sys_position));
+#endif
+  }
+  else { memcpy(position_steps, pl.position, sizeof(pl.position)); }
+
+  #ifdef COREXY
+    target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]);
+    target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]);
+    block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) + (target_steps[Y_AXIS]-position_steps[Y_AXIS]));
+    block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) - (target_steps[Y_AXIS]-position_steps[Y_AXIS]));
+  #endif
+
+  for (idx=0; idx<N_AXIS; idx++) {
+    // Calculate target position in absolute steps, number of steps for each axis, and determine max step events.
+    // Also, compute individual axes distance for move and prep unit vector calculations.
+    // NOTE: Computes true distance from converted step values.
+    #ifdef COREXY
+      if ( !(idx == A_MOTOR) && !(idx == B_MOTOR) ) {
+        target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]);
+        block->steps[idx] = labs(target_steps[idx]-position_steps[idx]);
+      }
+      block->step_event_count = max(block->step_event_count, block->steps[idx]);
+      if (idx == A_MOTOR) {
+        delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] + target_steps[Y_AXIS]-position_steps[Y_AXIS])/settings.steps_per_mm[idx];
+      } else if (idx == B_MOTOR) {
+        delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] - target_steps[Y_AXIS]+position_steps[Y_AXIS])/settings.steps_per_mm[idx];
+      } else {
+        delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx];
+      }
+    #else
+      target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]);
+      block->steps[idx] = labs(target_steps[idx]-position_steps[idx]);
+      block->step_event_count = max(block->step_event_count, block->steps[idx]);
+      delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx];
+	  #endif
+    unit_vec[idx] = delta_mm; // Store unit vector numerator
+
+    // Set direction bits. Bit enabled always means direction is negative.
+    if (delta_mm < 0.0f ) { block->direction_bits |= direction_pin_mask[idx]; }
+  }
+
+  // Bail if this is a zero-length block. Highly unlikely to occur.
+  if (block->step_event_count == 0) { return(PLAN_EMPTY_BLOCK); }
+
+  // Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled
+  // down such that no individual axes maximum values are exceeded with respect to the line direction.
+  // NOTE: This calculation assumes all axes are orthogonal (Cartesian) and works with ABC-axes,
+  // if they are also orthogonal/independent. Operates on the absolute value of the unit vector.
+  block->millimeters = convert_delta_vector_to_unit_vector(unit_vec);
+  block->acceleration = limit_value_by_axis_maximum(settings.acceleration, unit_vec);
+  block->rapid_rate = limit_value_by_axis_maximum(settings.max_rate, unit_vec);
+
+  // Store programmed rate.
+  if (block->condition & PL_COND_FLAG_RAPID_MOTION) { block->programmed_rate = block->rapid_rate; }
+  else { 
+    block->programmed_rate = pl_data->feed_rate;
+    if (block->condition & PL_COND_FLAG_INVERSE_TIME) { block->programmed_rate *= block->millimeters; }
+  }
+
+  // TODO: Need to check this method handling zero junction speeds when starting from rest.
+  if ((block_buffer_head == block_buffer_tail) || (block->condition & PL_COND_FLAG_SYSTEM_MOTION)) {
+
+    // Initialize block entry speed as zero. Assume it will be starting from rest. Planner will correct this later.
+    // If system motion, the system motion block always is assumed to start from rest and end at a complete stop.
+    block->entry_speed_sqr = 0.0f;
+    block->max_junction_speed_sqr = 0.0f; // Starting from rest. Enforce start from zero velocity.
+
+  } else {
+    // Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
+    // Let a circle be tangent to both previous and current path line segments, where the junction
+    // deviation is defined as the distance from the junction to the closest edge of the circle,
+    // colinear with the circle center. The circular segment joining the two paths represents the
+    // path of centripetal acceleration. Solve for max velocity based on max acceleration about the
+    // radius of the circle, defined indirectly by junction deviation. This may be also viewed as
+    // path width or max_jerk in the previous Grbl version. This approach does not actually deviate
+    // from path, but used as a robust way to compute cornering speeds, as it takes into account the
+    // nonlinearities of both the junction angle and junction velocity.
+    //
+    // NOTE: If the junction deviation value is finite, Grbl executes the motions in an exact path
+    // mode (G61). If the junction deviation value is zero, Grbl will execute the motion in an exact
+    // stop mode (G61.1) manner. In the future, if continuous mode (G64) is desired, the math here
+    // is exactly the same. Instead of motioning all the way to junction point, the machine will
+    // just follow the arc circle defined here. The Arduino doesn't have the CPU cycles to perform
+    // a continuous mode path, but ARM-based microcontrollers most certainly do.
+    //
+    // NOTE: The max junction speed is a fixed value, since machine acceleration limits cannot be
+    // changed dynamically during operation nor can the line move geometry. This must be kept in
+    // memory in the event of a feedrate override changing the nominal speeds of blocks, which can
+    // change the overall maximum entry speed conditions of all blocks.
+
+    float junction_unit_vec[N_AXIS];
+    float junction_cos_theta = 0.0f;
+    for (idx=0; idx<N_AXIS; idx++) {
+      junction_cos_theta -= pl.previous_unit_vec[idx]*unit_vec[idx];
+      junction_unit_vec[idx] = unit_vec[idx]-pl.previous_unit_vec[idx];
+    }
+
+    // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
+    if (junction_cos_theta > 0.999999f) {
+      //  For a 0 degree acute junction, just set minimum junction speed.
+      block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED;
+    } else {
+      if (junction_cos_theta < -0.999999f) {
+        // Junction is a straight line or 180 degrees. Junction speed is infinite.
+        block->max_junction_speed_sqr = SOME_LARGE_VALUE;
+      } else {
+        convert_delta_vector_to_unit_vector(junction_unit_vec);
+        float junction_acceleration = limit_value_by_axis_maximum(settings.acceleration, junction_unit_vec);
+        float sin_theta_d2 = sqrtf(0.5f*(1.0f-junction_cos_theta)); // Trig half angle identity. Always positive.
+        block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED,
+                       (junction_acceleration * settings.junction_deviation * sin_theta_d2)/(1.0f-sin_theta_d2) );
+      }
+    }
+  }
+
+  // Block system motion from updating this data to ensure next g-code motion is computed correctly.
+  if (!(block->condition & PL_COND_FLAG_SYSTEM_MOTION)) {
+    float nominal_speed = plan_compute_profile_nominal_speed(block);
+    plan_compute_profile_parameters(block, nominal_speed, pl.previous_nominal_speed);
+    pl.previous_nominal_speed = nominal_speed;
+
+    // Update previous path unit_vector and planner position.
+    memcpy(pl.previous_unit_vec, unit_vec, sizeof(unit_vec)); // pl.previous_unit_vec[] = unit_vec[]
+    memcpy(pl.position, target_steps, sizeof(target_steps)); // pl.position[] = target_steps[]
+
+    // New block is all set. Update buffer head and next buffer head indices.
+    block_buffer_head = next_buffer_head;
+    next_buffer_head = plan_next_block_index(block_buffer_head);
+
+    // Finish up by recalculating the plan with the new block.
+    planner_recalculate();
+  }
+  return(PLAN_OK);
+}
+
+
+// Reset the planner position vectors. Called by the system abort/initialization routine.
+void plan_sync_position()
+{
+  // TODO: For motor configurations not in the same coordinate frame as the machine position,
+  // this function needs to be updated to accomodate the difference.
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    #ifdef COREXY
+      if (idx==X_AXIS) {
+        pl.position[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position);
+      } else if (idx==Y_AXIS) {
+        pl.position[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position);
+      } else {
+        pl.position[idx] = sys_position[idx];
+      }
+    #else
+      pl.position[idx] = sys_position[idx];
+    #endif
+  }
+}
+
+
+// Returns the number of available blocks are in the planner buffer.
+uint8_t plan_get_block_buffer_available()
+{
+  if (block_buffer_head >= block_buffer_tail) { return((BLOCK_BUFFER_SIZE-1)-(block_buffer_head-block_buffer_tail)); }
+  return((block_buffer_tail-block_buffer_head-1));
+}
+
+
+// Returns the number of active blocks are in the planner buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
+uint8_t plan_get_block_buffer_count()
+{
+  if (block_buffer_head >= block_buffer_tail) { return(block_buffer_head-block_buffer_tail); }
+  return(BLOCK_BUFFER_SIZE - (block_buffer_tail-block_buffer_head));
+}
+
+
+// Re-initialize buffer plan with a partially completed block, assumed to exist at the buffer tail.
+// Called after a steppers have come to a complete stop for a feed hold and the cycle is stopped.
+void plan_cycle_reinitialize()
+{
+  // Re-plan from a complete stop. Reset planner entry speeds and buffer planned pointer.
+  st_update_plan_block_parameters();
+  block_buffer_planned = block_buffer_tail;
+  planner_recalculate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/planner.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,153 @@
+/*
+  planner.h - buffers movement commands and manages the acceleration profile plan
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef planner_h
+#define planner_h
+
+
+// The number of linear motions that can be in the plan at any give time
+#ifndef BLOCK_BUFFER_SIZE
+#ifdef AVRTARGET
+  #ifdef USE_LINE_NUMBERS
+    #define BLOCK_BUFFER_SIZE 15
+  #else
+    #define BLOCK_BUFFER_SIZE 16
+  #endif
+#else
+#define BLOCK_BUFFER_SIZE 36
+#endif
+#endif
+
+// Returned status message from planner.
+#define PLAN_OK true
+#define PLAN_EMPTY_BLOCK false
+
+// Define planner data condition flags. Used to denote running conditions of a block.
+#define PL_COND_FLAG_RAPID_MOTION      bit(0)
+#define PL_COND_FLAG_SYSTEM_MOTION     bit(1) // Single motion. Circumvents planner state. Used by home/park.
+#define PL_COND_FLAG_NO_FEED_OVERRIDE  bit(2) // Motion does not honor feed override.
+#define PL_COND_FLAG_INVERSE_TIME      bit(3) // Interprets feed rate value as inverse time when set.
+#define PL_COND_FLAG_SPINDLE_CW        bit(4)
+#define PL_COND_FLAG_SPINDLE_CCW       bit(5)
+#define PL_COND_FLAG_COOLANT_FLOOD     bit(6)
+#define PL_COND_FLAG_COOLANT_MIST      bit(7)
+#define PL_COND_MOTION_MASK    (PL_COND_FLAG_RAPID_MOTION|PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE)
+#define PL_COND_ACCESSORY_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW|PL_COND_FLAG_COOLANT_FLOOD|PL_COND_FLAG_COOLANT_MIST)
+
+
+// This struct stores a linear movement of a g-code block motion with its critical "nominal" values
+// are as specified in the source g-code.
+typedef struct {
+  // Fields used by the bresenham algorithm for tracing the line
+  // NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values.
+  uint32_t steps[N_AXIS];    // Step count along each axis
+  uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block.
+  uint8_t direction_bits;    // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
+
+  // Block condition data to ensure correct execution depending on states and overrides.
+  uint8_t condition;      // Block bitflag variable defining block run conditions. Copied from pl_line_data.
+  #ifdef USE_LINE_NUMBERS
+    int32_t line_number;  // Block line number for real-time reporting. Copied from pl_line_data.
+  #endif
+
+  // Fields used by the motion planner to manage acceleration. Some of these values may be updated
+  // by the stepper module during execution of special motion cases for replanning purposes.
+  float entry_speed_sqr;     // The current planned entry speed at block junction in (mm/min)^2
+  float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
+                             //   neighboring nominal speeds with overrides in (mm/min)^2
+  float acceleration;        // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
+  float millimeters;         // The remaining distance for this block to be executed in (mm).
+                             // NOTE: This value may be altered by stepper algorithm during execution.
+
+  // Stored rate limiting data used by planner when changes occur.
+  float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2
+  float rapid_rate;             // Axis-limit adjusted maximum rate for this block direction in (mm/min)
+  float programmed_rate;        // Programmed rate of this block (mm/min).
+
+  #ifdef VARIABLE_SPINDLE
+    // Stored spindle speed data used by spindle overrides and resuming methods.
+    float spindle_speed;    // Block spindle speed. Copied from pl_line_data.
+  #endif
+} plan_block_t;
+
+
+// Planner data prototype. Must be used when passing new motions to the planner.
+typedef struct {
+  float feed_rate;          // Desired feed rate for line motion. Value is ignored, if rapid motion.
+  float spindle_speed;      // Desired spindle speed through line motion.
+  uint8_t condition;        // Bitflag variable to indicate planner conditions. See defines above.
+  #ifdef USE_LINE_NUMBERS
+    int32_t line_number;    // Desired line number to report when executing.
+  #endif
+} plan_line_data_t;
+
+
+// Initialize and reset the motion plan subsystem
+void plan_reset(); // Reset all
+void plan_reset_buffer(); // Reset buffer only.
+
+// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
+// in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
+// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
+uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data);
+
+// Called when the current block is no longer needed. Discards the block and makes the memory
+// availible for new blocks.
+void plan_discard_current_block();
+
+// Gets the planner block for the special system motion cases. (Parking/Homing)
+plan_block_t *plan_get_system_motion_block();
+
+// Gets the current block. Returns NULL if buffer empty
+plan_block_t *plan_get_current_block();
+
+// Called periodically by step segment buffer. Mostly used internally by planner.
+uint8_t plan_next_block_index(uint8_t block_index);
+
+// Called by step segment buffer when computing executing block velocity profile.
+float plan_get_exec_block_exit_speed_sqr();
+
+// Called by main program during planner calculations and step segment buffer during initialization.
+float plan_compute_profile_nominal_speed(plan_block_t *block);
+
+// Re-calculates buffered motions profile parameters upon a motion-based override change.
+void plan_update_velocity_profile_parameters();
+
+// Reset the planner position vector (in steps)
+void plan_sync_position();
+
+// Reinitialize plan with a partially completed block
+void plan_cycle_reinitialize();
+
+// Returns the number of available blocks are in the planner buffer.
+uint8_t plan_get_block_buffer_available();
+
+// Returns the number of active blocks are in the planner buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
+uint8_t plan_get_block_buffer_count();
+
+// Returns the status of the block ring buffer. True, if buffer is full.
+uint8_t plan_check_full_buffer();
+
+void plan_get_planner_mpos(float *target);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/planner.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,149 @@
+/*
+  planner.h - buffers movement commands and manages the acceleration profile plan
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef planner_h
+#define planner_h
+
+
+// The number of linear motions that can be in the plan at any give time
+#ifndef BLOCK_BUFFER_SIZE
+  #ifdef USE_LINE_NUMBERS
+    #define BLOCK_BUFFER_SIZE 15
+  #else
+    #define BLOCK_BUFFER_SIZE 16
+  #endif
+#endif
+
+// Returned status message from planner.
+#define PLAN_OK true
+#define PLAN_EMPTY_BLOCK false
+
+// Define planner data condition flags. Used to denote running conditions of a block.
+#define PL_COND_FLAG_RAPID_MOTION      bit(0)
+#define PL_COND_FLAG_SYSTEM_MOTION     bit(1) // Single motion. Circumvents planner state. Used by home/park.
+#define PL_COND_FLAG_NO_FEED_OVERRIDE  bit(2) // Motion does not honor feed override.
+#define PL_COND_FLAG_INVERSE_TIME      bit(3) // Interprets feed rate value as inverse time when set.
+#define PL_COND_FLAG_SPINDLE_CW        bit(4)
+#define PL_COND_FLAG_SPINDLE_CCW       bit(5)
+#define PL_COND_FLAG_COOLANT_FLOOD     bit(6)
+#define PL_COND_FLAG_COOLANT_MIST      bit(7)
+#define PL_COND_MOTION_MASK    (PL_COND_FLAG_RAPID_MOTION|PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE)
+#define PL_COND_ACCESSORY_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW|PL_COND_FLAG_COOLANT_FLOOD|PL_COND_FLAG_COOLANT_MIST)
+
+
+// This struct stores a linear movement of a g-code block motion with its critical "nominal" values
+// are as specified in the source g-code.
+typedef struct {
+  // Fields used by the bresenham algorithm for tracing the line
+  // NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values.
+  uint32_t steps[N_AXIS];    // Step count along each axis
+  uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block.
+  uint8_t direction_bits;    // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
+
+  // Block condition data to ensure correct execution depending on states and overrides.
+  uint8_t condition;      // Block bitflag variable defining block run conditions. Copied from pl_line_data.
+  #ifdef USE_LINE_NUMBERS
+    int32_t line_number;  // Block line number for real-time reporting. Copied from pl_line_data.
+  #endif
+
+  // Fields used by the motion planner to manage acceleration. Some of these values may be updated
+  // by the stepper module during execution of special motion cases for replanning purposes.
+  float entry_speed_sqr;     // The current planned entry speed at block junction in (mm/min)^2
+  float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
+                             //   neighboring nominal speeds with overrides in (mm/min)^2
+  float acceleration;        // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
+  float millimeters;         // The remaining distance for this block to be executed in (mm).
+                             // NOTE: This value may be altered by stepper algorithm during execution.
+
+  // Stored rate limiting data used by planner when changes occur.
+  float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2
+  float rapid_rate;             // Axis-limit adjusted maximum rate for this block direction in (mm/min)
+  float programmed_rate;        // Programmed rate of this block (mm/min).
+
+  #ifdef VARIABLE_SPINDLE
+    // Stored spindle speed data used by spindle overrides and resuming methods.
+    float spindle_speed;    // Block spindle speed. Copied from pl_line_data.
+  #endif
+} plan_block_t;
+
+
+// Planner data prototype. Must be used when passing new motions to the planner.
+typedef struct {
+  float feed_rate;          // Desired feed rate for line motion. Value is ignored, if rapid motion.
+  float spindle_speed;      // Desired spindle speed through line motion.
+  uint8_t condition;        // Bitflag variable to indicate planner conditions. See defines above.
+  #ifdef USE_LINE_NUMBERS
+    int32_t line_number;    // Desired line number to report when executing.
+  #endif
+} plan_line_data_t;
+
+
+// Initialize and reset the motion plan subsystem
+void plan_reset(); // Reset all
+void plan_reset_buffer(); // Reset buffer only.
+
+// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
+// in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
+// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
+uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data);
+
+// Called when the current block is no longer needed. Discards the block and makes the memory
+// availible for new blocks.
+void plan_discard_current_block();
+
+// Gets the planner block for the special system motion cases. (Parking/Homing)
+plan_block_t *plan_get_system_motion_block();
+
+// Gets the current block. Returns NULL if buffer empty
+plan_block_t *plan_get_current_block();
+
+// Called periodically by step segment buffer. Mostly used internally by planner.
+uint8_t plan_next_block_index(uint8_t block_index);
+
+// Called by step segment buffer when computing executing block velocity profile.
+float plan_get_exec_block_exit_speed_sqr();
+
+// Called by main program during planner calculations and step segment buffer during initialization.
+float plan_compute_profile_nominal_speed(plan_block_t *block);
+
+// Re-calculates buffered motions profile parameters upon a motion-based override change.
+void plan_update_velocity_profile_parameters();
+
+// Reset the planner position vector (in steps)
+void plan_sync_position();
+
+// Reinitialize plan with a partially completed block
+void plan_cycle_reinitialize();
+
+// Returns the number of available blocks are in the planner buffer.
+uint8_t plan_get_block_buffer_available();
+
+// Returns the number of active blocks are in the planner buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
+uint8_t plan_get_block_buffer_count();
+
+// Returns the status of the block ring buffer. True, if buffer is full.
+uint8_t plan_check_full_buffer();
+
+void plan_get_planner_mpos(float *target);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/print.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,205 @@
+/*
+  print.c - Functions for formatting output strings
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+void printString(const char *s)
+{
+  while (*s)
+    serial_write(*s++);
+}
+
+#ifdef AVRTARGET
+// Print a string stored in PGM-memory
+void printPgmString(const char *s)
+{
+  char c;
+  while ((c = pgm_read_byte_near(s++)))
+    serial_write(c);
+}
+#endif
+
+// void printIntegerInBase(unsigned long n, unsigned long base)
+// {
+// 	unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
+// 	unsigned long i = 0;
+//
+// 	if (n == 0) {
+// 		serial_write('0');
+// 		return;
+// 	}
+//
+// 	while (n > 0) {
+// 		buf[i++] = n % base;
+// 		n /= base;
+// 	}
+//
+// 	for (; i > 0; i--)
+// 		serial_write(buf[i - 1] < 10 ?
+// 			'0' + buf[i - 1] :
+// 			'A' + buf[i - 1] - 10);
+// }
+
+
+// Prints an uint8 variable in base 10.
+void print_uint8_base10(uint8_t n)
+{
+  uint8_t digit_a = 0;
+  uint8_t digit_b = 0;
+  if (n >= 100) { // 100-255
+    digit_a = '0' + n % 10;
+    n /= 10;
+  }
+  if (n >= 10) { // 10-99
+    digit_b = '0' + n % 10;
+    n /= 10;
+  }
+  serial_write('0' + n);
+  if (digit_b) { serial_write(digit_b); }
+  if (digit_a) { serial_write(digit_a); }
+}
+
+
+// Prints an uint8 variable in base 2 with desired number of desired digits.
+void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) {
+#if defined(AVRTARGET) || defined(STM32F103C8)
+	unsigned char buf[digits];
+#endif
+#ifdef WIN32
+	unsigned char buf[20];
+#endif
+  uint8_t i = 0;
+
+  for (; i < digits; i++) {
+      buf[i] = n % 2 ;
+      n /= 2;
+  }
+
+  for (; i > 0; i--)
+      serial_write('0' + buf[i - 1]);
+}
+
+
+void print_uint32_base10(uint32_t n)
+{
+  if (n == 0) {
+    serial_write('0');
+    return;
+  }
+
+  unsigned char buf[10];
+  uint8_t i = 0;
+
+  while (n > 0) {
+    buf[i++] = n % 10;
+    n /= 10;
+  }
+
+  for (; i > 0; i--)
+    serial_write('0' + buf[i-1]);
+}
+
+
+void printInteger(long n)
+{
+  if (n < 0) {
+    serial_write('-');
+    print_uint32_base10(-n);
+  } else {
+    print_uint32_base10(n);
+  }
+}
+
+
+// Convert float to string by immediately converting to a long integer, which contains
+// more digits than a float. Number of decimal places, which are tracked by a counter,
+// may be set by the user. The integer is then efficiently converted to a string.
+// NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up
+// techniques are actually just slightly slower. Found this out the hard way.
+void printFloat(float n, uint8_t decimal_places)
+{
+  if (n < 0) {
+    serial_write('-');
+    n = -n;
+  }
+
+  uint8_t decimals = decimal_places;
+  while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4.
+    n *= 100;
+    decimals -= 2;
+  }
+  if (decimals) { n *= 10; }
+  n += 0.5; // Add rounding factor. Ensures carryover through entire value.
+
+  // Generate digits backwards and store in string.
+  unsigned char buf[13];
+  uint8_t i = 0;
+  uint32_t a = (long)n;
+  while(a > 0) {
+    buf[i++] = (a % 10) + '0'; // Get digit
+    a /= 10;
+  }
+  while (i < decimal_places) {
+     buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1)
+  }
+  if (i == decimal_places) { // Fill in leading zero, if needed.
+    buf[i++] = '0';
+  }
+
+  // Print the generated string.
+  for (; i > 0; i--) {
+    if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place.
+    serial_write(buf[i-1]);
+  }
+}
+
+
+// Floating value printing handlers for special variables types used in Grbl and are defined
+// in the config.h.
+//  - CoordValue: Handles all position or coordinate values in inches or mm reporting.
+//  - RateValue: Handles feed rate and current velocity in inches or mm reporting.
+void printFloat_CoordValue(float n) {
+  if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
+    printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH);
+  } else {
+    printFloat(n,N_DECIMAL_COORDVALUE_MM);
+  }
+}
+
+void printFloat_RateValue(float n) {
+  if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
+    printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH);
+  } else {
+    printFloat(n,N_DECIMAL_RATEVALUE_MM);
+  }
+}
+
+// Debug tool to print free memory in bytes at the called point.
+// NOTE: Keep commented unless using. Part of this function always gets compiled in.
+// void printFreeMemory()
+// {
+//   extern int __heap_start, *__brkval;
+//   uint16_t free;  // Up to 64k values.
+//   free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
+//   printInteger((int32_t)free);
+//   printString(" ");
+// }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/print.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,51 @@
+/*
+  print.h - Functions for formatting output strings
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef print_h
+#define print_h
+
+
+void printString(const char *s);
+
+void printPgmString(const char *s);
+
+void printInteger(long n);
+
+void print_uint32_base10(uint32_t n);
+
+// Prints an uint8 variable in base 10.
+void print_uint8_base10(uint8_t n);
+
+// Prints an uint8 variable in base 2 with desired number of desired digits.
+void print_uint8_base2_ndigit(uint8_t n, uint8_t digits);
+
+void printFloat(float n, uint8_t decimal_places);
+
+// Floating value printing handlers for special variables types used in Grbl.
+//  - CoordValue: Handles all position or coordinate values in inches or mm reporting.
+//  - RateValue: Handles feed rate and current velocity in inches or mm reporting.
+void printFloat_CoordValue(float n);
+void printFloat_RateValue(float n);
+
+// Debug tool to print free memory in bytes at the called point. Not used otherwise.
+void printFreeMemory();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/probe.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,91 @@
+/*
+  probe.c - code pertaining to probing methods
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+// Inverts the probe pin state depending on user settings and probing cycle mode.
+uint8_t probe_invert_mask;
+
+
+// Probe pin initialization routine.
+void probe_init()
+{
+#ifdef AVRTARGET
+  PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins
+  #ifdef DISABLE_PROBE_PIN_PULL_UP
+    PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down.
+  #else
+    PROBE_PORT |= PROBE_MASK;    // Enable internal pull-up resistors. Normal high operation.
+  #endif
+#endif
+#ifdef STM32F103C8
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_PROBE_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+#ifdef DISABLE_PROBE_PIN_PULL_UP
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+#else
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+#endif
+	GPIO_InitStructure.GPIO_Pin = PROBE_MASK;
+	GPIO_Init(PROBE_PORT, &GPIO_InitStructure);
+#endif
+  probe_configure_invert_mask(false); // Initialize invert mask.
+}
+
+
+// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to
+// appropriately set the pin logic according to setting for normal-high/normal-low operation
+// and the probing cycle modes for toward-workpiece/away-from-workpiece.
+void probe_configure_invert_mask(uint8_t is_probe_away)
+{
+  probe_invert_mask = 0; // Initialize as zero.
+  if (bit_isfalse(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { probe_invert_mask ^= PROBE_MASK; }
+  if (is_probe_away) { probe_invert_mask ^= PROBE_MASK; }
+}
+
+
+// Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor.
+uint8_t probe_get_state() 
+{ 
+#ifdef AVRTARGET
+	return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); 
+#endif
+#ifdef WIN32
+	return 0;
+#endif
+#ifdef STM32F103C8
+	return ((GPIO_ReadInputData(PROBE_PORT) & PROBE_MASK) ^ probe_invert_mask) != 0;
+#endif
+}
+
+
+// Monitors probe pin state and records the system position when detected. Called by the
+// stepper ISR per ISR tick.
+// NOTE: This function must be extremely efficient as to not bog down the stepper ISR.
+void probe_state_monitor()
+{
+  if (probe_get_state()) {
+    sys_probe_state = PROBE_OFF;
+    memcpy(sys_probe_position, sys_position, sizeof(sys_position));
+    bit_true(sys_rt_exec_state, EXEC_MOTION_CANCEL);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/probe.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,43 @@
+/*
+  probe.h - code pertaining to probing methods
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef probe_h
+#define probe_h
+
+// Values that define the probing state machine.
+#define PROBE_OFF     0 // Probing disabled or not in use. (Must be zero.)
+#define PROBE_ACTIVE  1 // Actively watching the input pin.
+
+// Probe pin initialization routine.
+void probe_init();
+
+// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to
+// appropriately set the pin logic according to setting for normal-high/normal-low operation
+// and the probing cycle modes for toward-workpiece/away-from-workpiece.
+void probe_configure_invert_mask(uint8_t is_probe_away);
+
+// Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor.
+uint8_t probe_get_state();
+
+// Monitors probe pin state and records the system position when detected. Called by the
+// stepper ISR per ISR tick.
+void probe_state_monitor();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/protocol.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,768 @@
+/*
+  protocol.c - controls Grbl execution protocol and procedures
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+// Define line flags. Includes comment type tracking and line overflow detection.
+#define LINE_FLAG_OVERFLOW bit(0)
+#define LINE_FLAG_COMMENT_PARENTHESES bit(1)
+#define LINE_FLAG_COMMENT_SEMICOLON bit(2)
+
+
+static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated.
+#ifdef LEDBLINK
+void LedBlink(void);
+#endif
+
+static void protocol_exec_rt_suspend();
+
+
+/*
+  GRBL PRIMARY LOOP:
+*/
+void protocol_main_loop()
+{
+  // Perform some machine checks to make sure everything is good to go.
+  #ifdef CHECK_LIMITS_AT_INIT
+    if (bit_istrue(settings.flags, BITFLAG_HARD_LIMIT_ENABLE)) {
+      if (limits_get_state()) {
+        sys.state = STATE_ALARM; // Ensure alarm state is active.
+        report_feedback_message(MESSAGE_CHECK_LIMITS);
+      }
+    }
+  #endif
+  // Check for and report alarm state after a reset, error, or an initial power up.
+  // NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed.
+  // Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges.
+  if (sys.state & (STATE_ALARM | STATE_SLEEP)) {
+    report_feedback_message(MESSAGE_ALARM_LOCK);
+    sys.state = STATE_ALARM; // Ensure alarm state is set.
+  } else {
+    // Check if the safety door is open.
+    sys.state = STATE_IDLE;
+    if (system_check_safety_door_ajar()) {
+      bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
+      protocol_execute_realtime(); // Enter safety door mode. Should return as IDLE state.
+    }
+    // All systems go!
+    system_execute_startup(line); // Execute startup script.
+  }
+
+  // ---------------------------------------------------------------------------------
+  // Primary loop! Upon a system abort, this exits back to main() to reset the system.
+  // This is also where Grbl idles while waiting for something to do.
+  // ---------------------------------------------------------------------------------
+
+  uint8_t line_flags = 0;
+  uint8_t char_counter = 0;
+  uint8_t c;
+  for (;;) {
+
+    // Process one line of incoming serial data, as the data becomes available. Performs an
+    // initial filtering by removing spaces and comments and capitalizing all letters.
+    while((c = serial_read()) != SERIAL_NO_DATA) {
+      if ((c == '\n') || (c == '\r')) { // End of line reached
+
+        protocol_execute_realtime(); // Runtime command check point.
+        if (sys.abort) { return; } // Bail to calling function upon system abort
+
+        line[char_counter] = 0; // Set string termination character.
+#ifdef LEDBLINK
+				LedBlink();
+#endif
+				#ifdef REPORT_ECHO_LINE_RECEIVED
+          report_echo_line_received(line);
+        #endif
+
+        // Direct and execute one line of formatted input, and report status of execution.
+        if (line_flags & LINE_FLAG_OVERFLOW) {
+          // Report line overflow error.
+          report_status_message(STATUS_OVERFLOW);
+        } else if (line[0] == 0) {
+          // Empty or comment line. For syncing purposes.
+          report_status_message(STATUS_OK);
+        } else if (line[0] == '$') {
+          // Grbl '$' system command
+          report_status_message(system_execute_line(line));
+        } else if (sys.state & (STATE_ALARM | STATE_JOG)) {
+          // Everything else is gcode. Block if in alarm or jog mode.
+          report_status_message(STATUS_SYSTEM_GC_LOCK);
+        } else {
+          // Parse and execute g-code block.
+          report_status_message(gc_execute_line(line));
+        }
+
+        // Reset tracking data for next line.
+        line_flags = 0;
+        char_counter = 0;
+
+      } else {
+
+        if (line_flags) {
+          // Throw away all (except EOL) comment characters and overflow characters.
+          if (c == ')') {
+            // End of '()' comment. Resume line allowed.
+            if (line_flags & LINE_FLAG_COMMENT_PARENTHESES) { line_flags &= ~(LINE_FLAG_COMMENT_PARENTHESES); }
+          }
+        } else {
+          if (c <= ' ') {
+            // Throw away whitepace and control characters
+          } else if (c == '/') {
+            // Block delete NOT SUPPORTED. Ignore character.
+            // NOTE: If supported, would simply need to check the system if block delete is enabled.
+          } else if (c == '(') {
+            // Enable comments flag and ignore all characters until ')' or EOL.
+            // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now.
+            // In the future, we could simply remove the items within the comments, but retain the
+            // comment control characters, so that the g-code parser can error-check it.
+            line_flags |= LINE_FLAG_COMMENT_PARENTHESES;
+          } else if (c == ';') {
+            // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST.
+            line_flags |= LINE_FLAG_COMMENT_SEMICOLON;
+          // TODO: Install '%' feature
+          // } else if (c == '%') {
+            // Program start-end percent sign NOT SUPPORTED.
+            // NOTE: This maybe installed to tell Grbl when a program is running vs manual input,
+            // where, during a program, the system auto-cycle start will continue to execute
+            // everything until the next '%' sign. This will help fix resuming issues with certain
+            // functions that empty the planner buffer to execute its task on-time.
+          } else if (char_counter >= (LINE_BUFFER_SIZE-1)) {
+            // Detect line buffer overflow and set flag.
+            line_flags |= LINE_FLAG_OVERFLOW;
+          } else if (c >= 'a' && c <= 'z') { // Upcase lowercase
+            line[char_counter++] = c-'a'+'A';
+          } else {
+            line[char_counter++] = c;
+          }
+        }
+
+      }
+    }
+
+    // If there are no more characters in the serial read buffer to be processed and executed,
+    // this indicates that g-code streaming has either filled the planner buffer or has
+    // completed. In either case, auto-cycle start, if enabled, any queued moves.
+    protocol_auto_cycle_start();
+
+    protocol_execute_realtime();  // Runtime command check point.
+    if (sys.abort) { return; } // Bail to main() program loop to reset system.
+  }
+
+  return; /* Never reached */
+}
+
+
+// Block until all buffered steps are executed or in a cycle state. Works with feed hold
+// during a synchronize call, if it should happen. Also, waits for clean cycle end.
+void protocol_buffer_synchronize()
+{
+  // If system is queued, ensure cycle resumes if the auto start flag is present.
+  protocol_auto_cycle_start();
+  do {
+    protocol_execute_realtime();   // Check and execute run-time commands
+    if (sys.abort) { return; } // Check for system abort
+  } while (plan_get_current_block() || (sys.state == STATE_CYCLE));
+}
+
+
+// Auto-cycle start triggers when there is a motion ready to execute and if the main program is not
+// actively parsing commands.
+// NOTE: This function is called from the main loop, buffer sync, and mc_line() only and executes
+// when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming
+// is finished, single commands), a command that needs to wait for the motions in the buffer to
+// execute calls a buffer sync, or the planner buffer is full and ready to go.
+void protocol_auto_cycle_start()
+{
+  if (plan_get_current_block() != NULL) { // Check if there are any blocks in the buffer.
+    system_set_exec_state_flag(EXEC_CYCLE_START); // If so, execute them!
+  }
+}
+
+
+// This function is the general interface to Grbl's real-time command execution system. It is called
+// from various check points in the main program, primarily where there may be a while loop waiting
+// for a buffer to clear space or any point where the execution time from the last check point may
+// be more than a fraction of a second. This is a way to execute realtime commands asynchronously
+// (aka multitasking) with grbl's g-code parsing and planning functions. This function also serves
+// as an interface for the interrupts to set the system realtime flags, where only the main program
+// handles them, removing the need to define more computationally-expensive volatile variables. This
+// also provides a controlled way to execute certain tasks without having two or more instances of
+// the same task, such as the planner recalculating the buffer upon a feedhold or overrides.
+// NOTE: The sys_rt_exec_state variable flags are set by any process, step or serial interrupts, pinouts,
+// limit switches, or the main program.
+void protocol_execute_realtime()
+{
+  protocol_exec_rt_system();
+  if (sys.suspend) { protocol_exec_rt_suspend(); }
+}
+
+
+// Executes run-time commands, when required. This function primarily operates as Grbl's state
+// machine and controls the various real-time features Grbl has to offer.
+// NOTE: Do not alter this unless you know exactly what you are doing!
+void protocol_exec_rt_system()
+{
+  uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times.
+  rt_exec = sys_rt_exec_alarm; // Copy volatile sys_rt_exec_alarm.
+  if (rt_exec) { // Enter only if any bit flag is true
+    // System alarm. Everything has shutdown by something that has gone severely wrong. Report
+    // the source of the error to the user. If critical, Grbl disables by entering an infinite
+    // loop until system reset/abort.
+    sys.state = STATE_ALARM; // Set system alarm state
+    report_alarm_message(rt_exec);
+    // Halt everything upon a critical event flag. Currently hard and soft limits flag this.
+    if ((rt_exec == EXEC_ALARM_HARD_LIMIT) || (rt_exec == EXEC_ALARM_SOFT_LIMIT)) {
+      report_feedback_message(MESSAGE_CRITICAL_EVENT);
+      system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset
+      do {
+        // Block everything, except reset and status reports, until user issues reset or power
+        // cycles. Hard limits typically occur while unattended or not paying attention. Gives
+        // the user and a GUI time to do what is needed before resetting, like killing the
+        // incoming stream. The same could be said about soft limits. While the position is not
+        // lost, continued streaming could cause a serious crash if by chance it gets executed.
+      } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET));
+    }
+    system_clear_exec_alarm(); // Clear alarm
+  }
+
+  rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state.
+  if (rt_exec) {
+
+    // Execute system abort.
+    if (rt_exec & EXEC_RESET) {
+      sys.abort = true;  // Only place this is set true.
+      return; // Nothing else to do but exit.
+    }
+
+    // Execute and serial print status
+    if (rt_exec & EXEC_STATUS_REPORT) {
+      report_realtime_status();
+      system_clear_exec_state_flag(EXEC_STATUS_REPORT);
+    }
+
+    // NOTE: Once hold is initiated, the system immediately enters a suspend state to block all
+    // main program processes until either reset or resumed. This ensures a hold completes safely.
+    if (rt_exec & (EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP)) {
+
+      // State check for allowable states for hold methods.
+      if (!(sys.state & (STATE_ALARM | STATE_CHECK_MODE))) {
+      
+        // If in CYCLE or JOG states, immediately initiate a motion HOLD.
+        if (sys.state & (STATE_CYCLE | STATE_JOG)) {
+          if (!(sys.suspend & (SUSPEND_MOTION_CANCEL | SUSPEND_JOG_CANCEL))) { // Block, if already holding.
+            st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.
+            sys.step_control = STEP_CONTROL_EXECUTE_HOLD; // Initiate suspend state with active flag.
+            if (sys.state == STATE_JOG) { // Jog cancelled upon any hold event, except for sleeping.
+              if (!(rt_exec & EXEC_SLEEP)) { sys.suspend |= SUSPEND_JOG_CANCEL; } 
+            }
+          }
+        }
+        // If IDLE, Grbl is not in motion. Simply indicate suspend state and hold is complete.
+        if (sys.state == STATE_IDLE) { sys.suspend = SUSPEND_HOLD_COMPLETE; }
+
+        // Execute and flag a motion cancel with deceleration and return to idle. Used primarily by probing cycle
+        // to halt and cancel the remainder of the motion.
+        if (rt_exec & EXEC_MOTION_CANCEL) {
+          // MOTION_CANCEL only occurs during a CYCLE, but a HOLD and SAFETY_DOOR may been initiated beforehand
+          // to hold the CYCLE. Motion cancel is valid for a single planner block motion only, while jog cancel
+          // will handle and clear multiple planner block motions.
+          if (!(sys.state & STATE_JOG)) { sys.suspend |= SUSPEND_MOTION_CANCEL; } // NOTE: State is STATE_CYCLE.
+        }
+
+        // Execute a feed hold with deceleration, if required. Then, suspend system.
+        if (rt_exec & EXEC_FEED_HOLD) {
+          // Block SAFETY_DOOR, JOG, and SLEEP states from changing to HOLD state.
+          if (!(sys.state & (STATE_SAFETY_DOOR | STATE_JOG | STATE_SLEEP))) { sys.state = STATE_HOLD; }
+        }
+
+        // Execute a safety door stop with a feed hold and disable spindle/coolant.
+        // NOTE: Safety door differs from feed holds by stopping everything no matter state, disables powered
+        // devices (spindle/coolant), and blocks resuming until switch is re-engaged.
+        if (rt_exec & EXEC_SAFETY_DOOR) {
+          report_feedback_message(MESSAGE_SAFETY_DOOR_AJAR);
+          // If jogging, block safety door methods until jog cancel is complete. Just flag that it happened.
+          if (!(sys.suspend & SUSPEND_JOG_CANCEL)) {
+            // Check if the safety re-opened during a restore parking motion only. Ignore if
+            // already retracting, parked or in sleep state.
+            if (sys.state == STATE_SAFETY_DOOR) {
+              if (sys.suspend & SUSPEND_INITIATE_RESTORE) { // Actively restoring
+                #ifdef PARKING_ENABLE
+                  // Set hold and reset appropriate control flags to restart parking sequence.
+                  if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) {
+                    st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.
+                    sys.step_control = (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION);
+                    sys.suspend &= ~(SUSPEND_HOLD_COMPLETE);
+                  } // else NO_MOTION is active.
+                #endif
+                sys.suspend &= ~(SUSPEND_RETRACT_COMPLETE | SUSPEND_INITIATE_RESTORE | SUSPEND_RESTORE_COMPLETE);
+                sys.suspend |= SUSPEND_RESTART_RETRACT;
+              }
+            }
+            if (sys.state != STATE_SLEEP) { sys.state = STATE_SAFETY_DOOR; }
+          }
+          // NOTE: This flag doesn't change when the door closes, unlike sys.state. Ensures any parking motions
+          // are executed if the door switch closes and the state returns to HOLD.
+          sys.suspend |= SUSPEND_SAFETY_DOOR_AJAR;
+        }
+        
+      }
+
+      if (rt_exec & EXEC_SLEEP) {
+        if (sys.state == STATE_ALARM) { sys.suspend |= (SUSPEND_RETRACT_COMPLETE|SUSPEND_HOLD_COMPLETE); }
+        sys.state = STATE_SLEEP; 
+      }
+
+      system_clear_exec_state_flag((EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP));
+    }
+
+    // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue.
+    if (rt_exec & EXEC_CYCLE_START) {
+      // Block if called at same time as the hold commands: feed hold, motion cancel, and safety door.
+      // Ensures auto-cycle-start doesn't resume a hold without an explicit user-input.
+      if (!(rt_exec & (EXEC_FEED_HOLD | EXEC_MOTION_CANCEL | EXEC_SAFETY_DOOR))) {
+        // Resume door state when parking motion has retracted and door has been closed.
+        if ((sys.state == STATE_SAFETY_DOOR) && !(sys.suspend & SUSPEND_SAFETY_DOOR_AJAR)) {
+          if (sys.suspend & SUSPEND_RESTORE_COMPLETE) {
+            sys.state = STATE_IDLE; // Set to IDLE to immediately resume the cycle.
+          } else if (sys.suspend & SUSPEND_RETRACT_COMPLETE) {
+            // Flag to re-energize powered components and restore original position, if disabled by SAFETY_DOOR.
+            // NOTE: For a safety door to resume, the switch must be closed, as indicated by HOLD state, and
+            // the retraction execution is complete, which implies the initial feed hold is not active. To
+            // restore normal operation, the restore procedures must be initiated by the following flag. Once,
+            // they are complete, it will call CYCLE_START automatically to resume and exit the suspend.
+            sys.suspend |= SUSPEND_INITIATE_RESTORE;
+          }
+        }
+        // Cycle start only when IDLE or when a hold is complete and ready to resume.
+        if ((sys.state == STATE_IDLE) || ((sys.state & STATE_HOLD) && (sys.suspend & SUSPEND_HOLD_COMPLETE))) {
+          if (sys.state == STATE_HOLD && sys.spindle_stop_ovr) {
+            sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE_CYCLE; // Set to restore in suspend routine and cycle start after.
+          } else {
+            // Start cycle only if queued motions exist in planner buffer and the motion is not canceled.
+            sys.step_control = STEP_CONTROL_NORMAL_OP; // Restore step control to normal operation
+            if (plan_get_current_block() && bit_isfalse(sys.suspend,SUSPEND_MOTION_CANCEL)) {
+              sys.suspend = SUSPEND_DISABLE; // Break suspend state.
+              sys.state = STATE_CYCLE;
+              st_prep_buffer(); // Initialize step segment buffer before beginning cycle.
+              st_wake_up();
+            } else { // Otherwise, do nothing. Set and resume IDLE state.
+              sys.suspend = SUSPEND_DISABLE; // Break suspend state.
+              sys.state = STATE_IDLE;
+            }
+          }
+        }
+      }
+      system_clear_exec_state_flag(EXEC_CYCLE_START);
+    }
+
+    if (rt_exec & EXEC_CYCLE_STOP) {
+      // Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by
+      // realtime command execution in the main program, ensuring that the planner re-plans safely.
+      // NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper
+      // cycle reinitializations. The stepper path should continue exactly as if nothing has happened.
+      // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.
+      if ((sys.state & (STATE_HOLD|STATE_SAFETY_DOOR|STATE_SLEEP)) && !(sys.soft_limit) && !(sys.suspend & SUSPEND_JOG_CANCEL)) {
+        // Hold complete. Set to indicate ready to resume.  Remain in HOLD or DOOR states until user
+        // has issued a resume command or reset.
+        plan_cycle_reinitialize();
+        if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { sys.suspend |= SUSPEND_HOLD_COMPLETE; }
+        bit_false(sys.step_control,(STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION));
+      } else {
+        // Motion complete. Includes CYCLE/JOG/HOMING states and jog cancel/motion cancel/soft limit events.
+        // NOTE: Motion and jog cancel both immediately return to idle after the hold completes.
+        if (sys.suspend & SUSPEND_JOG_CANCEL) {   // For jog cancel, flush buffers and sync positions.
+          sys.step_control = STEP_CONTROL_NORMAL_OP;
+          plan_reset();
+          st_reset();
+          gc_sync_position();
+          plan_sync_position();
+        }
+        if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) { // Only occurs when safety door opens during jog.
+          sys.suspend &= ~(SUSPEND_JOG_CANCEL);
+          sys.suspend |= SUSPEND_HOLD_COMPLETE;
+          sys.state = STATE_SAFETY_DOOR;
+        } else {
+          sys.suspend = SUSPEND_DISABLE;
+          sys.state = STATE_IDLE;
+        }
+      }
+      system_clear_exec_state_flag(EXEC_CYCLE_STOP);
+    }
+  }
+
+  // Execute overrides.
+  rt_exec = sys_rt_exec_motion_override; // Copy volatile sys_rt_exec_motion_override
+  if (rt_exec) {
+    system_clear_exec_motion_overrides(); // Clear all motion override flags.
+
+    uint8_t new_f_override =  sys.f_override;
+    if (rt_exec & EXEC_FEED_OVR_RESET) { new_f_override = DEFAULT_FEED_OVERRIDE; }
+    if (rt_exec & EXEC_FEED_OVR_COARSE_PLUS) { new_f_override += FEED_OVERRIDE_COARSE_INCREMENT; }
+    if (rt_exec & EXEC_FEED_OVR_COARSE_MINUS) { new_f_override -= FEED_OVERRIDE_COARSE_INCREMENT; }
+    if (rt_exec & EXEC_FEED_OVR_FINE_PLUS) { new_f_override += FEED_OVERRIDE_FINE_INCREMENT; }
+    if (rt_exec & EXEC_FEED_OVR_FINE_MINUS) { new_f_override -= FEED_OVERRIDE_FINE_INCREMENT; }
+    new_f_override = min(new_f_override,MAX_FEED_RATE_OVERRIDE);
+    new_f_override = max(new_f_override,MIN_FEED_RATE_OVERRIDE);
+
+    uint8_t new_r_override = sys.r_override;
+    if (rt_exec & EXEC_RAPID_OVR_RESET) { new_r_override = DEFAULT_RAPID_OVERRIDE; }
+    if (rt_exec & EXEC_RAPID_OVR_MEDIUM) { new_r_override = RAPID_OVERRIDE_MEDIUM; }
+    if (rt_exec & EXEC_RAPID_OVR_LOW) { new_r_override = RAPID_OVERRIDE_LOW; }
+
+    if ((new_f_override != sys.f_override) || (new_r_override != sys.r_override)) {
+      sys.f_override = new_f_override;
+      sys.r_override = new_r_override;
+      sys.report_ovr_counter = 0; // Set to report change immediately
+      plan_update_velocity_profile_parameters();
+      plan_cycle_reinitialize();
+    }
+  }
+
+  rt_exec = sys_rt_exec_accessory_override;
+  if (rt_exec) {
+    system_clear_exec_accessory_overrides(); // Clear all accessory override flags.
+
+    // NOTE: Unlike motion overrides, spindle overrides do not require a planner reinitialization.
+    uint8_t last_s_override =  sys.spindle_speed_ovr;
+    if (rt_exec & EXEC_SPINDLE_OVR_RESET) { last_s_override = DEFAULT_SPINDLE_SPEED_OVERRIDE; }
+    if (rt_exec & EXEC_SPINDLE_OVR_COARSE_PLUS) { last_s_override += SPINDLE_OVERRIDE_COARSE_INCREMENT; }
+    if (rt_exec & EXEC_SPINDLE_OVR_COARSE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_COARSE_INCREMENT; }
+    if (rt_exec & EXEC_SPINDLE_OVR_FINE_PLUS) { last_s_override += SPINDLE_OVERRIDE_FINE_INCREMENT; }
+    if (rt_exec & EXEC_SPINDLE_OVR_FINE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_FINE_INCREMENT; }
+    last_s_override = min(last_s_override,MAX_SPINDLE_SPEED_OVERRIDE);
+    last_s_override = max(last_s_override,MIN_SPINDLE_SPEED_OVERRIDE);
+
+    if (last_s_override != sys.spindle_speed_ovr) {
+      bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM);
+      sys.spindle_speed_ovr = last_s_override;
+      sys.report_ovr_counter = 0; // Set to report change immediately
+    }
+
+    if (rt_exec & EXEC_SPINDLE_OVR_STOP) {
+      // Spindle stop override allowed only while in HOLD state.
+      // NOTE: Report counters are set in spindle_set_state() when spindle stop is executed.
+      if (sys.state == STATE_HOLD) {
+        if (!(sys.spindle_stop_ovr)) { sys.spindle_stop_ovr = SPINDLE_STOP_OVR_INITIATE; }
+        else if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_ENABLED) { sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE; }
+      }
+    }
+
+    // NOTE: Since coolant state always performs a planner sync whenever it changes, the current
+    // run state can be determined by checking the parser state.
+    if (rt_exec & (EXEC_COOLANT_FLOOD_OVR_TOGGLE | EXEC_COOLANT_MIST_OVR_TOGGLE)) {
+      if ((sys.state == STATE_IDLE) || (sys.state & (STATE_CYCLE | STATE_HOLD))) {
+        uint8_t coolant_state = gc_state.modal.coolant;
+        #ifdef ENABLE_M7
+          if (rt_exec & EXEC_COOLANT_MIST_OVR_TOGGLE) {
+            if (coolant_state & COOLANT_MIST_ENABLE) { bit_false(coolant_state,COOLANT_MIST_ENABLE); }
+            else { coolant_state |= COOLANT_MIST_ENABLE; }
+          }
+          if (rt_exec & EXEC_COOLANT_FLOOD_OVR_TOGGLE) {
+            if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); }
+            else { coolant_state |= COOLANT_FLOOD_ENABLE; }
+          }
+        #else
+          if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); }
+          else { coolant_state |= COOLANT_FLOOD_ENABLE; }
+        #endif
+        coolant_set_state(coolant_state); // Report counter set in coolant_set_state().
+        gc_state.modal.coolant = coolant_state;
+      }
+    }
+  }
+
+  #ifdef DEBUG
+    if (sys_rt_exec_debug) {
+      report_realtime_debug();
+      sys_rt_exec_debug = 0;
+    }
+  #endif
+
+  // Reload step segment buffer
+  if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_SAFETY_DOOR | STATE_HOMING | STATE_SLEEP| STATE_JOG)) {
+    st_prep_buffer();
+  }
+
+}
+
+
+// Handles Grbl system suspend procedures, such as feed hold, safety door, and parking motion.
+// The system will enter this loop, create local variables for suspend tasks, and return to
+// whatever function that invoked the suspend, such that Grbl resumes normal operation.
+// This function is written in a way to promote custom parking motions. Simply use this as a
+// template
+static void protocol_exec_rt_suspend()
+{
+  #ifdef PARKING_ENABLE
+    // Declare and initialize parking local variables
+    float restore_target[N_AXIS];
+    float parking_target[N_AXIS];
+    float retract_waypoint = PARKING_PULLOUT_INCREMENT;
+    plan_line_data_t plan_data;
+    plan_line_data_t *pl_data = &plan_data;
+    memset(pl_data,0,sizeof(plan_line_data_t));
+    pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE);
+    #ifdef USE_LINE_NUMBERS
+      pl_data->line_number = PARKING_MOTION_LINE_NUMBER;
+    #endif
+  #endif
+
+  plan_block_t *block = plan_get_current_block();
+  uint8_t restore_condition;
+  #ifdef VARIABLE_SPINDLE
+    float restore_spindle_speed;
+    if (block == NULL) {
+      restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant);
+      restore_spindle_speed = gc_state.spindle_speed;
+    } else {
+      restore_condition = block->condition;
+      restore_spindle_speed = block->spindle_speed;
+    }
+    #ifdef DISABLE_LASER_DURING_HOLD
+      if (bit_istrue(settings.flags, BITFLAG_LASER_MODE)) {
+        system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP);
+      }
+    #endif
+  #else
+    if (block == NULL) { restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant); }
+    else { restore_condition = block->condition; }
+  #endif
+
+  while (sys.suspend) {
+
+    if (sys.abort) { return; }
+
+    // Block until initial hold is complete and the machine has stopped motion.
+    if (sys.suspend & SUSPEND_HOLD_COMPLETE) {
+
+      // Parking manager. Handles de/re-energizing, switch state checks, and parking motions for 
+      // the safety door and sleep states.
+      if (sys.state & (STATE_SAFETY_DOOR | STATE_SLEEP)) {
+      
+        // Handles retraction motions and de-energizing.
+        if (bit_isfalse(sys.suspend,SUSPEND_RETRACT_COMPLETE)) {
+
+          // Ensure any prior spindle stop override is disabled at start of safety door routine.
+          sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED;
+
+          #ifndef PARKING_ENABLE
+
+            spindle_set_state(SPINDLE_DISABLE,0.0f); // De-energize
+            coolant_set_state(COOLANT_DISABLE);     // De-energize
+
+          #else
+					
+            // Get current position and store restore location and spindle retract waypoint.
+            system_convert_array_steps_to_mpos(parking_target,sys_position);
+            if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
+              memcpy(restore_target,parking_target,sizeof(parking_target));
+              retract_waypoint += restore_target[PARKING_AXIS];
+              retract_waypoint = min(retract_waypoint,PARKING_TARGET);
+            }
+
+            // Execute slow pull-out parking retract motion. Parking requires homing enabled, the
+            // current location not exceeding the parking target location, and laser mode disabled.
+            // NOTE: State is will remain DOOR, until the de-energizing and retract is complete.
+						#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+						if ((bit_istrue(settings.flags, BITFLAG_HOMING_ENABLE)) &&
+														(parking_target[PARKING_AXIS] < PARKING_TARGET) &&
+														bit_isfalse(settings.flags, BITFLAG_LASER_MODE) &&
+														(sys.override_ctrl == OVERRIDE_PARKING_MOTION)) {
+						#else
+						if ((bit_istrue(settings.flags, BITFLAG_HOMING_ENABLE)) &&
+														(parking_target[PARKING_AXIS] < PARKING_TARGET) &&
+														bit_isfalse(settings.flags, BITFLAG_LASER_MODE)) {
+						#endif
+							// Retract spindle by pullout distance. Ensure retraction motion moves away from
+              // the workpiece and waypoint motion doesn't exceed the parking target location.
+              if (parking_target[PARKING_AXIS] < retract_waypoint) {
+                parking_target[PARKING_AXIS] = retract_waypoint;
+                pl_data->feed_rate = PARKING_PULLOUT_RATE;
+                pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Retain accessory state
+                pl_data->spindle_speed = restore_spindle_speed;
+                mc_parking_motion(parking_target, pl_data);
+              }
+
+              // NOTE: Clear accessory state after retract and after an aborted restore motion.
+              pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE);
+              pl_data->spindle_speed = 0.0f;
+              spindle_set_state(SPINDLE_DISABLE,0.0f); // De-energize
+              coolant_set_state(COOLANT_DISABLE); // De-energize
+
+              // Execute fast parking retract motion to parking target location.
+              if (parking_target[PARKING_AXIS] < PARKING_TARGET) {
+                parking_target[PARKING_AXIS] = PARKING_TARGET;
+                pl_data->feed_rate = PARKING_RATE;
+                mc_parking_motion(parking_target, pl_data);
+              }
+
+            } else {
+
+              // Parking motion not possible. Just disable the spindle and coolant.
+              // NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately.
+              spindle_set_state(SPINDLE_DISABLE,0.0f); // De-energize
+              coolant_set_state(COOLANT_DISABLE);     // De-energize
+
+            }
+
+          #endif
+
+          sys.suspend &= ~(SUSPEND_RESTART_RETRACT);
+          sys.suspend |= SUSPEND_RETRACT_COMPLETE;
+
+        } else {
+
+          
+          if (sys.state == STATE_SLEEP) {
+            report_feedback_message(MESSAGE_SLEEP_MODE);
+            // Spindle and coolant should already be stopped, but do it again just to be sure.
+            spindle_set_state(SPINDLE_DISABLE,0.0f); // De-energize
+            coolant_set_state(COOLANT_DISABLE); // De-energize
+            st_go_idle(); // Disable steppers
+            while (!(sys.abort)) { protocol_exec_rt_system(); } // Do nothing until reset.
+            return; // Abort received. Return to re-initialize.
+          }    
+          
+          // Allows resuming from parking/safety door. Actively checks if safety door is closed and ready to resume.
+          if (sys.state == STATE_SAFETY_DOOR) {
+            if (!(system_check_safety_door_ajar())) {
+              sys.suspend &= ~(SUSPEND_SAFETY_DOOR_AJAR); // Reset door ajar flag to denote ready to resume.
+            }
+          }
+
+          // Handles parking restore and safety door resume.
+          if (sys.suspend & SUSPEND_INITIATE_RESTORE) {
+
+            #ifdef PARKING_ENABLE
+              // Execute fast restore motion to the pull-out position. Parking requires homing enabled.
+              // NOTE: State is will remain DOOR, until the de-energizing and retract is complete.
+							#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+							if (((settings.flags & (BITFLAG_HOMING_ENABLE | BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) &&
+									 (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) {
+							#else
+							if ((settings.flags & (BITFLAG_HOMING_ENABLE | BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) {
+							#endif
+                // Check to ensure the motion doesn't move below pull-out position.
+                if (parking_target[PARKING_AXIS] <= PARKING_TARGET) {
+                  parking_target[PARKING_AXIS] = retract_waypoint;
+                  pl_data->feed_rate = PARKING_RATE;
+                  mc_parking_motion(parking_target, pl_data);
+                }
+              }
+            #endif
+
+            // Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle.
+            if (gc_state.modal.spindle != SPINDLE_DISABLE) {
+              // Block if safety door re-opened during prior restore actions.
+              if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
+                if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) {
+                  // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts.
+                  bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM);
+                } else {
+                  spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed);
+                  delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND);
+                }
+              }
+            }
+            if (gc_state.modal.coolant != COOLANT_DISABLE) {
+              // Block if safety door re-opened during prior restore actions.
+              if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
+                // NOTE: Laser mode will honor this delay. An exhaust system is often controlled by this pin.
+                coolant_set_state((restore_condition & (PL_COND_FLAG_COOLANT_FLOOD | PL_COND_FLAG_COOLANT_FLOOD)));
+                delay_sec(SAFETY_DOOR_COOLANT_DELAY, DELAY_MODE_SYS_SUSPEND);
+              }
+            }
+
+            #ifdef PARKING_ENABLE
+              // Execute slow plunge motion from pull-out position to resume position.
+						#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+						if (((settings.flags & (BITFLAG_HOMING_ENABLE | BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) &&
+									(sys.override_ctrl == OVERRIDE_PARKING_MOTION)) {
+							#else
+							if ((settings.flags & (BITFLAG_HOMING_ENABLE | BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) {
+							#endif
+                // Block if safety door re-opened during prior restore actions.
+                if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
+                  // Regardless if the retract parking motion was a valid/safe motion or not, the
+                  // restore parking motion should logically be valid, either by returning to the
+                  // original position through valid machine space or by not moving at all.
+                  pl_data->feed_rate = PARKING_PULLOUT_RATE;
+									pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Restore accessory state
+									pl_data->spindle_speed = restore_spindle_speed;
+                  mc_parking_motion(restore_target, pl_data);
+                }
+              }
+            #endif
+
+            if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
+              sys.suspend |= SUSPEND_RESTORE_COMPLETE;
+              system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program.
+            }
+          }
+
+        }
+
+
+      } else {
+
+        // Feed hold manager. Controls spindle stop override states.
+        // NOTE: Hold ensured as completed by condition check at the beginning of suspend routine.
+        if (sys.spindle_stop_ovr) {
+          // Handles beginning of spindle stop
+          if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_INITIATE) {
+            if (gc_state.modal.spindle != SPINDLE_DISABLE) {
+              spindle_set_state(SPINDLE_DISABLE,0.0f); // De-energize
+              sys.spindle_stop_ovr = SPINDLE_STOP_OVR_ENABLED; // Set stop override state to enabled, if de-energized.
+            } else {
+              sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state
+            }
+          // Handles restoring of spindle state
+          } else if (sys.spindle_stop_ovr & (SPINDLE_STOP_OVR_RESTORE | SPINDLE_STOP_OVR_RESTORE_CYCLE)) {
+            if (gc_state.modal.spindle != SPINDLE_DISABLE) {
+              report_feedback_message(MESSAGE_SPINDLE_RESTORE);
+              if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) {
+                // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts.
+                bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM);
+              } else {
+                spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed);
+              }
+            }
+            if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_RESTORE_CYCLE) {
+              system_set_exec_state_flag(EXEC_CYCLE_START);  // Set to resume program.
+            }
+            sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state
+          }
+        } else {
+          // Handles spindle state during hold. NOTE: Spindle speed overrides may be altered during hold state.
+          // NOTE: STEP_CONTROL_UPDATE_SPINDLE_PWM is automatically reset upon resume in step generator.
+          if (bit_istrue(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM)) {
+            spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed);
+            bit_false(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM);
+          }
+        }
+
+      }
+    }
+
+    protocol_exec_rt_system();
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/protocol.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,49 @@
+/*
+  protocol.h - controls Grbl execution protocol and procedures
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef protocol_h
+#define protocol_h
+
+// Line buffer size from the serial input stream to be executed.
+// NOTE: Not a problem except for extreme cases, but the line buffer size can be too small
+// and g-code blocks can get truncated. Officially, the g-code standards support up to 256
+// characters. In future versions, this will be increased, when we know how much extra
+// memory space we can invest into here or we re-write the g-code parser not to have this
+// buffer.
+#ifndef LINE_BUFFER_SIZE
+  #define LINE_BUFFER_SIZE 80
+#endif
+
+// Starts Grbl main loop. It handles all incoming characters from the serial port and executes
+// them as they complete. It is also responsible for finishing the initialization procedures.
+void protocol_main_loop();
+
+// Checks and executes a realtime command at various stop points in main program
+void protocol_execute_realtime();
+void protocol_exec_rt_system();
+
+// Executes the auto cycle feature, if enabled.
+void protocol_auto_cycle_start();
+
+// Block until all buffered steps are executed
+void protocol_buffer_synchronize();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/report.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,651 @@
+/*
+  report.c - reporting and messaging methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+  This file functions as the primary feedback interface for Grbl. Any outgoing data, such
+  as the protocol status messages, feedback messages, and status reports, are stored here.
+  For the most part, these functions primarily are called from protocol.c methods. If a
+  different style feedback is desired (i.e. JSON), then a user can change these following
+  methods to accomodate their needs.
+*/
+
+#include "grbl.h"
+
+
+// Internal report utilities to reduce flash with repetitive tasks turned into functions.
+void report_util_setting_prefix(uint8_t n) { serial_write('$'); print_uint8_base10(n); serial_write('='); }
+static void report_util_line_feed() { printPgmString(PSTR("\r\n")); }
+static void report_util_feedback_line_feed() { serial_write(']'); report_util_line_feed(); }
+static void report_util_gcode_modes_G() { printPgmString(PSTR(" G")); }
+static void report_util_gcode_modes_M() { printPgmString(PSTR(" M")); }
+// static void report_util_comment_line_feed() { serial_write(')'); report_util_line_feed(); }
+static void report_util_axis_values(float *axis_value) {
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    printFloat_CoordValue(axis_value[idx]);
+    if (idx < (N_AXIS-1)) { serial_write(','); }
+  }
+}
+
+/*
+static void report_util_setting_string(uint8_t n) {
+  serial_write(' ');
+  serial_write('(');
+  switch(n) {
+    case 0: printPgmString(PSTR("stp pulse")); break;
+    case 1: printPgmString(PSTR("idl delay")); break; 
+    case 2: printPgmString(PSTR("stp inv")); break;
+    case 3: printPgmString(PSTR("dir inv")); break;
+    case 4: printPgmString(PSTR("stp en inv")); break;
+    case 5: printPgmString(PSTR("lim inv")); break;
+    case 6: printPgmString(PSTR("prb inv")); break;
+    case 10: printPgmString(PSTR("rpt")); break;
+    case 11: printPgmString(PSTR("jnc dev")); break;
+    case 12: printPgmString(PSTR("arc tol")); break;
+    case 13: printPgmString(PSTR("rpt inch")); break;
+    case 20: printPgmString(PSTR("sft lim")); break;
+    case 21: printPgmString(PSTR("hrd lim")); break;
+    case 22: printPgmString(PSTR("hm cyc")); break;
+    case 23: printPgmString(PSTR("hm dir inv")); break;
+    case 24: printPgmString(PSTR("hm feed")); break;
+    case 25: printPgmString(PSTR("hm seek")); break;
+    case 26: printPgmString(PSTR("hm delay")); break;
+    case 27: printPgmString(PSTR("hm pulloff")); break;
+    case 30: printPgmString(PSTR("rpm max")); break;
+    case 31: printPgmString(PSTR("rpm min")); break;
+    case 32: printPgmString(PSTR("laser")); break;
+    default:
+      n -= AXIS_SETTINGS_START_VAL;
+      uint8_t idx = 0;
+      while (n >= AXIS_SETTINGS_INCREMENT) {
+        n -= AXIS_SETTINGS_INCREMENT;
+        idx++;
+      }
+      serial_write(n+'x');
+      switch (idx) {
+        case 0: printPgmString(PSTR(":stp/mm")); break;
+        case 1: printPgmString(PSTR(":mm/min")); break;
+        case 2: printPgmString(PSTR(":mm/s^2")); break;
+        case 3: printPgmString(PSTR(":mm max")); break;
+      }
+      break;
+  }
+  report_util_comment_line_feed();
+}
+*/
+
+static void report_util_uint8_setting(uint8_t n, int val) {
+  report_util_setting_prefix(n);
+  print_uint8_base10(val);
+  report_util_line_feed(); // report_util_setting_string(n); 
+}
+static void report_util_float_setting(uint8_t n, float val, uint8_t n_decimal) {
+  report_util_setting_prefix(n);
+  printFloat(val, n_decimal);
+  report_util_line_feed(); // report_util_setting_string(n);
+}
+
+// Handles the primary confirmation protocol response for streaming interfaces and human-feedback.
+// For every incoming line, this method responds with an 'ok' for a successful command or an
+// 'error:'  to indicate some error event with the line or some critical system error during
+// operation. Errors events can originate from the g-code parser, settings module, or asynchronously
+// from a critical error, such as a triggered hard limit. Interface should always monitor for these
+// responses.
+void report_status_message(uint8_t status_code)
+{
+  switch(status_code) {
+    case STATUS_OK: // STATUS_OK
+      printPgmString(PSTR("ok\r\n")); break;
+    default:
+      printPgmString(PSTR("error:"));
+      print_uint8_base10(status_code);
+      report_util_line_feed();
+  }
+}
+
+// Prints alarm messages.
+void report_alarm_message(uint8_t alarm_code)
+{
+  printPgmString(PSTR("ALARM:"));
+  print_uint8_base10(alarm_code);
+  report_util_line_feed();
+  delay_ms(500); // Force delay to ensure message clears serial write buffer.
+}
+
+// Prints feedback messages. This serves as a centralized method to provide additional
+// user feedback for things that are not of the status/alarm message protocol. These are
+// messages such as setup warnings, switch toggling, and how to exit alarms.
+// NOTE: For interfaces, messages are always placed within brackets. And if silent mode
+// is installed, the message number codes are less than zero.
+void report_feedback_message(uint8_t message_code)
+{
+  printPgmString(PSTR("[MSG:"));
+  switch(message_code) {
+    case MESSAGE_CRITICAL_EVENT:
+      printPgmString(PSTR("Reset to continue")); break;
+    case MESSAGE_ALARM_LOCK:
+      printPgmString(PSTR("'$H'|'$X' to unlock")); break;
+    case MESSAGE_ALARM_UNLOCK:
+      printPgmString(PSTR("Caution: Unlocked")); break;
+    case MESSAGE_ENABLED:
+      printPgmString(PSTR("Enabled")); break;
+    case MESSAGE_DISABLED:
+      printPgmString(PSTR("Disabled")); break;
+    case MESSAGE_SAFETY_DOOR_AJAR:
+      printPgmString(PSTR("Check Door")); break;
+    case MESSAGE_CHECK_LIMITS:
+      printPgmString(PSTR("Check Limits")); break;
+    case MESSAGE_PROGRAM_END:
+      printPgmString(PSTR("Pgm End")); break;
+    case MESSAGE_RESTORE_DEFAULTS:
+      printPgmString(PSTR("Restoring defaults")); break;
+    case MESSAGE_SPINDLE_RESTORE:
+      printPgmString(PSTR("Restoring spindle")); break;
+    case MESSAGE_SLEEP_MODE:
+      printPgmString(PSTR("Sleeping")); break;
+  }
+  report_util_feedback_line_feed();
+}
+
+
+// Welcome message
+void report_init_message()
+{
+  printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
+}
+
+// Grbl help message
+void report_grbl_help() {
+  printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]\r\n"));    
+}
+
+
+// Grbl global settings print out.
+// NOTE: The numbering scheme here must correlate to storing in settings.c
+void report_grbl_settings() {
+  // Print Grbl settings.
+  report_util_uint8_setting(0,settings.pulse_microseconds);
+  report_util_uint8_setting(1,settings.stepper_idle_lock_time);
+  report_util_uint8_setting(2,settings.step_invert_mask);
+  report_util_uint8_setting(3,settings.dir_invert_mask);
+  report_util_uint8_setting(4,bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
+  report_util_uint8_setting(5,bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS));
+  report_util_uint8_setting(6,bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN));
+  report_util_uint8_setting(10,settings.status_report_mask);
+  report_util_float_setting(11,settings.junction_deviation,N_DECIMAL_SETTINGVALUE);
+  report_util_float_setting(12,settings.arc_tolerance,N_DECIMAL_SETTINGVALUE);
+  report_util_uint8_setting(13,bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
+  report_util_uint8_setting(20,bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
+  report_util_uint8_setting(21,bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
+  report_util_uint8_setting(22,bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
+  report_util_uint8_setting(23,settings.homing_dir_mask);
+  report_util_float_setting(24,settings.homing_feed_rate,N_DECIMAL_SETTINGVALUE);
+  report_util_float_setting(25,settings.homing_seek_rate,N_DECIMAL_SETTINGVALUE);
+  report_util_uint8_setting(26,settings.homing_debounce_delay);
+  report_util_float_setting(27,settings.homing_pulloff,N_DECIMAL_SETTINGVALUE);
+  report_util_float_setting(30,settings.rpm_max,N_DECIMAL_RPMVALUE);
+  report_util_float_setting(31,settings.rpm_min,N_DECIMAL_RPMVALUE);
+  #ifdef VARIABLE_SPINDLE
+    report_util_uint8_setting(32,bit_istrue(settings.flags,BITFLAG_LASER_MODE));
+  #else
+    report_util_uint8_setting(32,0);
+  #endif
+  // Print axis settings
+  uint8_t idx, set_idx;
+  uint8_t val = AXIS_SETTINGS_START_VAL;
+  for (set_idx=0; set_idx<AXIS_N_SETTINGS; set_idx++) {
+    for (idx=0; idx<N_AXIS; idx++) {
+      switch (set_idx) {
+        case 0: report_util_float_setting(val+idx,settings.steps_per_mm[idx],N_DECIMAL_SETTINGVALUE); break;
+        case 1: report_util_float_setting(val+idx,settings.max_rate[idx],N_DECIMAL_SETTINGVALUE); break;
+        case 2: report_util_float_setting(val+idx,settings.acceleration[idx]/(60*60),N_DECIMAL_SETTINGVALUE); break;
+        case 3: report_util_float_setting(val+idx,-settings.max_travel[idx],N_DECIMAL_SETTINGVALUE); break;
+      }
+    }
+    val += AXIS_SETTINGS_INCREMENT;
+  }
+}
+
+
+// Prints current probe parameters. Upon a probe command, these parameters are updated upon a
+// successful probe or upon a failed probe with the G38.3 without errors command (if supported).
+// These values are retained until Grbl is power-cycled, whereby they will be re-zeroed.
+void report_probe_parameters()
+{
+  // Report in terms of machine position.
+  printPgmString(PSTR("[PRB:"));
+  float print_position[N_AXIS];
+  system_convert_array_steps_to_mpos(print_position,sys_probe_position);
+  report_util_axis_values(print_position);
+  serial_write(':');
+  print_uint8_base10(sys.probe_succeeded);
+  report_util_feedback_line_feed();
+}
+
+
+// Prints Grbl NGC parameters (coordinate offsets, probing)
+void report_ngc_parameters()
+{
+  float coord_data[N_AXIS];
+  uint8_t coord_select;
+  for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
+    if (!(settings_read_coord_data(coord_select,coord_data))) {
+      report_status_message(STATUS_SETTING_READ_FAIL);
+      return;
+    }
+    printPgmString(PSTR("[G"));
+    switch (coord_select) {
+      case 6: printPgmString(PSTR("28")); break;
+      case 7: printPgmString(PSTR("30")); break;
+      default: print_uint8_base10(coord_select+54); break; // G54-G59
+    }
+    serial_write(':');
+    report_util_axis_values(coord_data);
+    report_util_feedback_line_feed();
+  }
+  printPgmString(PSTR("[G92:")); // Print G92,G92.1 which are not persistent in memory
+  report_util_axis_values(gc_state.coord_offset);
+  report_util_feedback_line_feed();
+  printPgmString(PSTR("[TLO:")); // Print tool length offset value
+  printFloat_CoordValue(gc_state.tool_length_offset);
+  report_util_feedback_line_feed();
+  report_probe_parameters(); // Print probe parameters. Not persistent in memory.
+}
+
+
+// Print current gcode parser mode state
+void report_gcode_modes()
+{
+  printPgmString(PSTR("[GC:G"));
+  if (gc_state.modal.motion >= MOTION_MODE_PROBE_TOWARD) {
+    printPgmString(PSTR("38."));
+    print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2));
+  } else {
+    print_uint8_base10(gc_state.modal.motion);
+  }
+
+  report_util_gcode_modes_G();
+  print_uint8_base10(gc_state.modal.coord_select+54);
+
+  report_util_gcode_modes_G();
+  print_uint8_base10(gc_state.modal.plane_select+17);
+
+  report_util_gcode_modes_G();
+  print_uint8_base10(21-gc_state.modal.units);
+
+  report_util_gcode_modes_G();
+  print_uint8_base10(gc_state.modal.distance+90);
+
+  report_util_gcode_modes_G();
+  print_uint8_base10(94-gc_state.modal.feed_rate);
+
+  if (gc_state.modal.program_flow) {
+    report_util_gcode_modes_M();
+    switch (gc_state.modal.program_flow) {
+      case PROGRAM_FLOW_PAUSED : serial_write('0'); break;
+      // case PROGRAM_FLOW_OPTIONAL_STOP : serial_write('1'); break; // M1 is ignored and not supported.
+      case PROGRAM_FLOW_COMPLETED_M2 : 
+      case PROGRAM_FLOW_COMPLETED_M30 : 
+        print_uint8_base10(gc_state.modal.program_flow);
+        break;
+    }
+  }
+
+  report_util_gcode_modes_M();
+  switch (gc_state.modal.spindle) {
+    case SPINDLE_ENABLE_CW : serial_write('3'); break;
+    case SPINDLE_ENABLE_CCW : serial_write('4'); break;
+    case SPINDLE_DISABLE : serial_write('5'); break;
+  }
+
+  report_util_gcode_modes_M();
+  #ifdef ENABLE_M7
+    if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time.
+      if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { report_util_gcode_modes_M(); serial_write('7'); }
+      if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { report_util_gcode_modes_M(); serial_write('8'); }
+    } else { report_util_gcode_modes_M(); serial_write('9'); }
+  #else
+    report_util_gcode_modes_M();
+    if (gc_state.modal.coolant) { serial_write('8'); }
+    else { serial_write('9'); }
+  #endif
+
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		if (sys.override_ctrl == OVERRIDE_PARKING_MOTION) {
+			report_util_gcode_modes_M();
+			print_uint8_base10(56);
+		}
+	#endif
+
+  printPgmString(PSTR(" T"));
+  print_uint8_base10(gc_state.tool);
+
+  printPgmString(PSTR(" F"));
+  printFloat_RateValue(gc_state.feed_rate);
+
+  #ifdef VARIABLE_SPINDLE
+    printPgmString(PSTR(" S"));
+    printFloat(gc_state.spindle_speed,N_DECIMAL_RPMVALUE);
+  #endif
+
+  report_util_feedback_line_feed();
+}
+
+// Prints specified startup line
+void report_startup_line(uint8_t n, char *line)
+{
+  printPgmString(PSTR("$N"));
+  print_uint8_base10(n);
+  serial_write('=');
+  printString(line);
+  report_util_line_feed();
+}
+
+void report_execute_startup_message(char *line, uint8_t status_code)
+{
+  serial_write('>');
+  printString(line);
+  serial_write(':');
+  report_status_message(status_code);
+}
+
+// Prints build info line
+void report_build_info(char *line)
+{
+  printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":"));
+  printString(line);
+  report_util_feedback_line_feed();
+  printPgmString(PSTR("[OPT:")); // Generate compile-time build option list
+  #ifdef VARIABLE_SPINDLE
+    serial_write('V');
+  #endif
+  #ifdef USE_LINE_NUMBERS
+    serial_write('N');
+  #endif
+  #ifdef ENABLE_M7
+    serial_write('M');
+  #endif
+  #ifdef COREXY
+    serial_write('C');
+  #endif
+  #ifdef PARKING_ENABLE
+    serial_write('P');
+  #endif
+  #ifdef HOMING_FORCE_SET_ORIGIN
+    serial_write('Z');
+  #endif
+  #ifdef HOMING_SINGLE_AXIS_COMMANDS
+    serial_write('H');
+  #endif
+  #ifdef LIMITS_TWO_SWITCHES_ON_AXES
+    serial_write('T');
+  #endif
+  #ifdef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES
+    serial_write('A');
+  #endif
+	#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+		serial_write('D');
+	#endif
+	#ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED
+		serial_write('0');
+	#endif
+	#ifdef ENABLE_SOFTWARE_DEBOUNCE
+		serial_write('S');
+	#endif
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		serial_write('R');
+	#endif
+	#ifndef ENABLE_RESTORE_EEPROM_WIPE_ALL // NOTE: Shown when disabled.
+    serial_write('*');
+  #endif
+  #ifndef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // NOTE: Shown when disabled.
+    serial_write('$');
+  #endif
+  #ifndef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // NOTE: Shown when disabled.
+    serial_write('#');
+  #endif
+  #ifndef ENABLE_BUILD_INFO_WRITE_COMMAND // NOTE: Shown when disabled.
+    serial_write('I');
+  #endif
+  #ifndef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // NOTE: Shown when disabled.
+    serial_write('E');
+  #endif
+  #ifndef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // NOTE: Shown when disabled.
+    serial_write('W');
+  #endif
+	#ifndef HOMING_INIT_LOCK
+		serial_write('L');
+	#endif
+
+  // NOTE: Compiled values, like override increments/max/min values, may be added at some point later.
+	serial_write(',');
+	print_uint8_base10(BLOCK_BUFFER_SIZE - 1);
+	serial_write(',');
+	print_uint8_base10(RX_BUFFER_SIZE);
+
+	report_util_feedback_line_feed();
+}
+
+
+// Prints the character string line Grbl has received from the user, which has been pre-parsed,
+// and has been sent into protocol_execute_line() routine to be executed by Grbl.
+void report_echo_line_received(char *line)
+{
+  printPgmString(PSTR("[echo: ")); printString(line);
+  report_util_feedback_line_feed();
+}
+
+
+ // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram
+ // and the actual location of the CNC machine. Users may change the following function to their
+ // specific needs, but the desired real-time data report must be as short as possible. This is
+ // requires as it minimizes the computational overhead and allows grbl to keep running smoothly,
+ // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
+void report_realtime_status()
+{
+  uint8_t idx;
+  int32_t current_position[N_AXIS]; // Copy current state of the system position variable
+  memcpy(current_position, sys_position, sizeof(sys_position));
+  float print_position[N_AXIS];
+  system_convert_array_steps_to_mpos(print_position, current_position);
+
+  // Report current machine state and sub-states
+  serial_write('<');
+  switch (sys.state) {
+  case STATE_IDLE: printPgmString(PSTR("Idle")); break;
+  case STATE_CYCLE: printPgmString(PSTR("Run")); break;
+  case STATE_HOLD:
+    if (!(sys.suspend & SUSPEND_JOG_CANCEL)) {
+      printPgmString(PSTR("Hold:"));
+      if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume
+      else { serial_write('1'); } // Actively holding
+      break;
+    } // Continues to print jog state during jog cancel.
+  case STATE_JOG: printPgmString(PSTR("Jog")); break;
+  case STATE_HOMING: printPgmString(PSTR("Home")); break;
+  case STATE_ALARM: printPgmString(PSTR("Alarm")); break;
+  case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break;
+  case STATE_SAFETY_DOOR:
+    printPgmString(PSTR("Door:"));
+    if (sys.suspend & SUSPEND_INITIATE_RESTORE) {
+      serial_write('3'); // Restoring
+    }
+    else {
+      if (sys.suspend & SUSPEND_RETRACT_COMPLETE) {
+        if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) {
+          serial_write('1'); // Door ajar
+        }
+        else {
+          serial_write('0');
+        } // Door closed and ready to resume
+      }
+      else {
+        serial_write('2'); // Retracting
+      }
+    }
+    break;
+  case STATE_SLEEP: printPgmString(PSTR("Sleep")); break;
+  }
+
+  float wco[N_AXIS];
+  if (bit_isfalse(settings.status_report_mask, BITFLAG_RT_STATUS_POSITION_TYPE) ||
+    (sys.report_wco_counter == 0)) {
+    for (idx = 0; idx< N_AXIS; idx++) {
+      // Apply work coordinate offsets and tool length offset to current position.
+      wco[idx] = gc_state.coord_system[idx] + gc_state.coord_offset[idx];
+      if (idx == TOOL_LENGTH_OFFSET_AXIS) { wco[idx] += gc_state.tool_length_offset; }
+      if (bit_isfalse(settings.status_report_mask, BITFLAG_RT_STATUS_POSITION_TYPE)) {
+        print_position[idx] -= wco[idx];
+      }
+    }
+  }
+
+  // Report machine position
+  if (bit_istrue(settings.status_report_mask, BITFLAG_RT_STATUS_POSITION_TYPE)) {
+    printPgmString(PSTR("|MPos:"));
+  }
+  else {
+    printPgmString(PSTR("|WPos:"));
+  }
+  report_util_axis_values(print_position);
+
+  // Returns planner and serial read buffer states.
+#ifdef REPORT_FIELD_BUFFER_STATE
+  if (bit_istrue(settings.status_report_mask, BITFLAG_RT_STATUS_BUFFER_STATE)) {
+    printPgmString(PSTR("|Bf:"));
+    print_uint8_base10(plan_get_block_buffer_available());
+    serial_write(',');
+    print_uint8_base10(serial_get_rx_buffer_available());
+  }
+#endif
+
+#ifdef USE_LINE_NUMBERS
+#ifdef REPORT_FIELD_LINE_NUMBERS
+  // Report current line number
+  plan_block_t * cur_block = plan_get_current_block();
+  if (cur_block != NULL) {
+    uint32_t ln = cur_block->line_number;
+    if (ln > 0) {
+      printPgmString(PSTR("|Ln:"));
+      printInteger(ln);
+    }
+  }
+#endif
+#endif
+
+  // Report realtime feed speed
+#ifdef REPORT_FIELD_CURRENT_FEED_SPEED
+#ifdef VARIABLE_SPINDLE
+  printPgmString(PSTR("|FS:"));
+  printFloat_RateValue(st_get_realtime_rate());
+  serial_write(',');
+  printFloat(sys.spindle_speed, N_DECIMAL_RPMVALUE);
+#else
+  printPgmString(PSTR("|F:"));
+  printFloat_RateValue(st_get_realtime_rate());
+#endif      
+#endif
+
+#ifdef REPORT_FIELD_PIN_STATE
+  uint8_t lim_pin_state = limits_get_state();
+  uint8_t ctrl_pin_state = system_control_get_state();
+  uint8_t prb_pin_state = probe_get_state();
+  if (lim_pin_state | ctrl_pin_state | prb_pin_state) {
+    printPgmString(PSTR("|Pn:"));
+    if (prb_pin_state) { serial_write('P'); }
+    if (lim_pin_state) {
+      if (bit_istrue(lim_pin_state, bit(X_AXIS))) { serial_write('X'); }
+      if (bit_istrue(lim_pin_state, bit(Y_AXIS))) { serial_write('Y'); }
+      if (bit_istrue(lim_pin_state, bit(Z_AXIS))) { serial_write('Z'); }
+    }
+    if (ctrl_pin_state) {
+#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+      if (bit_istrue(ctrl_pin_state, CONTROL_PIN_INDEX_SAFETY_DOOR)) { serial_write('D'); }
+#endif
+      if (bit_istrue(ctrl_pin_state, CONTROL_PIN_INDEX_RESET)) { serial_write('R'); }
+      if (bit_istrue(ctrl_pin_state, CONTROL_PIN_INDEX_FEED_HOLD)) { serial_write('H'); }
+      if (bit_istrue(ctrl_pin_state, CONTROL_PIN_INDEX_CYCLE_START)) { serial_write('S'); }
+    }
+  }
+#endif
+
+#ifdef REPORT_FIELD_WORK_COORD_OFFSET
+  if (sys.report_wco_counter > 0) { sys.report_wco_counter--; }
+  else {
+    if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
+      sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT - 1); // Reset counter for slow refresh
+    }
+    else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT - 1); }
+    if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report.
+    printPgmString(PSTR("|WCO:"));
+    report_util_axis_values(wco);
+  }
+#endif
+
+  #ifdef REPORT_FIELD_OVERRIDES
+    if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; }
+    else {
+      if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
+        sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT - 1); // Reset counter for slow refresh
+      }
+      else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT - 1); }
+      printPgmString(PSTR("|Ov:"));
+      print_uint8_base10(sys.f_override);
+      serial_write(',');
+      print_uint8_base10(sys.r_override);
+      serial_write(',');
+      print_uint8_base10(sys.spindle_speed_ovr);
+
+      uint8_t sp_state = spindle_get_state();
+      uint8_t cl_state = coolant_get_state();
+      if (sp_state || cl_state) {
+        printPgmString(PSTR("|A:"));
+        if (sp_state) { // != SPINDLE_STATE_DISABLE
+          #ifdef VARIABLE_SPINDLE 
+            #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+              serial_write('S'); // CW
+            #else
+              if (sp_state == SPINDLE_STATE_CW) { serial_write('S'); } // CW
+              else { serial_write('C'); } // CCW
+            #endif
+          #else
+            if (sp_state & SPINDLE_STATE_CW) { serial_write('S'); } // CW
+            else { serial_write('C'); } // CCW
+          #endif
+        }
+        if (cl_state & COOLANT_STATE_FLOOD) { serial_write('F'); }
+        #ifdef ENABLE_M7
+          if (cl_state & COOLANT_STATE_MIST) { serial_write('M'); }
+        #endif
+      }
+    }
+  #endif
+
+  serial_write('>');
+  report_util_line_feed();
+}
+
+
+#ifdef DEBUG
+  void report_realtime_debug()
+  {
+
+  }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/report.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,131 @@
+/*
+  report.h - reporting and messaging methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef report_h
+#define report_h
+
+// Define Grbl status codes. Valid values (0-255)
+#define STATUS_OK 0
+#define STATUS_EXPECTED_COMMAND_LETTER 1
+#define STATUS_BAD_NUMBER_FORMAT 2
+#define STATUS_INVALID_STATEMENT 3
+#define STATUS_NEGATIVE_VALUE 4
+#define STATUS_SETTING_DISABLED 5
+#define STATUS_SETTING_STEP_PULSE_MIN 6
+#define STATUS_SETTING_READ_FAIL 7
+#define STATUS_IDLE_ERROR 8
+#define STATUS_SYSTEM_GC_LOCK 9
+#define STATUS_SOFT_LIMIT_ERROR 10
+#define STATUS_OVERFLOW 11
+#define STATUS_MAX_STEP_RATE_EXCEEDED 12
+#define STATUS_CHECK_DOOR 13
+#define STATUS_LINE_LENGTH_EXCEEDED 14
+#define STATUS_TRAVEL_EXCEEDED 15
+#define STATUS_INVALID_JOG_COMMAND 16
+#define STATUS_SETTING_DISABLED_LASER 17
+
+#define STATUS_GCODE_UNSUPPORTED_COMMAND 20
+#define STATUS_GCODE_MODAL_GROUP_VIOLATION 21
+#define STATUS_GCODE_UNDEFINED_FEED_RATE 22
+#define STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER 23
+#define STATUS_GCODE_AXIS_COMMAND_CONFLICT 24
+#define STATUS_GCODE_WORD_REPEATED 25
+#define STATUS_GCODE_NO_AXIS_WORDS 26
+#define STATUS_GCODE_INVALID_LINE_NUMBER 27
+#define STATUS_GCODE_VALUE_WORD_MISSING 28
+#define STATUS_GCODE_UNSUPPORTED_COORD_SYS 29
+#define STATUS_GCODE_G53_INVALID_MOTION_MODE 30
+#define STATUS_GCODE_AXIS_WORDS_EXIST 31
+#define STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE 32
+#define STATUS_GCODE_INVALID_TARGET 33
+#define STATUS_GCODE_ARC_RADIUS_ERROR 34
+#define STATUS_GCODE_NO_OFFSETS_IN_PLANE 35
+#define STATUS_GCODE_UNUSED_WORDS 36
+#define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37
+#define STATUS_GCODE_MAX_VALUE_EXCEEDED 38
+
+// Define Grbl alarm codes. Valid values (1-255). 0 is reserved.
+#define ALARM_HARD_LIMIT_ERROR      EXEC_ALARM_HARD_LIMIT
+#define ALARM_SOFT_LIMIT_ERROR      EXEC_ALARM_SOFT_LIMIT
+#define ALARM_ABORT_CYCLE           EXEC_ALARM_ABORT_CYCLE
+#define ALARM_PROBE_FAIL_INITIAL    EXEC_ALARM_PROBE_FAIL_INITIAL
+#define ALARM_PROBE_FAIL_CONTACT    EXEC_ALARM_PROBE_FAIL_CONTACT
+#define ALARM_HOMING_FAIL_RESET     EXEC_ALARM_HOMING_FAIL_RESET
+#define ALARM_HOMING_FAIL_DOOR      EXEC_ALARM_HOMING_FAIL_DOOR
+#define ALARM_HOMING_FAIL_PULLOFF   EXEC_ALARM_HOMING_FAIL_PULLOFF
+#define ALARM_HOMING_FAIL_APPROACH  EXEC_ALARM_HOMING_FAIL_APPROACH
+
+// Define Grbl feedback message codes. Valid values (0-255).
+#define MESSAGE_CRITICAL_EVENT 1
+#define MESSAGE_ALARM_LOCK 2
+#define MESSAGE_ALARM_UNLOCK 3
+#define MESSAGE_ENABLED 4
+#define MESSAGE_DISABLED 5
+#define MESSAGE_SAFETY_DOOR_AJAR 6
+#define MESSAGE_CHECK_LIMITS 7
+#define MESSAGE_PROGRAM_END 8
+#define MESSAGE_RESTORE_DEFAULTS 9
+#define MESSAGE_SPINDLE_RESTORE 10
+#define MESSAGE_SLEEP_MODE 11
+
+// Prints system status messages.
+void report_status_message(uint8_t status_code);
+
+// Prints system alarm messages.
+void report_alarm_message(uint8_t alarm_code);
+
+// Prints miscellaneous feedback messages.
+void report_feedback_message(uint8_t message_code);
+
+// Prints welcome message
+void report_init_message();
+
+// Prints Grbl help and current global settings
+void report_grbl_help();
+
+// Prints Grbl global settings
+void report_grbl_settings();
+
+// Prints an echo of the pre-parsed line received right before execution.
+void report_echo_line_received(char *line);
+
+// Prints realtime status report
+void report_realtime_status();
+
+// Prints recorded probe position
+void report_probe_parameters();
+
+// Prints Grbl NGC parameters (coordinate offsets, probe)
+void report_ngc_parameters();
+
+// Prints current g-code parser mode state
+void report_gcode_modes();
+
+// Prints startup line when requested and executed.
+void report_startup_line(uint8_t n, char *line);
+void report_execute_startup_message(char *line, uint8_t status_code);
+
+// Prints build info and user info
+void report_build_info(char *line);
+
+#ifdef DEBUG
+  void report_realtime_debug();
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/serial.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,428 @@
+/*
+  serial.c - Low level functions for sending and recieving bytes via the serial port
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+#ifdef WIN32
+#include <stdio.h>
+#include <process.h> 
+#include <conio.h>
+CRITICAL_SECTION CriticalSection; 
+//#define LOCAL_ECHO
+
+HANDLE hSerial = INVALID_HANDLE_VALUE;
+void RecvthreadFunction( void *);
+void SendthreadFunction( void *);
+
+#endif
+#ifdef STM32F103C8
+#include "stm32f10x.h"
+#include "core_cm3.h"
+#ifndef USEUSB
+#include "stm32f10x_usart.h"
+#else
+#include "usb_regs.h"
+#endif
+#endif
+
+#if !defined(STM32F103C8)
+#define RX_RING_BUFFER (RX_BUFFER_SIZE+1)
+#define TX_RING_BUFFER (TX_BUFFER_SIZE+1)
+#else
+#define RX_RING_BUFFER (RX_BUFFER_SIZE)
+#define TX_RING_BUFFER (TX_BUFFER_SIZE)
+#endif
+
+uint8_t serial_rx_buffer[RX_RING_BUFFER];
+uint8_t serial_rx_buffer_head = 0;
+volatile uint8_t serial_rx_buffer_tail = 0;
+
+uint8_t serial_tx_buffer[TX_RING_BUFFER];
+uint8_t serial_tx_buffer_head = 0;
+volatile uint8_t serial_tx_buffer_tail = 0;
+
+
+// Returns the number of bytes available in the RX serial buffer.
+uint8_t serial_get_rx_buffer_available()
+{
+  uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_rx_buffer_head >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head-rtail)); }
+  return((rtail-serial_rx_buffer_head-1));
+}
+
+
+// Returns the number of bytes used in the RX serial buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
+uint8_t serial_get_rx_buffer_count()
+{
+  uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_rx_buffer_head >= rtail) { return(serial_rx_buffer_head-rtail); }
+  return (RX_BUFFER_SIZE - (rtail-serial_rx_buffer_head));
+}
+
+
+// Returns the number of bytes used in the TX serial buffer.
+// NOTE: Not used except for debugging and ensuring no TX bottlenecks.
+uint8_t serial_get_tx_buffer_count()
+{
+  uint8_t ttail = serial_tx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_tx_buffer_head >= ttail) { return(serial_tx_buffer_head-ttail); }
+  return (TX_RING_BUFFER - (ttail-serial_tx_buffer_head));
+}
+
+
+void serial_init()
+{
+#ifdef AVRTARGET 
+    // Set baud rate
+  #if BAUD_RATE < 57600
+    uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ;
+    UCSR0A &= ~(1 << U2X0); // baud doubler off  - Only needed on Uno XXX
+  #else
+    uint16_t UBRR0_value = ((F_CPU / (4L * BAUD_RATE)) - 1)/2;
+    UCSR0A |= (1 << U2X0);  // baud doubler on for high baud rates, i.e. 115200
+  #endif
+  UBRR0H = UBRR0_value >> 8;
+  UBRR0L = UBRR0_value;
+
+  // enable rx, tx, and interrupt on complete reception of a byte
+  UCSR0B |= (1<<RXEN0 | 1<<TXEN0 | 1<<RXCIE0);
+
+  // defaults to 8-bit, no parity, 1 stop bit
+#endif
+#ifdef WIN32
+  InitializeCriticalSectionAndSpinCount(&CriticalSection,0x00000400);
+#endif
+}
+#ifdef WIN32
+#define MAX_DEVPATH_LENGTH 1024
+void winserial_init(char *pPort)
+{
+    DCB dcb;
+    BOOL fSuccess;
+    TCHAR devicePath[MAX_DEVPATH_LENGTH];
+    COMMTIMEOUTS commTimeout;
+
+    if (pPort != NULL)
+    {
+        mbstowcs_s(NULL, devicePath, MAX_DEVPATH_LENGTH, pPort, strlen(pPort));
+        hSerial = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                    OPEN_EXISTING, 0, NULL);
+    }
+    if (hSerial != INVALID_HANDLE_VALUE)
+    {
+        //  Initialize the DCB structure.
+        SecureZeroMemory(&dcb, sizeof(DCB));
+        dcb.DCBlength = sizeof(DCB);
+        fSuccess = GetCommState(hSerial, &dcb);
+        if (!fSuccess) 
+        {
+            CloseHandle(hSerial);
+            hSerial = INVALID_HANDLE_VALUE;
+            return;
+        }
+
+        GetCommState(hSerial, &dcb);
+        dcb.BaudRate = CBR_115200;     //  baud rate
+        dcb.ByteSize = 8;             //  data size, xmit and rcv
+        dcb.Parity   = NOPARITY;      //  parity bit
+        dcb.StopBits = ONESTOPBIT;    //  stop bit
+        dcb.fBinary = TRUE;
+        dcb.fParity = TRUE;
+
+        fSuccess = SetCommState(hSerial, &dcb);
+        if (!fSuccess) 
+        {
+            CloseHandle(hSerial);
+            hSerial = INVALID_HANDLE_VALUE;
+            return;
+        }
+
+        GetCommTimeouts(hSerial, &commTimeout);
+        commTimeout.ReadIntervalTimeout     = 1;
+        commTimeout.ReadTotalTimeoutConstant     = 1;
+        commTimeout.ReadTotalTimeoutMultiplier     = 1;
+        commTimeout.WriteTotalTimeoutConstant     = 1;
+        commTimeout.WriteTotalTimeoutMultiplier = 1;
+        SetCommTimeouts(hSerial, &commTimeout);
+    }
+    _beginthread( RecvthreadFunction, 0, NULL );
+    _beginthread( SendthreadFunction, 0, NULL );
+}
+#endif
+
+
+// Writes one byte to the TX serial buffer. Called by main program.
+void serial_write(uint8_t data) {
+  // Calculate next head
+  uint8_t next_head = serial_tx_buffer_head + 1;
+  #ifdef STM32F103C8
+#ifndef USEUSB
+	USART_SendData(USART1, data);
+	while (!(USART1->SR & USART_FLAG_TXE));		 //µÈ´ý·¢ËÍÍê³É
+    return;
+#endif
+#endif
+  if (next_head == TX_RING_BUFFER) { next_head = 0; }
+
+  // Wait until there is space in the buffer
+  while (next_head == serial_tx_buffer_tail) {
+    // TODO: Restructure st_prep_buffer() calls to be executed here during a long print.
+    if (sys_rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
+#ifdef WIN32
+     Sleep(1);
+#endif
+  }
+
+  // Store data and advance head
+  serial_tx_buffer[serial_tx_buffer_head] = data;
+
+  serial_tx_buffer_head = next_head;
+
+#ifdef AVRTARGET
+  // Enable Data Register Empty Interrupt to make sure tx-streaming is running
+  UCSR0B |=  (1 << UDRIE0);
+#endif
+}
+
+#ifdef AVRTARGET
+// Data Register Empty Interrupt handler
+ISR(SERIAL_UDRE)
+{
+  uint8_t tail = serial_tx_buffer_tail; // Temporary serial_tx_buffer_tail (to optimize for volatile)
+
+  // Send a byte from the buffer
+  UDR0 = serial_tx_buffer[tail];
+
+  // Update tail position
+  tail++;
+  if (tail == TX_RING_BUFFER) { tail = 0; }
+
+  serial_tx_buffer_tail = tail;
+
+  // Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer
+  if (tail == serial_tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }
+}
+#endif
+#ifdef WIN32
+void SendthreadFunction( void *pVoid)
+{
+    unsigned char szBuf[RX_RING_BUFFER + 1];
+
+	DWORD dwBytesWritten;
+	uint8_t nNextTai;
+    for (;;)
+    {
+		while (serial_tx_buffer_head == serial_tx_buffer_tail)
+			Sleep(1);
+	    uint16_t USB_Tx_length;
+
+        if (serial_tx_buffer_head > serial_tx_buffer_tail)
+		    USB_Tx_length = serial_tx_buffer_head - serial_tx_buffer_tail;
+        else
+        {
+		    USB_Tx_length = RX_RING_BUFFER - serial_tx_buffer_tail;
+            if (USB_Tx_length == 0)
+            {
+                USB_Tx_length = serial_tx_buffer_head;
+            }
+        }
+		nNextTai = serial_tx_buffer_tail;
+
+        if (USB_Tx_length != 0)
+        {
+			if (hSerial != INVALID_HANDLE_VALUE)
+			{
+				WriteFile(hSerial, serial_tx_buffer + serial_tx_buffer_tail, USB_Tx_length, &dwBytesWritten, NULL);
+				nNextTai += (uint8_t)dwBytesWritten;
+#ifdef LOCAL_ECHO
+				memcpy(szBuf, &serial_tx_buffer[serial_tx_buffer_tail], dwBytesWritten);
+				szBuf[dwBytesWritten] = 0;
+				printf(szBuf);
+#endif
+			}
+			else
+			{
+			//	fwrite(szBuf, 1, USB_Tx_length, stdout);
+				memcpy(szBuf, &serial_tx_buffer[serial_tx_buffer_tail], USB_Tx_length);
+				szBuf[USB_Tx_length] = 0;
+				printf(szBuf);
+				nNextTai += USB_Tx_length;
+			}
+			if (nNextTai == RX_RING_BUFFER)
+				nNextTai = 0;
+
+			serial_tx_buffer_tail = nNextTai;
+		}
+	}
+}
+#endif
+
+// Fetches the first byte in the serial read buffer. Called by main program.
+uint8_t serial_read()
+{
+  uint8_t tail = serial_rx_buffer_tail; // Temporary serial_rx_buffer_tail (to optimize for volatile)
+  if (serial_rx_buffer_head == tail) {
+    return SERIAL_NO_DATA;
+  } else {
+    uint8_t data = serial_rx_buffer[tail];
+
+    tail++;
+    if (tail == RX_RING_BUFFER) { tail = 0; }
+    serial_rx_buffer_tail = tail;
+
+    return data;
+  }
+}
+
+#ifdef AVRTARGET
+ISR(SERIAL_RX)
+{
+  uint8_t data = UDR0;
+  uint8_t next_head;
+#endif
+#ifdef WIN32
+//#define WINLOG
+void RecvthreadFunction(void *pVoid )
+{
+    DWORD  dwBytesRead;
+    uint8_t data;
+    uint8_t next_head;
+    for (;;)
+    {
+        if (hSerial != INVALID_HANDLE_VALUE)
+        {
+            if (ReadFile(hSerial, &data, 1, &dwBytesRead, NULL) && dwBytesRead == 1)
+            {
+            }
+            else
+            {
+#ifdef WIN32
+								Sleep(1);
+#endif
+
+                data = 0;
+            }
+        }
+        else
+        {
+            while (_kbhit() == 0)
+                ;
+            data = _getch();
+        }
+         if (data == 0)
+             continue;
+#endif
+#ifdef STM32F103C8
+#ifdef USEUSB
+void OnUsbDataRx(uint8_t* dataIn, uint8_t length)
+{
+	//lcd_write_char(*dataIn);
+	uint8_t next_head;
+    uint8_t data;
+
+	// Write data to buffer unless it is full.
+	while (length != 0)
+	{
+        data = *dataIn ++;
+#else
+/*----------------------------------------------------------------------------
+  USART1_IRQHandler
+  Handles USART1 global interrupt request.
+ *----------------------------------------------------------------------------*/
+void USART1_IRQHandler (void) 
+{
+    volatile unsigned int IIR;
+    uint8_t data;
+    uint8_t next_head;
+
+    IIR = USART1->SR;
+    if (IIR & USART_FLAG_RXNE) 
+    {                  // read interrupt
+        data = USART1->DR & 0x1FF;
+#endif
+#endif
+  // Pick off realtime command characters directly from the serial stream. These characters are
+  // not passed into the main buffer, but these set system state flag bits for realtime execution.
+  switch (data) {
+    case CMD_RESET:         mc_reset(); break; // Call motion control reset routine.
+    case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true
+    case CMD_CYCLE_START:   system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
+    case CMD_FEED_HOLD:     system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
+    default :
+      if (data > 0x7F) { // Real-time control characters are extended ACSII only.
+        switch(data) {
+          case CMD_SAFETY_DOOR:   system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
+          case CMD_JOG_CANCEL:   
+            if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
+              system_set_exec_state_flag(EXEC_MOTION_CANCEL); 
+            }
+            break; 
+          #ifdef DEBUG
+            case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break;
+          #endif
+          case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break;
+          case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break;
+          case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break;
+          case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break;
+          case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break;
+          case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break;
+          case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break;
+          case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break;
+          case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break;
+          case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
+          case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
+          case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
+          case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
+          case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break;
+          case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
+          #ifdef ENABLE_M7
+            case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
+          #endif
+        }
+        // Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
+      } else { // Write character to buffer
+        next_head = serial_rx_buffer_head + 1;
+        if (next_head == RX_RING_BUFFER) { next_head = 0; }
+
+        // Write data to buffer unless it is full.
+        if (next_head != serial_rx_buffer_tail) {
+          serial_rx_buffer[serial_rx_buffer_head] = data;
+          serial_rx_buffer_head = next_head;
+        }
+      }
+  }
+#ifdef WIN32
+    }
+#endif
+#ifdef STM32F103C8
+#ifndef USEUSB
+        USART1->SR &= ~USART_FLAG_RXNE;	          // clear interrupt
+#else
+    length--;
+#endif
+   }
+#endif
+}
+
+void serial_reset_read_buffer()
+{
+  serial_rx_buffer_tail = serial_rx_buffer_head;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/serial.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,424 @@
+/*
+  serial.c - Low level functions for sending and recieving bytes via the serial port
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+#ifdef WIN32
+#include <stdio.h>
+#include <process.h> 
+#include <conio.h>
+CRITICAL_SECTION CriticalSection; 
+//#define LOCAL_ECHO
+
+HANDLE hSerial = INVALID_HANDLE_VALUE;
+void RecvthreadFunction( void *);
+void SendthreadFunction( void *);
+
+#endif
+#ifdef STM32F103C8
+#include "stm32f10x.h"
+#include "core_cm3.h"
+#ifndef USEUSB
+#include "stm32f10x_usart.h"
+#else
+#include "usb_regs.h"
+#endif
+#endif
+
+#if !defined(STM32F103C8)
+#define RX_RING_BUFFER (RX_BUFFER_SIZE+1)
+#define TX_RING_BUFFER (TX_BUFFER_SIZE+1)
+#else
+#define RX_RING_BUFFER (RX_BUFFER_SIZE)
+#define TX_RING_BUFFER (TX_BUFFER_SIZE)
+#endif
+
+uint8_t serial_rx_buffer[RX_RING_BUFFER];
+uint8_t serial_rx_buffer_head = 0;
+volatile uint8_t serial_rx_buffer_tail = 0;
+
+uint8_t serial_tx_buffer[TX_RING_BUFFER];
+uint8_t serial_tx_buffer_head = 0;
+volatile uint8_t serial_tx_buffer_tail = 0;
+
+
+// Returns the number of bytes available in the RX serial buffer.
+uint8_t serial_get_rx_buffer_available()
+{
+  uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_rx_buffer_head >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head-rtail)); }
+  return((rtail-serial_rx_buffer_head-1));
+}
+
+
+// Returns the number of bytes used in the RX serial buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
+uint8_t serial_get_rx_buffer_count()
+{
+  uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_rx_buffer_head >= rtail) { return(serial_rx_buffer_head-rtail); }
+  return (RX_BUFFER_SIZE - (rtail-serial_rx_buffer_head));
+}
+
+
+// Returns the number of bytes used in the TX serial buffer.
+// NOTE: Not used except for debugging and ensuring no TX bottlenecks.
+uint8_t serial_get_tx_buffer_count()
+{
+  uint8_t ttail = serial_tx_buffer_tail; // Copy to limit multiple calls to volatile
+  if (serial_tx_buffer_head >= ttail) { return(serial_tx_buffer_head-ttail); }
+  return (TX_RING_BUFFER - (ttail-serial_tx_buffer_head));
+}
+
+
+void serial_init()
+{
+#ifdef AVRTARGET 
+    // Set baud rate
+  #if BAUD_RATE < 57600
+    uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ;
+    UCSR0A &= ~(1 << U2X0); // baud doubler off  - Only needed on Uno XXX
+  #else
+    uint16_t UBRR0_value = ((F_CPU / (4L * BAUD_RATE)) - 1)/2;
+    UCSR0A |= (1 << U2X0);  // baud doubler on for high baud rates, i.e. 115200
+  #endif
+  UBRR0H = UBRR0_value >> 8;
+  UBRR0L = UBRR0_value;
+
+  // enable rx, tx, and interrupt on complete reception of a byte
+  UCSR0B |= (1<<RXEN0 | 1<<TXEN0 | 1<<RXCIE0);
+
+  // defaults to 8-bit, no parity, 1 stop bit
+#endif
+#ifdef WIN32
+  InitializeCriticalSectionAndSpinCount(&CriticalSection,0x00000400);
+#endif
+}
+#ifdef WIN32
+#define MAX_DEVPATH_LENGTH 1024
+void winserial_init(char *pPort)
+{
+    DCB dcb;
+    BOOL fSuccess;
+    TCHAR devicePath[MAX_DEVPATH_LENGTH];
+    COMMTIMEOUTS commTimeout;
+
+    if (pPort != NULL)
+    {
+        mbstowcs_s(NULL, devicePath, MAX_DEVPATH_LENGTH, pPort, strlen(pPort));
+        hSerial = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                    OPEN_EXISTING, 0, NULL);
+    }
+    if (hSerial != INVALID_HANDLE_VALUE)
+    {
+        //  Initialize the DCB structure.
+        SecureZeroMemory(&dcb, sizeof(DCB));
+        dcb.DCBlength = sizeof(DCB);
+        fSuccess = GetCommState(hSerial, &dcb);
+        if (!fSuccess) 
+        {
+            CloseHandle(hSerial);
+            hSerial = INVALID_HANDLE_VALUE;
+            return;
+        }
+
+        GetCommState(hSerial, &dcb);
+        dcb.BaudRate = CBR_115200;     //  baud rate
+        dcb.ByteSize = 8;             //  data size, xmit and rcv
+        dcb.Parity   = NOPARITY;      //  parity bit
+        dcb.StopBits = ONESTOPBIT;    //  stop bit
+        dcb.fBinary = TRUE;
+        dcb.fParity = TRUE;
+
+        fSuccess = SetCommState(hSerial, &dcb);
+        if (!fSuccess) 
+        {
+            CloseHandle(hSerial);
+            hSerial = INVALID_HANDLE_VALUE;
+            return;
+        }
+
+        GetCommTimeouts(hSerial, &commTimeout);
+        commTimeout.ReadIntervalTimeout     = 1;
+        commTimeout.ReadTotalTimeoutConstant     = 1;
+        commTimeout.ReadTotalTimeoutMultiplier     = 1;
+        commTimeout.WriteTotalTimeoutConstant     = 1;
+        commTimeout.WriteTotalTimeoutMultiplier = 1;
+        SetCommTimeouts(hSerial, &commTimeout);
+    }
+    _beginthread( RecvthreadFunction, 0, NULL );
+    _beginthread( SendthreadFunction, 0, NULL );
+}
+#endif
+
+
+// Writes one byte to the TX serial buffer. Called by main program.
+void serial_write(uint8_t data) {
+  // Calculate next head
+  uint8_t next_head = serial_tx_buffer_head + 1;
+  #ifdef STM32F103C8
+#ifndef USEUSB
+	USART_SendData(USART1, data);
+	while (!(USART1->SR & USART_FLAG_TXE));		 //µÈ´ý·¢ËÍÍê³É
+    return;
+#endif
+#endif
+  if (next_head == TX_RING_BUFFER) { next_head = 0; }
+
+  // Wait until there is space in the buffer
+  while (next_head == serial_tx_buffer_tail) {
+    // TODO: Restructure st_prep_buffer() calls to be executed here during a long print.
+    if (sys_rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
+#ifdef WIN32
+     Sleep(1);
+#endif
+  }
+
+  // Store data and advance head
+  serial_tx_buffer[serial_tx_buffer_head] = data;
+
+  serial_tx_buffer_head = next_head;
+
+#ifdef AVRTARGET
+  // Enable Data Register Empty Interrupt to make sure tx-streaming is running
+  UCSR0B |=  (1 << UDRIE0);
+#endif
+}
+
+#ifdef AVRTARGET
+// Data Register Empty Interrupt handler
+ISR(SERIAL_UDRE)
+{
+  uint8_t tail = serial_tx_buffer_tail; // Temporary serial_tx_buffer_tail (to optimize for volatile)
+
+  // Send a byte from the buffer
+  UDR0 = serial_tx_buffer[tail];
+
+  // Update tail position
+  tail++;
+  if (tail == TX_RING_BUFFER) { tail = 0; }
+
+  serial_tx_buffer_tail = tail;
+
+  // Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer
+  if (tail == serial_tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }
+}
+#endif
+#ifdef WIN32
+void SendthreadFunction( void *pVoid)
+{
+    unsigned char szBuf[RX_RING_BUFFER + 1];
+
+	DWORD dwBytesWritten;
+	uint8_t nNextTai;
+    for (;;)
+    {
+		while (serial_tx_buffer_head == serial_tx_buffer_tail)
+			Sleep(1);
+	    uint16_t USB_Tx_length;
+
+        if (serial_tx_buffer_head > serial_tx_buffer_tail)
+		    USB_Tx_length = serial_tx_buffer_head - serial_tx_buffer_tail;
+        else
+        {
+		    USB_Tx_length = RX_RING_BUFFER - serial_tx_buffer_tail;
+            if (USB_Tx_length == 0)
+            {
+                USB_Tx_length = serial_tx_buffer_head;
+            }
+        }
+		nNextTai = serial_tx_buffer_tail;
+
+        if (USB_Tx_length != 0)
+        {
+			if (hSerial != INVALID_HANDLE_VALUE)
+			{
+				WriteFile(hSerial, serial_tx_buffer + serial_tx_buffer_tail, USB_Tx_length, &dwBytesWritten, NULL);
+				nNextTai += (uint8_t)dwBytesWritten;
+#ifdef LOCAL_ECHO
+				memcpy(szBuf, &serial_tx_buffer[serial_tx_buffer_tail], dwBytesWritten);
+				szBuf[dwBytesWritten] = 0;
+				printf(szBuf);
+#endif
+			}
+			else
+			{
+			//	fwrite(szBuf, 1, USB_Tx_length, stdout);
+				memcpy(szBuf, &serial_tx_buffer[serial_tx_buffer_tail], USB_Tx_length);
+				szBuf[USB_Tx_length] = 0;
+				printf(szBuf);
+				nNextTai += USB_Tx_length;
+			}
+			if (nNextTai == RX_RING_BUFFER)
+				nNextTai = 0;
+
+			serial_tx_buffer_tail = nNextTai;
+		}
+	}
+}
+#endif
+
+// Fetches the first byte in the serial read buffer. Called by main program.
+uint8_t serial_read()
+{
+  uint8_t tail = serial_rx_buffer_tail; // Temporary serial_rx_buffer_tail (to optimize for volatile)
+  if (serial_rx_buffer_head == tail) {
+    return SERIAL_NO_DATA;
+  } else {
+    uint8_t data = serial_rx_buffer[tail];
+
+    tail++;
+    if (tail == RX_RING_BUFFER) { tail = 0; }
+    serial_rx_buffer_tail = tail;
+
+    return data;
+  }
+}
+
+#ifdef AVRTARGET
+ISR(SERIAL_RX)
+{
+  uint8_t data = UDR0;
+  uint8_t next_head;
+#endif
+#ifdef WIN32
+//#define WINLOG
+void RecvthreadFunction(void *pVoid )
+{
+    DWORD  dwBytesRead;
+    uint8_t data;
+    uint8_t next_head;
+    for (;;)
+    {
+        if (hSerial != INVALID_HANDLE_VALUE)
+        {
+            if (ReadFile(hSerial, &data, 1, &dwBytesRead, NULL) && dwBytesRead == 1)
+            {
+            }
+            else
+            {
+                data = 0;
+            }
+        }
+        else
+        {
+            while (_kbhit() == 0)
+                ;
+            data = _getch();
+        }
+         if (data == 0)
+             continue;
+#endif
+#ifdef STM32F103C8
+#ifdef USEUSB
+void OnUsbDataRx(uint8_t* dataIn, uint8_t length)
+{
+	//lcd_write_char(*dataIn);
+	uint8_t next_head;
+    uint8_t data;
+
+	// Write data to buffer unless it is full.
+	while (length != 0)
+	{
+        data = *dataIn ++;
+#else
+/*----------------------------------------------------------------------------
+  USART1_IRQHandler
+  Handles USART1 global interrupt request.
+ *----------------------------------------------------------------------------*/
+void USART1_IRQHandler (void) 
+{
+    volatile unsigned int IIR;
+    uint8_t data;
+    uint8_t next_head;
+
+    IIR = USART1->SR;
+    if (IIR & USART_FLAG_RXNE) 
+    {                  // read interrupt
+        data = USART1->DR & 0x1FF;
+#endif
+#endif
+  // Pick off realtime command characters directly from the serial stream. These characters are
+  // not passed into the main buffer, but these set system state flag bits for realtime execution.
+  switch (data) {
+    case CMD_RESET:         mc_reset(); break; // Call motion control reset routine.
+    case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true
+    case CMD_CYCLE_START:   system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
+    case CMD_FEED_HOLD:     system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
+    default :
+      if (data > 0x7F) { // Real-time control characters are extended ACSII only.
+        switch(data) {
+          case CMD_SAFETY_DOOR:   system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
+          case CMD_JOG_CANCEL:   
+            if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
+              system_set_exec_state_flag(EXEC_MOTION_CANCEL); 
+            }
+            break; 
+          #ifdef DEBUG
+            case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break;
+          #endif
+          case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break;
+          case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break;
+          case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break;
+          case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break;
+          case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break;
+          case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break;
+          case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break;
+          case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break;
+          case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break;
+          case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
+          case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
+          case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
+          case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
+          case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break;
+          case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
+          #ifdef ENABLE_M7
+            case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
+          #endif
+        }
+        // Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
+      } else { // Write character to buffer
+        next_head = serial_rx_buffer_head + 1;
+        if (next_head == RX_RING_BUFFER) { next_head = 0; }
+
+        // Write data to buffer unless it is full.
+        if (next_head != serial_rx_buffer_tail) {
+          serial_rx_buffer[serial_rx_buffer_head] = data;
+          serial_rx_buffer_head = next_head;
+        }
+      }
+  }
+#ifdef WIN32
+    }
+#endif
+#ifdef STM32F103C8
+#ifndef USEUSB
+        USART1->SR &= ~USART_FLAG_RXNE;	          // clear interrupt
+#else
+    length--;
+#endif
+   }
+#endif
+}
+
+void serial_reset_read_buffer()
+{
+  serial_rx_buffer_tail = serial_rx_buffer_head;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/serial.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,73 @@
+/*
+  serial.c - Low level functions for sending and recieving bytes via the serial port
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef serial_h
+#define serial_h
+
+#ifdef AVRTARGET
+#ifndef RX_BUFFER_SIZE
+  #define RX_BUFFER_SIZE 128
+#endif
+#ifndef TX_BUFFER_SIZE
+  #ifdef USE_LINE_NUMBERS
+    #define TX_BUFFER_SIZE 112
+  #else
+    #define TX_BUFFER_SIZE 104
+  #endif
+#endif
+#else
+#define RX_BUFFER_SIZE 254
+#ifndef WIN32
+#define TX_BUFFER_SIZE 128	// Do not try 256 it will not work for STM32.
+#else
+#define TX_BUFFER_SIZE 254
+#endif
+#endif
+
+#define SERIAL_NO_DATA 0xff
+
+#ifdef WIN32
+void winserial_init(char *pPort);
+#endif
+
+void serial_init();
+
+// Writes one byte to the TX serial buffer. Called by main program.
+void serial_write(uint8_t data);
+
+// Fetches the first byte in the serial read buffer. Called by main program.
+uint8_t serial_read();
+
+// Reset and empty data in read buffer. Used by e-stop and reset.
+void serial_reset_read_buffer();
+
+// Returns the number of bytes available in the RX serial buffer.
+uint8_t serial_get_rx_buffer_available();
+
+// Returns the number of bytes used in the RX serial buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
+uint8_t serial_get_rx_buffer_count();
+
+// Returns the number of bytes used in the TX serial buffer.
+// NOTE: Not used except for debugging and ensuring no TX bottlenecks.
+uint8_t serial_get_tx_buffer_count();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/serial.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,69 @@
+/*
+  serial.c - Low level functions for sending and recieving bytes via the serial port
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef serial_h
+#define serial_h
+
+#if !defined(STM32F103C8)
+#ifndef RX_BUFFER_SIZE
+  #define RX_BUFFER_SIZE 128
+#endif
+#ifndef TX_BUFFER_SIZE
+  #ifdef USE_LINE_NUMBERS
+    #define TX_BUFFER_SIZE 112
+  #else
+    #define TX_BUFFER_SIZE 104
+  #endif
+#endif
+#else
+#define RX_BUFFER_SIZE 254
+#define TX_BUFFER_SIZE 128
+#endif
+
+#define SERIAL_NO_DATA 0xff
+
+#ifdef WIN32
+void winserial_init(char *pPort);
+#endif
+
+void serial_init();
+
+// Writes one byte to the TX serial buffer. Called by main program.
+void serial_write(uint8_t data);
+
+// Fetches the first byte in the serial read buffer. Called by main program.
+uint8_t serial_read();
+
+// Reset and empty data in read buffer. Used by e-stop and reset.
+void serial_reset_read_buffer();
+
+// Returns the number of bytes available in the RX serial buffer.
+uint8_t serial_get_rx_buffer_available();
+
+// Returns the number of bytes used in the RX serial buffer.
+// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
+uint8_t serial_get_rx_buffer_count();
+
+// Returns the number of bytes used in the TX serial buffer.
+// NOTE: Not used except for debugging and ensuring no TX bottlenecks.
+uint8_t serial_get_tx_buffer_count();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/settings.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,317 @@
+/*
+  settings.c - eeprom configuration handling
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+settings_t settings;
+
+
+// Method to store startup lines into EEPROM
+void settings_store_startup_line(uint8_t n, char *line)
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
+    protocol_buffer_synchronize(); // A startup line may contain a motion and be executing. 
+  #endif
+  uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
+  memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE);
+}
+
+
+// Method to store build info into EEPROM
+// NOTE: This function can only be called in IDLE state.
+void settings_store_build_info(char *line)
+{
+  // Build info can only be stored when state is IDLE.
+  memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE);
+}
+
+
+// Method to store coord data parameters into EEPROM
+void settings_write_coord_data(uint8_t coord_select, float *coord_data)
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
+    protocol_buffer_synchronize();
+  #endif
+  uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
+  memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS);
+}
+
+
+// Method to store Grbl global settings struct and version number into EEPROM
+// NOTE: This function can only be called in IDLE state.
+void write_global_settings()
+{
+  eeprom_put_char(0, SETTINGS_VERSION);
+  memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t));
+}
+
+
+// Method to restore EEPROM-saved Grbl global settings back to defaults.
+void settings_restore(uint8_t restore_flag) {
+  if (restore_flag & SETTINGS_RESTORE_DEFAULTS) {
+    settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS;
+    settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
+    settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK;
+    settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK;
+    settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK;
+    settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;
+    settings.arc_tolerance = DEFAULT_ARC_TOLERANCE;
+
+    settings.rpm_max = DEFAULT_SPINDLE_RPM_MAX;
+    settings.rpm_min = DEFAULT_SPINDLE_RPM_MIN;
+
+    settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK;
+    settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE;
+    settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE;
+    settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
+    settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;
+
+    settings.flags = 0;
+    if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }
+    if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }
+    if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
+    if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
+    if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
+    if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; }
+    if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
+    if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
+
+    settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;
+    settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM;
+    settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM;
+    settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE;
+    settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE;
+    settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE;
+    settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION;
+    settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION;
+    settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION;
+    settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL);
+    settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL);
+    settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL);
+
+    write_global_settings();
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_PARAMETERS) {
+    uint8_t idx;
+    float coord_data[N_AXIS];
+    memset(&coord_data, 0, sizeof(coord_data));
+    for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); }
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) {
+    #if N_STARTUP_LINE > 0
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0);
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum
+    #endif
+    #if N_STARTUP_LINE > 1
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0);
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum
+    #endif
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) {
+    eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0);
+    eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum
+  }
+}
+
+
+// Reads startup line from EEPROM. Updated pointed line string data.
+uint8_t settings_read_startup_line(uint8_t n, char *line)
+{
+  uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
+  if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) {
+    // Reset line with default value
+    line[0] = 0; // Empty line
+    settings_store_startup_line(n, line);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Reads startup line from EEPROM. Updated pointed line string data.
+uint8_t settings_read_build_info(char *line)
+{
+  if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) {
+    // Reset line with default value
+    line[0] = 0; // Empty line
+    settings_store_build_info(line);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Read selected coordinate data from EEPROM. Updates pointed coord_data value.
+uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
+{
+  uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
+  if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) {
+    // Reset with default zero vector
+    clear_vector_float(coord_data);
+    settings_write_coord_data(coord_select,coord_data);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Reads Grbl global settings struct from EEPROM.
+uint8_t read_global_settings() {
+  // Check version-byte of eeprom
+  uint8_t version = eeprom_get_char(0);
+  if (version == SETTINGS_VERSION) {
+    // Read settings-record and check checksum
+    if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) {
+      return(false);
+    }
+  } else {
+    return(false);
+  }
+  return(true);
+}
+
+
+// A helper method to set settings from command line
+uint8_t settings_store_global_setting(uint8_t parameter, float value) {
+  if (value < 0.0f) { return(STATUS_NEGATIVE_VALUE); }
+  if (parameter >= AXIS_SETTINGS_START_VAL) {
+    // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines.
+    // NOTE: Ensure the setting index corresponds to the report.c settings printout.
+    parameter -= AXIS_SETTINGS_START_VAL;
+    uint8_t set_idx = 0;
+    while (set_idx < AXIS_N_SETTINGS) {
+      if (parameter < N_AXIS) {
+        // Valid axis setting found.
+        switch (set_idx) {
+          case 0:
+            #ifdef MAX_STEP_RATE_HZ
+            if (value*settings.max_rate[parameter] >(MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
+            #endif
+            settings.steps_per_mm[parameter] = value;
+            break;
+          case 1:
+            #ifdef MAX_STEP_RATE_HZ
+            if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
+            #endif
+            settings.max_rate[parameter] = value;
+            break;
+          case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
+          case 3: settings.max_travel[parameter] = -value; break;  // Store as negative for grbl internal use.
+        }
+        break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call.
+      } else {
+        set_idx++;
+        // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out.
+        if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); }
+        parameter -= AXIS_SETTINGS_INCREMENT;
+      }
+    }
+  } else {
+    // Store non-axis Grbl settings
+    uint8_t int_value = truncf(value);
+    switch(parameter) {
+      case 0:
+        if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); }
+        settings.pulse_microseconds = int_value; break;
+      case 1: settings.stepper_idle_lock_time = int_value; break;
+      case 2:
+        settings.step_invert_mask = int_value;
+        st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
+        break;
+      case 3:
+        settings.dir_invert_mask = int_value;
+        st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
+        break;
+      case 4: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
+        else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; }
+        break;
+      case 5: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
+        else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; }
+        break;
+      case 6: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
+        else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; }
+        probe_configure_invert_mask(false);
+        break;
+      case 10: settings.status_report_mask = int_value; break;
+      case 11: settings.junction_deviation = value; break;
+      case 12: settings.arc_tolerance = value; break;
+      case 13:
+        if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; }
+        else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
+        system_flag_wco_change(); // Make sure WCO is immediately updated.
+        break;
+      case 20:
+        if (int_value) {
+          if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); }
+          settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE;
+        } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; }
+        break;
+      case 21:
+        if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
+        else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
+        limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later.
+        break;
+      case 22:
+        if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; }
+        else {
+          settings.flags &= ~BITFLAG_HOMING_ENABLE;
+          settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits.
+        }
+        break;
+      case 23: settings.homing_dir_mask = int_value; break;
+      case 24: settings.homing_feed_rate = value; break;
+      case 25: settings.homing_seek_rate = value; break;
+      case 26: settings.homing_debounce_delay = int_value; break;
+      case 27: settings.homing_pulloff = value; break;
+      case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration
+      case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration
+      case 32:
+        #ifdef VARIABLE_SPINDLE
+          if (int_value) { settings.flags |= BITFLAG_LASER_MODE; }
+          else { settings.flags &= ~BITFLAG_LASER_MODE; }
+        #else
+				return(STATUS_SETTING_DISABLED_LASER);
+        #endif
+        break;
+      default:
+        return(STATUS_INVALID_STATEMENT);
+    }
+  }
+  write_global_settings();
+  return(STATUS_OK);
+}
+
+
+// Initialize the config subsystem
+void settings_init() {
+  if(!read_global_settings()) {
+    report_status_message(STATUS_SETTING_READ_FAIL);
+    settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data.
+    report_grbl_settings();
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/settings.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,317 @@
+/*
+  settings.c - eeprom configuration handling
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+settings_t settings;
+
+
+// Method to store startup lines into EEPROM
+void settings_store_startup_line(uint8_t n, char *line)
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
+    protocol_buffer_synchronize(); // A startup line may contain a motion and be executing. 
+  #endif
+  uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
+  memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE);
+}
+
+
+// Method to store build info into EEPROM
+// NOTE: This function can only be called in IDLE state.
+void settings_store_build_info(char *line)
+{
+  // Build info can only be stored when state is IDLE.
+  memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE);
+}
+
+
+// Method to store coord data parameters into EEPROM
+void settings_write_coord_data(uint8_t coord_select, float *coord_data)
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
+    protocol_buffer_synchronize();
+  #endif
+  uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
+  memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS);
+}
+
+
+// Method to store Grbl global settings struct and version number into EEPROM
+// NOTE: This function can only be called in IDLE state.
+void write_global_settings()
+{
+  eeprom_put_char(0, SETTINGS_VERSION);
+  memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t));
+}
+
+
+// Method to restore EEPROM-saved Grbl global settings back to defaults.
+void settings_restore(uint8_t restore_flag) {
+  if (restore_flag & SETTINGS_RESTORE_DEFAULTS) {
+    settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS;
+    settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
+    settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK;
+    settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK;
+    settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK;
+    settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;
+    settings.arc_tolerance = DEFAULT_ARC_TOLERANCE;
+
+    settings.rpm_max = DEFAULT_SPINDLE_RPM_MAX;
+    settings.rpm_min = DEFAULT_SPINDLE_RPM_MIN;
+
+    settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK;
+    settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE;
+    settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE;
+    settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
+    settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;
+
+    settings.flags = 0;
+    if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }
+    if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }
+    if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
+    if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
+    if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
+    if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; }
+    if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
+    if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
+
+    settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;
+    settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM;
+    settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM;
+    settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE;
+    settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE;
+    settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE;
+    settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION;
+    settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION;
+    settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION;
+    settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL);
+    settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL);
+    settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL);
+
+    write_global_settings();
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_PARAMETERS) {
+    uint8_t idx;
+    float coord_data[N_AXIS];
+    memset(&coord_data, 0, sizeof(coord_data));
+    for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); }
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) {
+    #if N_STARTUP_LINE > 0
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0);
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum
+    #endif
+    #if N_STARTUP_LINE > 1
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0);
+      eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum
+    #endif
+  }
+
+  if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) {
+    eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0);
+    eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum
+  }
+}
+
+
+// Reads startup line from EEPROM. Updated pointed line string data.
+uint8_t settings_read_startup_line(uint8_t n, char *line)
+{
+  uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
+  if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) {
+    // Reset line with default value
+    line[0] = 0; // Empty line
+    settings_store_startup_line(n, line);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Reads startup line from EEPROM. Updated pointed line string data.
+uint8_t settings_read_build_info(char *line)
+{
+  if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) {
+    // Reset line with default value
+    line[0] = 0; // Empty line
+    settings_store_build_info(line);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Read selected coordinate data from EEPROM. Updates pointed coord_data value.
+uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
+{
+  uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
+  if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) {
+    // Reset with default zero vector
+    clear_vector_float(coord_data);
+    settings_write_coord_data(coord_select,coord_data);
+    return(false);
+  }
+  return(true);
+}
+
+
+// Reads Grbl global settings struct from EEPROM.
+uint8_t read_global_settings() {
+  // Check version-byte of eeprom
+  uint8_t version = eeprom_get_char(0);
+  if (version == SETTINGS_VERSION) {
+    // Read settings-record and check checksum
+    if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) {
+      return(false);
+    }
+  } else {
+    return(false);
+  }
+  return(true);
+}
+
+
+// A helper method to set settings from command line
+uint8_t settings_store_global_setting(uint8_t parameter, float value) {
+  if (value < 0.0f) { return(STATUS_NEGATIVE_VALUE); }
+  if (parameter >= AXIS_SETTINGS_START_VAL) {
+    // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines.
+    // NOTE: Ensure the setting index corresponds to the report.c settings printout.
+    parameter -= AXIS_SETTINGS_START_VAL;
+    uint8_t set_idx = 0;
+    while (set_idx < AXIS_N_SETTINGS) {
+      if (parameter < N_AXIS) {
+        // Valid axis setting found.
+        switch (set_idx) {
+          case 0:
+            #ifdef MAX_STEP_RATE_HZ
+            if (value*settings.max_rate[parameter] >(MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
+            #endif
+            settings.steps_per_mm[parameter] = value;
+            break;
+          case 1:
+            #ifdef MAX_STEP_RATE_HZ
+            if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0f)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
+            #endif
+            settings.max_rate[parameter] = value;
+            break;
+          case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
+          case 3: settings.max_travel[parameter] = -value; break;  // Store as negative for grbl internal use.
+        }
+        break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call.
+      } else {
+        set_idx++;
+        // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out.
+        if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); }
+        parameter -= AXIS_SETTINGS_INCREMENT;
+      }
+    }
+  } else {
+    // Store non-axis Grbl settings
+    uint8_t int_value = trunc(value);
+    switch(parameter) {
+      case 0:
+        if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); }
+        settings.pulse_microseconds = int_value; break;
+      case 1: settings.stepper_idle_lock_time = int_value; break;
+      case 2:
+        settings.step_invert_mask = int_value;
+        st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
+        break;
+      case 3:
+        settings.dir_invert_mask = int_value;
+        st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
+        break;
+      case 4: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
+        else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; }
+        break;
+      case 5: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
+        else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; }
+        break;
+      case 6: // Reset to ensure change. Immediate re-init may cause problems.
+        if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
+        else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; }
+        probe_configure_invert_mask(false);
+        break;
+      case 10: settings.status_report_mask = int_value; break;
+      case 11: settings.junction_deviation = value; break;
+      case 12: settings.arc_tolerance = value; break;
+      case 13:
+        if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; }
+        else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
+        system_flag_wco_change(); // Make sure WCO is immediately updated.
+        break;
+      case 20:
+        if (int_value) {
+          if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); }
+          settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE;
+        } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; }
+        break;
+      case 21:
+        if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
+        else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
+        limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later.
+        break;
+      case 22:
+        if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; }
+        else {
+          settings.flags &= ~BITFLAG_HOMING_ENABLE;
+          settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits.
+        }
+        break;
+      case 23: settings.homing_dir_mask = int_value; break;
+      case 24: settings.homing_feed_rate = value; break;
+      case 25: settings.homing_seek_rate = value; break;
+      case 26: settings.homing_debounce_delay = int_value; break;
+      case 27: settings.homing_pulloff = value; break;
+      case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration
+      case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration
+      case 32:
+        #ifdef VARIABLE_SPINDLE
+          if (int_value) { settings.flags |= BITFLAG_LASER_MODE; }
+          else { settings.flags &= ~BITFLAG_LASER_MODE; }
+        #else
+					return(STATUS_SETTING_DISABLED_LASER); 
+        #endif
+        break;
+      default:
+        return(STATUS_INVALID_STATEMENT);
+    }
+  }
+  write_global_settings();
+  return(STATUS_OK);
+}
+
+
+// Initialize the config subsystem
+void settings_init() {
+  if(!read_global_settings()) {
+    report_status_message(STATUS_SETTING_READ_FAIL);
+    settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data.
+    report_grbl_settings();
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/settings.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,134 @@
+/*
+  settings.h - eeprom configuration handling
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef settings_h
+#define settings_h
+
+#include "grbl.h"
+
+
+// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
+// when firmware is upgraded. Always stored in byte 0 of eeprom
+#define SETTINGS_VERSION 10  // NOTE: Check settings_reset() when moving to next version.
+
+// Define bit flag masks for the boolean settings in settings.flag.
+#define BITFLAG_REPORT_INCHES      bit(0)
+#define BITFLAG_LASER_MODE         bit(1)
+#define BITFLAG_INVERT_ST_ENABLE   bit(2)
+#define BITFLAG_HARD_LIMIT_ENABLE  bit(3)
+#define BITFLAG_HOMING_ENABLE      bit(4)
+#define BITFLAG_SOFT_LIMIT_ENABLE  bit(5)
+#define BITFLAG_INVERT_LIMIT_PINS  bit(6)
+#define BITFLAG_INVERT_PROBE_PIN   bit(7)
+
+// Define status reporting boolean enable bit flags in settings.status_report_mask
+#define BITFLAG_RT_STATUS_POSITION_TYPE     bit(0)
+#define BITFLAG_RT_STATUS_BUFFER_STATE      bit(1)
+
+// Define settings restore bitflags.
+#define SETTINGS_RESTORE_DEFAULTS bit(0)
+#define SETTINGS_RESTORE_PARAMETERS bit(1)
+#define SETTINGS_RESTORE_STARTUP_LINES bit(2)
+#define SETTINGS_RESTORE_BUILD_INFO bit(3)
+#ifndef SETTINGS_RESTORE_ALL
+  #define SETTINGS_RESTORE_ALL 0xFF // All bitflags
+#endif
+
+// Define EEPROM memory address location values for Grbl settings and parameters
+// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and
+// the startup script. The lower half contains the global settings and space for future
+// developments.
+#define EEPROM_ADDR_GLOBAL         1U
+#define EEPROM_ADDR_PARAMETERS     512U
+#define EEPROM_ADDR_STARTUP_BLOCK  768U
+#define EEPROM_ADDR_BUILD_INFO     942U
+
+// Define EEPROM address indexing for coordinate parameters
+#define N_COORDINATE_SYSTEM 6  // Number of supported work coordinate systems (from index 1)
+#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0)
+// NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59)
+#define SETTING_INDEX_G28    N_COORDINATE_SYSTEM    // Home position 1
+#define SETTING_INDEX_G30    N_COORDINATE_SYSTEM+1  // Home position 2
+// #define SETTING_INDEX_G92    N_COORDINATE_SYSTEM+2  // Coordinate offset (G92.2,G92.3 not supported)
+
+// Define Grbl axis settings numbering scheme. Starts at START_VAL, every INCREMENT, over N_SETTINGS.
+#define AXIS_N_SETTINGS          4
+#define AXIS_SETTINGS_START_VAL  100 // NOTE: Reserving settings values >= 100 for axis settings. Up to 255.
+#define AXIS_SETTINGS_INCREMENT  10  // Must be greater than the number of axis settings
+
+// Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards)
+typedef struct {
+  // Axis settings
+  float steps_per_mm[N_AXIS];
+  float max_rate[N_AXIS];
+  float acceleration[N_AXIS];
+  float max_travel[N_AXIS];
+
+  // Remaining Grbl settings
+  uint8_t pulse_microseconds;
+  uint8_t step_invert_mask;
+  uint8_t dir_invert_mask;
+  uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable.
+  uint8_t status_report_mask; // Mask to indicate desired report data.
+  float junction_deviation;
+  float arc_tolerance;
+
+  float rpm_max;
+  float rpm_min;
+
+  uint8_t flags;  // Contains default boolean settings
+
+  uint8_t homing_dir_mask;
+  float homing_feed_rate;
+  float homing_seek_rate;
+  uint16_t homing_debounce_delay;
+  float homing_pulloff;
+} settings_t;
+extern settings_t settings;
+
+// Initialize the configuration subsystem (load settings from EEPROM)
+void settings_init();
+
+// Helper function to clear and restore EEPROM defaults
+void settings_restore(uint8_t restore_flag);
+
+// A helper method to set new settings from command line
+uint8_t settings_store_global_setting(uint8_t parameter, float value);
+
+// Stores the protocol line variable as a startup line in EEPROM
+void settings_store_startup_line(uint8_t n, char *line);
+
+// Reads an EEPROM startup line to the protocol line variable
+uint8_t settings_read_startup_line(uint8_t n, char *line);
+
+// Stores build info user-defined string
+void settings_store_build_info(char *line);
+
+// Reads build info user-defined string
+uint8_t settings_read_build_info(char *line);
+
+// Writes selected coordinate data to EEPROM
+void settings_write_coord_data(uint8_t coord_select, float *coord_data);
+
+// Reads selected coordinate data from EEPROM
+uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/spindle_control.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,330 @@
+/*
+  spindle_control.c - spindle control methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+#ifdef VARIABLE_SPINDLE
+  static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
+#endif
+
+
+void spindle_init()
+{
+#ifdef VARIABLE_SPINDLE
+  pwm_gradient = SPINDLE_PWM_RANGE / (settings.rpm_max - settings.rpm_min);
+#endif
+
+#ifdef AVRTARGET
+  #ifdef VARIABLE_SPINDLE
+
+    // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are
+    // combined unless configured otherwise.
+    SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT); // Configure as PWM output pin.
+    SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK; // Configure PWM output compare timer
+    SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK;
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
+    #else
+      SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
+    #endif
+
+  #else
+
+    // Configure no variable spindle and only enable pin.
+    SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
+    SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
+
+  #endif
+#endif
+#if defined (STM32F103C8)
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_SPINDLE_ENABLE_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_ENABLE_BIT;
+#else
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_DIRECTION_BIT;
+#endif
+  GPIO_Init(SPINDLE_ENABLE_PORT, &GPIO_InitStructure);
+
+
+#ifdef VARIABLE_SPINDLE
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+  TIM_TimeBaseInitTypeDef timerInitStructure;
+  TIM_OCInitTypeDef outputChannelInit = { 0 };
+  TIM_TimeBaseStructInit(&timerInitStructure);
+
+  timerInitStructure.TIM_Prescaler = F_CPU / 1000000 - 1; // 1000
+  timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  timerInitStructure.TIM_Period = SPINDLE_PWM_MAX_VALUE - 1;
+  timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
+  timerInitStructure.TIM_RepetitionCounter = 0;
+  TIM_TimeBaseInit(TIM1, &timerInitStructure);
+
+  outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
+  outputChannelInit.TIM_Pulse = 0;     // initi speed is 0
+  outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
+  outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
+
+  TIM_OC1Init(TIM1, &outputChannelInit);
+  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
+  TIM_CtrlPWMOutputs(TIM1, DISABLE);
+  TIM_Cmd(TIM1, ENABLE);
+
+  RCC_APB2PeriphClockCmd(RCC_SPINDLE_PWM_PORT, ENABLE);
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_PWM_BIT;
+  GPIO_Init(SPINDLE_PWM_PORT, &GPIO_InitStructure);
+
+
+#endif
+#endif
+
+  spindle_stop();
+}
+
+
+uint8_t spindle_get_state()
+{
+  uint8_t pin = 0;
+	#ifdef VARIABLE_SPINDLE
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#ifdef AVRTARGET
+  pin = SPINDLE_ENABLE_PORT;
+#endif
+#if defined (STM32F103C8)
+  pin = GPIO_ReadInputData(SPINDLE_ENABLE_PORT);
+#endif
+		  // No spindle direction output pin. 
+			#ifdef INVERT_SPINDLE_ENABLE_PIN
+			  if (bit_isfalse(pin,(1<<SPINDLE_ENABLE_BIT))) { return(SPINDLE_STATE_CW); }
+	    #else
+	 			if (bit_istrue(pin,(1<<SPINDLE_ENABLE_BIT))) { return(SPINDLE_STATE_CW); }
+	    #endif
+    #else
+#ifdef AVRTARGET
+  pin = SPINDLE_DIRECTION_PORT;
+    if (SPINDLE_TCCRA_REGISTER & (1<<SPINDLE_COMB_BIT)) 
+#endif
+#if defined (STM32F103C8)
+      pin = GPIO_ReadInputData(SPINDLE_DIRECTION_PORT);
+#endif
+     {
+        if (pin & (1<<SPINDLE_DIRECTION_BIT)) { return(SPINDLE_STATE_CCW); }
+        else { return(SPINDLE_STATE_CW); }
+      }
+    #endif
+	#else
+#ifdef AVRTARGET
+  pin = SPINDLE_ENABLE_PORT;
+#endif
+#if defined (STM32F103C8)
+  pin = GPIO_ReadInputData(SPINDLE_ENABLE_PORT);
+#endif
+		#ifdef INVERT_SPINDLE_ENABLE_PIN
+		  if (bit_isfalse(pin,(1<<SPINDLE_ENABLE_BIT))) {
+		#else
+		  if (bit_istrue(pin,(1<<SPINDLE_ENABLE_BIT))) {
+		#endif
+		  if (pin & (1 << SPINDLE_DIRECTION_BIT)) { return(SPINDLE_STATE_CCW); }
+		  else { return(SPINDLE_STATE_CW); }
+		}
+	#endif
+	return(SPINDLE_STATE_DISABLE);
+}
+
+
+// Disables the spindle and sets PWM output to zero when PWM variable spindle speed is enabled.
+// Called by various main program and ISR routines. Keep routine small, fast, and efficient.
+// Called by spindle_init(), spindle_set_speed(), spindle_set_state(), and mc_reset().
+void spindle_stop()
+{
+#ifdef VARIABLE_SPINDLE
+#ifdef AVRTARGET
+    SPINDLE_TCCRA_REGISTER &= ~(1<<SPINDLE_COMB_BIT); // Disable PWM. Output voltage is zero.
+#endif
+#if defined (STM32F103C8)
+    TIM_CtrlPWMOutputs(TIM1, DISABLE);
+#endif
+
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      #ifdef INVERT_SPINDLE_ENABLE_PIN
+        SetSpindleEnablebit();
+      #else
+        ResetSpindleEnablebit();
+      #endif
+    #endif
+#else
+    #ifdef INVERT_SPINDLE_ENABLE_PIN
+      SetSpindleEnablebit();
+    #else
+      ResetSpindleEnablebit();
+    #endif
+#endif
+}
+
+
+#ifdef VARIABLE_SPINDLE
+  // Sets spindle speed PWM output and enable pin, if configured. Called by spindle_set_state()
+  // and stepper ISR. Keep routine small and efficient.
+  void spindle_set_speed(SPINDLE_PWM_TYPE pwm_value)
+  {
+#ifdef AVRTARGET
+		SPINDLE_OCR_REGISTER = pwm_value; // Set PWM output level.
+#endif
+#if defined (STM32F103C8)
+		TIM1->CCR1 = pwm_value;
+#endif
+		#ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED
+     if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
+        spindle_stop();
+      } else {
+				#ifdef AVRTARGET
+					SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT); // Ensure PWM output is enabled.
+				#endif
+				#if defined (STM32F103C8)
+						TIM_CtrlPWMOutputs(TIM1, ENABLE);
+				#endif
+				#ifdef INVERT_SPINDLE_ENABLE_PIN
+					ResetSpindleEnablebit();
+				#else
+					SetSpindleEnablebit();
+				#endif
+		 }
+		#else
+			if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
+			#ifdef AVRTARGET
+				SPINDLE_TCCRA_REGISTER &= ~(1 << SPINDLE_COMB_BIT); // Disable PWM. Output voltage is zero.
+			#endif
+			#if defined (STM32F103C8)
+				TIM_CtrlPWMOutputs(TIM1, DISABLE);
+			#endif
+			} else {
+			#ifdef AVRTARGET
+      SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT); // Ensure PWM output is enabled.
+			#endif
+			#if defined (STM32F103C8)
+      TIM_CtrlPWMOutputs(TIM1, ENABLE);
+			#endif
+			}
+		#endif
+	}
+
+
+  // Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
+  SPINDLE_PWM_TYPE spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit.
+  {
+    SPINDLE_PWM_TYPE pwm_value;
+    rpm *= (0.010f*sys.spindle_speed_ovr); // Scale by spindle speed override value.
+    // Calculate PWM register value based on rpm max/min settings and programmed rpm.
+    if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) {
+      // No PWM range possible. Set simple on/off spindle control pin state.
+      sys.spindle_speed = settings.rpm_max;
+      pwm_value = SPINDLE_PWM_MAX_VALUE;
+    } else if (rpm <= settings.rpm_min) {
+      if (rpm == 0.0f) { // S0 disables spindle
+        sys.spindle_speed = 0.0f;
+        pwm_value = SPINDLE_PWM_OFF_VALUE;
+      } else { // Set minimum PWM output
+        sys.spindle_speed = settings.rpm_min;
+        pwm_value = SPINDLE_PWM_MIN_VALUE;
+      }
+    } else { 
+      // Compute intermediate PWM value with linear spindle speed model.
+      // NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight.
+      sys.spindle_speed = rpm;
+	    pwm_value = (SPINDLE_PWM_TYPE)floorf((rpm - settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
+    }
+    return(pwm_value);
+  }
+#endif
+
+
+// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled.
+// Called by g-code parser spindle_sync(), parking retract and restore, g-code program end,
+// sleep, and spindle stop override.
+#ifdef VARIABLE_SPINDLE
+  void spindle_set_state(uint8_t state, float rpm)
+#else
+  void _spindle_set_state(uint8_t state)
+#endif
+{
+  if (sys.abort) { return; } // Block during abort.
+  if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm.
+  
+    #ifdef VARIABLE_SPINDLE
+      sys.spindle_speed = 0.0f;
+    #endif
+    spindle_stop();
+  
+  } else {
+    #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      if (state == SPINDLE_ENABLE_CW) {
+        ResetSpindleDirectionBit();
+	  }
+	  else {
+      SetSpindleDirectionBit();
+      }
+    #endif
+  
+    #ifdef VARIABLE_SPINDLE
+      // NOTE: Assumes all calls to this function is when Grbl is not moving or must remain off.
+      if (settings.flags & BITFLAG_LASER_MODE) {
+        if (state == SPINDLE_ENABLE_CCW) { rpm = 0.0f; } // TODO: May need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE);
+      }
+    spindle_set_speed(spindle_compute_pwm_value(rpm));
+		#endif
+    #if (defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && \
+        !defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED)) || !defined(VARIABLE_SPINDLE)
+      // NOTE: Without variable spindle, the enable bit should just turn on or off, regardless
+      // if the spindle speed value is zero, as its ignored anyhow.
+      #ifdef INVERT_SPINDLE_ENABLE_PIN
+        ResetSpindleEnablebit();
+      #else
+        SetSpindleEnablebit();
+      #endif    
+    #endif
+  }
+  
+  sys.report_ovr_counter = 0; // Set to report change immediately
+}
+
+
+// G-code parser entry-point for setting spindle state. Forces a planner buffer sync and bails 
+// if an abort or check-mode is active.
+#ifdef VARIABLE_SPINDLE
+  void spindle_sync(uint8_t state, float rpm)
+  {
+    if (sys.state == STATE_CHECK_MODE) { return; }
+    protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed.
+    spindle_set_state(state,rpm);
+  }
+#else
+  void _spindle_sync(uint8_t state)
+  {
+    if (sys.state == STATE_CHECK_MODE) { return; }
+    protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed.
+    _spindle_set_state(state);
+  }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/spindle_control.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,330 @@
+/*
+  spindle_control.c - spindle control methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+#ifdef VARIABLE_SPINDLE
+  static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
+#endif
+
+
+void spindle_init()
+{
+#ifdef VARIABLE_SPINDLE
+  pwm_gradient = SPINDLE_PWM_RANGE / (settings.rpm_max - settings.rpm_min);
+#endif
+
+#ifdef AVRTARGET
+  #ifdef VARIABLE_SPINDLE
+
+    // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are
+    // combined unless configured otherwise.
+    SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT); // Configure as PWM output pin.
+    SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK; // Configure PWM output compare timer
+    SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK;
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
+    #else
+      SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
+    #endif
+
+  #else
+
+    // Configure no variable spindle and only enable pin.
+    SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
+    SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
+
+  #endif
+#endif
+#if defined (STM32F103C8)
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_SPINDLE_ENABLE_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_ENABLE_BIT;
+#else
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_DIRECTION_BIT;
+#endif
+  GPIO_Init(SPINDLE_ENABLE_PORT, &GPIO_InitStructure);
+
+
+#ifdef VARIABLE_SPINDLE
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+  TIM_TimeBaseInitTypeDef timerInitStructure;
+  TIM_OCInitTypeDef outputChannelInit = { 0 };
+  TIM_TimeBaseStructInit(&timerInitStructure);
+
+  timerInitStructure.TIM_Prescaler = F_CPU / 1000000 - 1; // 1000K
+  timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  timerInitStructure.TIM_Period = SPINDLE_PWM_MAX_VALUE - 1;
+  timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
+  timerInitStructure.TIM_RepetitionCounter = 0;
+  TIM_TimeBaseInit(TIM1, &timerInitStructure);
+
+  outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
+  outputChannelInit.TIM_Pulse = 0;     // initi speed is 0
+  outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
+  outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
+
+  TIM_OC1Init(TIM1, &outputChannelInit);
+  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
+  TIM_CtrlPWMOutputs(TIM1, DISABLE);
+  TIM_Cmd(TIM1, ENABLE);
+
+  RCC_APB2PeriphClockCmd(RCC_SPINDLE_PWM_PORT, ENABLE);
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+  GPIO_InitStructure.GPIO_Pin = 1 << SPINDLE_PWM_BIT;
+  GPIO_Init(SPINDLE_PWM_PORT, &GPIO_InitStructure);
+
+
+#endif
+#endif
+
+  spindle_stop();
+}
+
+
+uint8_t spindle_get_state()
+{
+  uint8_t pin = 0;
+	#ifdef VARIABLE_SPINDLE
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+#ifdef AVRTARGET
+  pin = SPINDLE_ENABLE_PORT;
+#endif
+#if defined (STM32F103C8)
+  pin = GPIO_ReadInputData(SPINDLE_ENABLE_PORT);
+#endif
+		  // No spindle direction output pin. 
+			#ifdef INVERT_SPINDLE_ENABLE_PIN
+			  if (bit_isfalse(pin,(1<<SPINDLE_ENABLE_BIT))) { return(SPINDLE_STATE_CW); }
+	    #else
+	 			if (bit_istrue(pin,(1<<SPINDLE_ENABLE_BIT))) { return(SPINDLE_STATE_CW); }
+	    #endif
+    #else
+#ifdef AVRTARGET
+  pin = SPINDLE_DIRECTION_PORT;
+    if (SPINDLE_TCCRA_REGISTER & (1<<SPINDLE_COMB_BIT)) 
+#endif
+#if defined (STM32F103C8)
+      pin = GPIO_ReadInputData(SPINDLE_DIRECTION_PORT);
+#endif
+     {
+        if (pin & (1<<SPINDLE_DIRECTION_BIT)) { return(SPINDLE_STATE_CCW); }
+        else { return(SPINDLE_STATE_CW); }
+      }
+    #endif
+	#else
+#ifdef AVRTARGET
+  pin = SPINDLE_ENABLE_PORT;
+#endif
+#if defined (STM32F103C8)
+  pin = GPIO_ReadInputData(SPINDLE_ENABLE_PORT);
+#endif
+		#ifdef INVERT_SPINDLE_ENABLE_PIN
+		  if (bit_isfalse(pin,(1<<SPINDLE_ENABLE_BIT))) {
+		#else
+		  if (bit_istrue(pin,(1<<SPINDLE_ENABLE_BIT))) {
+		#endif
+		  if (pin & (1 << SPINDLE_DIRECTION_BIT)) { return(SPINDLE_STATE_CCW); }
+		  else { return(SPINDLE_STATE_CW); }
+		}
+	#endif
+	return(SPINDLE_STATE_DISABLE);
+}
+
+
+// Disables the spindle and sets PWM output to zero when PWM variable spindle speed is enabled.
+// Called by various main program and ISR routines. Keep routine small, fast, and efficient.
+// Called by spindle_init(), spindle_set_speed(), spindle_set_state(), and mc_reset().
+void spindle_stop()
+{
+#ifdef VARIABLE_SPINDLE
+#ifdef AVRTARGET
+    SPINDLE_TCCRA_REGISTER &= ~(1<<SPINDLE_COMB_BIT); // Disable PWM. Output voltage is zero.
+#endif
+#if defined (STM32F103C8)
+    TIM_CtrlPWMOutputs(TIM1, DISABLE);
+#endif
+
+    #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      #ifdef INVERT_SPINDLE_ENABLE_PIN
+        SetSpindleEnablebit();
+      #else
+        ResetSpindleEnablebit();
+      #endif
+    #endif
+#else
+    #ifdef INVERT_SPINDLE_ENABLE_PIN
+      SetSpindleEnablebit();
+    #else
+      ResetSpindleEnablebit();
+    #endif
+#endif
+}
+
+
+#ifdef VARIABLE_SPINDLE
+  // Sets spindle speed PWM output and enable pin, if configured. Called by spindle_set_state()
+  // and stepper ISR. Keep routine small and efficient.
+  void spindle_set_speed(SPINDLE_PWM_TYPE pwm_value)
+  {
+#ifdef AVRTARGET
+		SPINDLE_OCR_REGISTER = pwm_value; // Set PWM output level.
+#endif
+#if defined (STM32F103C8)
+		TIM1->CCR1 = pwm_value;
+#endif
+		#ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED
+     if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
+        spindle_stop();
+      } else {
+				#ifdef AVRTARGET
+					SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT); // Ensure PWM output is enabled.
+				#endif
+				#if defined (STM32F103C8)
+						TIM_CtrlPWMOutputs(TIM1, ENABLE);
+				#endif
+				#ifdef INVERT_SPINDLE_ENABLE_PIN
+					ResetSpindleEnablebit();
+				#else
+					SetSpindleEnablebit();
+				#endif
+		 }
+		#else
+			if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
+			#ifdef AVRTARGET
+				SPINDLE_TCCRA_REGISTER &= ~(1 << SPINDLE_COMB_BIT); // Disable PWM. Output voltage is zero.
+			#endif
+			#if defined (STM32F103C8)
+				TIM_CtrlPWMOutputs(TIM1, DISABLE);
+			#endif
+			} else {
+			#ifdef AVRTARGET
+      SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT); // Ensure PWM output is enabled.
+			#endif
+			#if defined (STM32F103C8)
+      TIM_CtrlPWMOutputs(TIM1, ENABLE);
+			#endif
+			}
+		#endif
+  }
+
+
+  // Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
+  SPINDLE_PWM_TYPE spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit.
+  {
+    SPINDLE_PWM_TYPE pwm_value;
+    rpm *= (0.010f*sys.spindle_speed_ovr); // Scale by spindle speed override value.
+    // Calculate PWM register value based on rpm max/min settings and programmed rpm.
+    if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) {
+      // No PWM range possible. Set simple on/off spindle control pin state.
+      sys.spindle_speed = settings.rpm_max;
+      pwm_value = SPINDLE_PWM_MAX_VALUE;
+    } else if (rpm <= settings.rpm_min) {
+      if (rpm == 0.0f) { // S0 disables spindle
+        sys.spindle_speed = 0.0f;
+        pwm_value = SPINDLE_PWM_OFF_VALUE;
+      } else { // Set minimum PWM output
+        sys.spindle_speed = settings.rpm_min;
+        pwm_value = SPINDLE_PWM_MIN_VALUE;
+      }
+    } else { 
+      // Compute intermediate PWM value with linear spindle speed model.
+      // NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight.
+      sys.spindle_speed = rpm;
+	    pwm_value = (SPINDLE_PWM_TYPE)floorf((rpm - settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
+    }
+    return(pwm_value);
+  }
+#endif
+
+
+// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled.
+// Called by g-code parser spindle_sync(), parking retract and restore, g-code program end,
+// sleep, and spindle stop override.
+#ifdef VARIABLE_SPINDLE
+  void spindle_set_state(uint8_t state, float rpm)
+#else
+  void _spindle_set_state(uint8_t state)
+#endif
+{
+  if (sys.abort) { return; } // Block during abort.
+  if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm.
+  
+    #ifdef VARIABLE_SPINDLE
+      sys.spindle_speed = 0.0f;
+    #endif
+    spindle_stop();
+  
+  } else {
+    #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
+      if (state == SPINDLE_ENABLE_CW) {
+        ResetSpindleDirectionBit();
+	  }
+	  else {
+      SetSpindleDirectionBit();
+      }
+    #endif
+  
+    #ifdef VARIABLE_SPINDLE
+      // NOTE: Assumes all calls to this function is when Grbl is not moving or must remain off.
+      if (settings.flags & BITFLAG_LASER_MODE) {
+        if (state == SPINDLE_ENABLE_CCW) { rpm = 0.0f; } // TODO: May need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE);
+      }
+    spindle_set_speed(spindle_compute_pwm_value(rpm));
+		#endif
+    #if (defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && \
+        !defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED)) || !defined(VARIABLE_SPINDLE)
+      // NOTE: Without variable spindle, the enable bit should just turn on or off, regardless
+      // if the spindle speed value is zero, as its ignored anyhow.
+      #ifdef INVERT_SPINDLE_ENABLE_PIN
+        ResetSpindleEnablebit();
+      #else
+        SetSpindleEnablebit();
+      #endif    
+    #endif
+  }
+  
+  sys.report_ovr_counter = 0; // Set to report change immediately
+}
+
+
+// G-code parser entry-point for setting spindle state. Forces a planner buffer sync and bails 
+// if an abort or check-mode is active.
+#ifdef VARIABLE_SPINDLE
+  void spindle_sync(uint8_t state, float rpm)
+  {
+    if (sys.state == STATE_CHECK_MODE) { return; }
+    protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed.
+    spindle_set_state(state,rpm);
+  }
+#else
+  void _spindle_sync(uint8_t state)
+  {
+    if (sys.state == STATE_CHECK_MODE) { return; }
+    protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed.
+    _spindle_set_state(state);
+  }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/spindle_control.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,78 @@
+/*
+  spindle_control.h - spindle control methods
+  Part of Grbl
+
+  Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef spindle_control_h
+#define spindle_control_h
+
+#define SPINDLE_NO_SYNC false
+#define SPINDLE_FORCE_SYNC true
+
+#define SPINDLE_STATE_DISABLE  0  // Must be zero.
+#define SPINDLE_STATE_CW       bit(0)
+#define SPINDLE_STATE_CCW      bit(1)
+
+
+// Initializes spindle pins and hardware PWM, if enabled.
+void spindle_init();
+
+// Returns current spindle output state. Overrides may alter it from programmed states.
+uint8_t spindle_get_state();
+
+// Called by g-code parser when setting spindle state and requires a buffer sync.
+// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled.
+// Called by spindle_sync() after sync and parking motion/spindle stop override during restore.
+#ifdef VARIABLE_SPINDLE
+#ifdef STM32F103C8
+#define SPINDLE_PWM_TYPE    uint16_t
+#else
+#define SPINDLE_PWM_TYPE    uint8_t
+#endif
+
+  // Called by g-code parser when setting spindle state and requires a buffer sync.
+  void spindle_sync(uint8_t state, float rpm);
+
+  // Sets spindle running state with direction, enable, and spindle PWM.
+  void spindle_set_state(uint8_t state, float rpm); 
+  
+  // Sets spindle PWM quickly for stepper ISR. Also called by spindle_set_state().
+  // NOTE: 328p PWM register is 8-bit.
+  void spindle_set_speed(SPINDLE_PWM_TYPE pwm_value);
+  
+  // Computes 328p-specific PWM register value for the given RPM for quick updating.
+  SPINDLE_PWM_TYPE spindle_compute_pwm_value(float rpm);
+  
+#else
+  
+  // Called by g-code parser when setting spindle state and requires a buffer sync.
+  #define spindle_sync(state, rpm) _spindle_sync(state)
+  void _spindle_sync(uint8_t state);
+
+  // Sets spindle running state with direction and enable.
+  #define spindle_set_state(state, rpm) _spindle_set_state(state)
+  void _spindle_set_state(uint8_t state);
+
+#endif
+
+// Stop and start spindle routines. Called by all spindle routines and stepper ISR.
+void spindle_stop();
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/stepper.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1301 @@
+/*
+  stepper.c - stepper motor driver: executes motion plans using stepper motors
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+#ifdef STM32F103C8
+typedef int bool;
+#include "stm32f10x_rcc.h"
+#include "stm32f10x_tim.h"
+#include "misc.h"
+void TIM_Configuration(TIM_TypeDef* TIMER, u16 Period, u16 Prescaler, u8 PP);
+#endif
+
+
+// Some useful constants.
+#define DT_SEGMENT (1.0f/(ACCELERATION_TICKS_PER_SECOND*60.0f)) // min/segment
+#define REQ_MM_INCREMENT_SCALAR 1.25f
+#define RAMP_ACCEL 0
+#define RAMP_CRUISE 1
+#define RAMP_DECEL 2
+#define RAMP_DECEL_OVERRIDE 3
+
+#define PREP_FLAG_RECALCULATE bit(0)
+#define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1)
+#define PREP_FLAG_PARKING bit(2)
+#define PREP_FLAG_DECEL_OVERRIDE bit(3)
+const PORTPINDEF step_pin_mask[N_AXIS] =
+{
+	1 << X_STEP_BIT,
+	1 << Y_STEP_BIT,
+	1 << Z_STEP_BIT,
+
+};
+const PORTPINDEF direction_pin_mask[N_AXIS] =
+{
+	1 << X_DIRECTION_BIT,
+	1 << Y_DIRECTION_BIT,
+	1 << Z_DIRECTION_BIT,
+};
+const PORTPINDEF limit_pin_mask[N_AXIS] =
+{
+	1 << X_LIMIT_BIT,
+	1 << Y_LIMIT_BIT,
+	1 << Z_LIMIT_BIT,
+};
+
+// Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level
+// frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin
+// starts at the next higher cutoff frequency, and so on. The cutoff frequencies for each level must
+// be considered carefully against how much it over-drives the stepper ISR, the accuracy of the 16-bit
+// timer, and the CPU overhead. Level 0 (no AMASS, normal operation) frequency bin starts at the
+// Level 1 cutoff frequency and up to as fast as the CPU allows (over 30kHz in limited testing).
+// NOTE: AMASS cutoff frequency multiplied by ISR overdrive factor must not exceed maximum step frequency.
+// NOTE: Current settings are set to overdrive the ISR to no more than 16kHz, balancing CPU overhead
+// and timer accuracy.  Do not alter these settings unless you know what you are doing.
+#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+	#define MAX_AMASS_LEVEL 3
+	// AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency.
+	#define AMASS_LEVEL1 (F_CPU/8000) // Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz)
+	#define AMASS_LEVEL2 (F_CPU/4000) // Over-drives ISR (x4)
+	#define AMASS_LEVEL3 (F_CPU/2000) // Over-drives ISR (x8)
+
+  #if MAX_AMASS_LEVEL <= 0
+    error "AMASS must have 1 or more levels to operate correctly."
+  #endif
+#endif
+#ifdef WIN32
+#include <process.h> 
+unsigned char PORTB = 0;
+unsigned char DDRD = 0;
+unsigned char DDRB = 0;
+unsigned char PORTD = 0;
+LARGE_INTEGER Win32Frequency;
+LONGLONG nTimer1Out = 0;
+LONGLONG nTimer0Out = 0;
+#endif
+
+
+// Stores the planner block Bresenham algorithm execution data for the segments in the segment
+// buffer. Normally, this buffer is partially in-use, but, for the worst case scenario, it will
+// never exceed the number of accessible stepper buffer segments (SEGMENT_BUFFER_SIZE-1).
+// NOTE: This data is copied from the prepped planner blocks so that the planner blocks may be
+// discarded when entirely consumed and completed by the segment buffer. Also, AMASS alters this
+// data for its own use.
+typedef struct {
+  uint32_t steps[N_AXIS];
+  uint32_t step_event_count;
+  uint8_t direction_bits;
+  #ifdef VARIABLE_SPINDLE
+    uint8_t is_pwm_rate_adjusted; // Tracks motions that require constant laser power/rate
+  #endif
+} st_block_t;
+static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1];
+
+// Primary stepper segment ring buffer. Contains small, short line segments for the stepper
+// algorithm to execute, which are "checked-out" incrementally from the first block in the
+// planner buffer. Once "checked-out", the steps in the segments buffer cannot be modified by
+// the planner, where the remaining planner block steps still can.
+typedef struct {
+  uint16_t n_step;           // Number of step events to be executed for this segment
+  uint16_t cycles_per_tick;  // Step distance traveled per ISR tick, aka step rate.
+  uint8_t  st_block_index;   // Stepper block data index. Uses this information to execute this segment.
+  #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+    uint8_t amass_level;    // Indicates AMASS level for the ISR to execute this segment
+  #else
+    uint8_t prescaler;      // Without AMASS, a prescaler is required to adjust for slow timing.
+  #endif
+  #ifdef VARIABLE_SPINDLE
+    uint8_t spindle_pwm;
+  #endif
+} segment_t;
+static segment_t segment_buffer[SEGMENT_BUFFER_SIZE];
+
+// Stepper ISR data struct. Contains the running data for the main stepper ISR.
+typedef struct {
+  // Used by the bresenham line algorithm
+  uint32_t counter_x,        // Counter variables for the bresenham line tracer
+           counter_y,
+           counter_z;
+  #ifdef STEP_PULSE_DELAY
+    uint8_t step_bits;  // Stores out_bits output to complete the step pulse delay
+  #endif
+
+  uint8_t execute_step;     // Flags step execution for each interrupt.
+#ifndef WIN32
+  uint8_t step_pulse_time;  // Step pulse reset time after step rise
+#else
+  LONGLONG step_pulse_time;
+#endif
+  PORTPINDEF step_outbits;         // The next stepping-bits to be output
+  PORTPINDEF dir_outbits;
+  #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+    uint32_t steps[N_AXIS];
+  #endif
+
+  uint16_t step_count;       // Steps remaining in line segment motion
+  uint8_t exec_block_index; // Tracks the current st_block index. Change indicates new block.
+  st_block_t *exec_block;   // Pointer to the block data for the segment being executed
+  segment_t *exec_segment;  // Pointer to the segment being executed
+} stepper_t;
+static stepper_t st;
+
+// Step segment ring buffer indices
+static volatile uint8_t segment_buffer_tail;
+static uint8_t segment_buffer_head;
+static uint8_t segment_next_head;
+
+// Step and direction port invert masks.
+static PORTPINDEF step_port_invert_mask;
+static PORTPINDEF dir_port_invert_mask;
+
+// Used to avoid ISR nesting of the "Stepper Driver Interrupt". Should never occur though.
+static volatile uint8_t busy;
+
+// Pointers for the step segment being prepped from the planner buffer. Accessed only by the
+// main program. Pointers may be planning segments or planner blocks ahead of what being executed.
+static plan_block_t *pl_block;     // Pointer to the planner block being prepped
+static st_block_t *st_prep_block;  // Pointer to the stepper block data being prepped
+
+// Segment preparation data struct. Contains all the necessary information to compute new segments
+// based on the current executing planner block.
+typedef struct {
+  uint8_t st_block_index;  // Index of stepper common data block being prepped
+  uint8_t recalculate_flag;
+
+  float dt_remainder;
+  float steps_remaining;
+  float step_per_mm;
+  float req_mm_increment;
+
+  #ifdef PARKING_ENABLE
+    uint8_t last_st_block_index;
+    float last_steps_remaining;
+    float last_step_per_mm;
+    float last_dt_remainder;
+  #endif
+
+  uint8_t ramp_type;      // Current segment ramp state
+  float mm_complete;      // End of velocity profile from end of current planner block in (mm).
+                          // NOTE: This value must coincide with a step(no mantissa) when converted.
+  float current_speed;    // Current speed at the end of the segment buffer (mm/min)
+  float maximum_speed;    // Maximum speed of executing block. Not always nominal speed. (mm/min)
+  float exit_speed;       // Exit speed of executing block (mm/min)
+  float accelerate_until; // Acceleration ramp end measured from end of block (mm)
+  float decelerate_after; // Deceleration ramp start measured from end of block (mm)
+
+  #ifdef VARIABLE_SPINDLE
+    float inv_rate;    // Used by PWM laser mode to speed up segment calculations.
+    uint8_t current_spindle_pwm;
+  #endif
+} st_prep_t;
+static st_prep_t prep;
+
+
+/*    BLOCK VELOCITY PROFILE DEFINITION
+          __________________________
+         /|                        |\     _________________         ^
+        / |                        | \   /|               |\        |
+       /  |                        |  \ / |               | \       s
+      /   |                        |   |  |               |  \      p
+     /    |                        |   |  |               |   \     e
+    +-----+------------------------+---+--+---------------+----+    e
+    |               BLOCK 1            ^      BLOCK 2          |    d
+                                       |
+                  time ----->      EXAMPLE: Block 2 entry speed is at max junction velocity
+
+  The planner block buffer is planned assuming constant acceleration velocity profiles and are
+  continuously joined at block junctions as shown above. However, the planner only actively computes
+  the block entry speeds for an optimal velocity plan, but does not compute the block internal
+  velocity profiles. These velocity profiles are computed ad-hoc as they are executed by the
+  stepper algorithm and consists of only 7 possible types of profiles: cruise-only, cruise-
+  deceleration, acceleration-cruise, acceleration-only, deceleration-only, full-trapezoid, and
+  triangle(no cruise).
+
+                                        maximum_speed (< nominal_speed) ->  +
+                    +--------+ <- maximum_speed (= nominal_speed)          /|\
+                   /          \                                           / | \
+ current_speed -> +            \                                         /  |  + <- exit_speed
+                  |             + <- exit_speed                         /   |  |
+                  +-------------+                     current_speed -> +----+--+
+                   time -->  ^  ^                                           ^  ^
+                             |  |                                           |  |
+                decelerate_after(in mm)                             decelerate_after(in mm)
+                    ^           ^                                           ^  ^
+                    |           |                                           |  |
+                accelerate_until(in mm)                             accelerate_until(in mm)
+
+  The step segment buffer computes the executing block velocity profile and tracks the critical
+  parameters for the stepper algorithm to accurately trace the profile. These critical parameters
+  are shown and defined in the above illustration.
+*/
+
+
+// Stepper state initialization. Cycle should only start if the st.cycle_start flag is
+// enabled. Startup init and limits call this function but shouldn't start the cycle.
+void st_wake_up()
+{
+  // Enable stepper drivers.
+  if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) 
+  { 
+	  SetStepperDisableBit();
+  }
+  else 
+  { 
+	  ResetStepperDisableBit(); 
+  }
+
+  // Initialize stepper output bits to ensure first ISR call does not step.
+  st.step_outbits = step_port_invert_mask;
+
+  // Initialize step pulse timing from settings. Here to ensure updating after re-writing.
+  #ifdef STEP_PULSE_DELAY
+    // Set total step pulse time after direction pin set. Ad hoc computation from oscilloscope.
+    st.step_pulse_time = -(((settings.pulse_microseconds+STEP_PULSE_DELAY-2)*TICKS_PER_MICROSECOND) >> 3);
+    // Set delay between direction pin write and step command.
+    OCR0A = -(((settings.pulse_microseconds)*TICKS_PER_MICROSECOND) >> 3);
+  #else // Normal operation
+    // Set step pulse time. Ad hoc computation from oscilloscope. Uses two's complement.
+#ifdef AVRTARGET
+  st.step_pulse_time = -(((settings.pulse_microseconds - 2)*TICKS_PER_MICROSECOND) >> 3);
+#elif defined (WIN32)
+  st.step_pulse_time = (settings.pulse_microseconds)*TICKS_PER_MICROSECOND;
+#elif defined(STM32F103C8)
+  st.step_pulse_time = (settings.pulse_microseconds)*TICKS_PER_MICROSECOND;
+#endif
+  #endif
+
+  // Enable Stepper Driver Interrupt
+#ifdef AVRTARGET
+  TIMSK1 |= (1<<OCIE1A);
+#endif
+#ifdef WIN32
+  nTimer1Out = 1;
+#endif
+#if defined (STM32F103C8)
+  TIM3->ARR = st.step_pulse_time - 1;
+  TIM3->EGR = TIM_PSCReloadMode_Immediate;
+  TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
+
+  TIM2->ARR = st.exec_segment->cycles_per_tick - 1;
+  /* Set the Autoreload value */
+#ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING        
+  TIM2->PSC = st.exec_segment->prescaler;
+#endif
+  TIM2->EGR = TIM_PSCReloadMode_Immediate;
+  NVIC_EnableIRQ(TIM2_IRQn);
+#endif
+}
+
+
+// Stepper shutdown
+void st_go_idle()
+{
+  // Disable Stepper Driver Interrupt. Allow Stepper Port Reset Interrupt to finish, if active.
+#ifdef AVRTARGET
+  TIMSK1 &= ~(1<<OCIE1A); // Disable Timer1 interrupt
+  TCCR1B = (TCCR1B & ~((1<<CS12) | (1<<CS11))) | (1<<CS10); // Reset clock to no prescaling.
+#endif
+#ifdef WIN32
+  nTimer1Out = 0;
+#endif
+#ifdef STM32F103C8
+  NVIC_DisableIRQ(TIM2_IRQn);
+#endif
+
+  busy = false;
+
+  // Set stepper driver idle state, disabled or enabled, depending on settings and circumstances.
+  bool pin_state = false; // Keep enabled.
+  if (((settings.stepper_idle_lock_time != 0xff) || sys_rt_exec_alarm || sys.state == STATE_SLEEP) && sys.state != STATE_HOMING) {
+    // Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
+    // stop and not drift from residual inertial forces at the end of the last movement.
+    delay_ms(settings.stepper_idle_lock_time);
+    pin_state = true; // Override. Disable steppers.
+  }
+  if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) { pin_state = !pin_state; } // Apply pin invert.
+  if (pin_state) 
+  { 
+	  SetStepperDisableBit();
+  }
+  else 
+  { 
+	  ResetStepperDisableBit();
+  }
+}
+
+
+/* "The Stepper Driver Interrupt" - This timer interrupt is the workhorse of Grbl. Grbl employs
+   the venerable Bresenham line algorithm to manage and exactly synchronize multi-axis moves.
+   Unlike the popular DDA algorithm, the Bresenham algorithm is not susceptible to numerical
+   round-off errors and only requires fast integer counters, meaning low computational overhead
+   and maximizing the Arduino's capabilities. However, the downside of the Bresenham algorithm
+   is, for certain multi-axis motions, the non-dominant axes may suffer from un-smooth step
+   pulse trains, or aliasing, which can lead to strange audible noises or shaking. This is
+   particularly noticeable or may cause motion issues at low step frequencies (0-5kHz), but
+   is usually not a physical problem at higher frequencies, although audible.
+     To improve Bresenham multi-axis performance, Grbl uses what we call an Adaptive Multi-Axis
+   Step Smoothing (AMASS) algorithm, which does what the name implies. At lower step frequencies,
+   AMASS artificially increases the Bresenham resolution without effecting the algorithm's
+   innate exactness. AMASS adapts its resolution levels automatically depending on the step
+   frequency to be executed, meaning that for even lower step frequencies the step smoothing
+   level increases. Algorithmically, AMASS is acheived by a simple bit-shifting of the Bresenham
+   step count for each AMASS level. For example, for a Level 1 step smoothing, we bit shift
+   the Bresenham step event count, effectively multiplying it by 2, while the axis step counts
+   remain the same, and then double the stepper ISR frequency. In effect, we are allowing the
+   non-dominant Bresenham axes step in the intermediate ISR tick, while the dominant axis is
+   stepping every two ISR ticks, rather than every ISR tick in the traditional sense. At AMASS
+   Level 2, we simply bit-shift again, so the non-dominant Bresenham axes can step within any
+   of the four ISR ticks, the dominant axis steps every four ISR ticks, and quadruple the
+   stepper ISR frequency. And so on. This, in effect, virtually eliminates multi-axis aliasing
+   issues with the Bresenham algorithm and does not significantly alter Grbl's performance, but
+   in fact, more efficiently utilizes unused CPU cycles overall throughout all configurations.
+     AMASS retains the Bresenham algorithm exactness by requiring that it always executes a full
+   Bresenham step, regardless of AMASS Level. Meaning that for an AMASS Level 2, all four
+   intermediate steps must be completed such that baseline Bresenham (Level 0) count is always
+   retained. Similarly, AMASS Level 3 means all eight intermediate steps must be executed.
+   Although the AMASS Levels are in reality arbitrary, where the baseline Bresenham counts can
+   be multiplied by any integer value, multiplication by powers of two are simply used to ease
+   CPU overhead with bitshift integer operations.
+     This interrupt is simple and dumb by design. All the computational heavy-lifting, as in
+   determining accelerations, is performed elsewhere. This interrupt pops pre-computed segments,
+   defined as constant velocity over n number of steps, from the step segment buffer and then
+   executes them by pulsing the stepper pins appropriately via the Bresenham algorithm. This
+   ISR is supported by The Stepper Port Reset Interrupt which it uses to reset the stepper port
+   after each pulse. The bresenham line tracer algorithm controls all stepper outputs
+   simultaneously with these two interrupts.
+
+   NOTE: This interrupt must be as efficient as possible and complete before the next ISR tick,
+   which for Grbl must be less than 33.3usec (@30kHz ISR rate). Oscilloscope measured time in
+   ISR is 5usec typical and 25usec maximum, well below requirement.
+   NOTE: This ISR expects at least one step to be executed per segment.
+*/
+// TODO: Replace direct updating of the int32 position counters in the ISR somehow. Perhaps use smaller
+// int8 variables and update position counters only when a segment completes. This can get complicated
+// with probing and homing cycles that require true real-time positions.
+#ifdef STM32F103C8
+void TIM2_IRQHandler(void)
+#endif
+#ifdef AVRTARGET
+ISR(TIMER1_COMPA_vect)
+#endif
+#ifdef WIN32
+void Timer1Proc()
+#endif
+{
+#ifdef STM32F103C8
+	if ((TIM2->SR & 0x0001) != 0)                  // check interrupt source
+	{
+		TIM2->SR &= ~(1 << 0);                          // clear UIF flag
+		TIM2->CNT = 0;
+	}
+	else
+	{
+		return;
+	}
+#endif
+
+  if (busy) { return; } // The busy-flag is used to avoid reentering this interrupt
+#ifdef AVRTARGET
+  // Set the direction pins a couple of nanoseconds before we step the steppers
+  DIRECTION_PORT = (DIRECTION_PORT & ~DIRECTION_MASK) | (st.dir_outbits & DIRECTION_MASK);
+#endif
+#ifdef STM32F103C8
+  GPIO_Write(DIRECTION_PORT, (GPIO_ReadOutputData(DIRECTION_PORT) & ~DIRECTION_MASK) | (st.dir_outbits & DIRECTION_MASK));
+  TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
+#endif
+
+  // Then pulse the stepping pins
+  #ifdef STEP_PULSE_DELAY
+    st.step_bits = (STEP_PORT & ~STEP_MASK) | st.step_outbits; // Store out_bits to prevent overwriting.
+  #else  // Normal operation
+#ifdef AVRTARGET
+    STEP_PORT = (STEP_PORT & ~STEP_MASK) | st.step_outbits;
+#endif
+#ifdef STM32F103C8
+	GPIO_Write(STEP_PORT, (GPIO_ReadOutputData(STEP_PORT) & ~STEP_MASK) | st.step_outbits);
+#endif
+  #endif
+
+  // Enable step pulse reset timer so that The Stepper Port Reset Interrupt can reset the signal after
+  // exactly settings.pulse_microseconds microseconds, independent of the main Timer1 prescaler.
+#ifdef AVRTARGET
+  TCNT0 = st.step_pulse_time; // Reload Timer0 counter
+  TCCR0B = (1<<CS01); // Begin Timer0. Full speed, 1/8 prescaler
+#endif
+#ifdef WIN32
+  nTimer0Out = st.step_pulse_time;
+#endif
+#ifdef STM32F103C8
+  NVIC_EnableIRQ(TIM3_IRQn);
+#endif
+
+  busy = true;
+#ifdef AVRTARGET
+  sei(); // Re-enable interrupts to allow Stepper Port Reset Interrupt to fire on-time.
+         // NOTE: The remaining code in this ISR will finish before returning to main program.
+#endif
+
+  // If there is no step segment, attempt to pop one from the stepper buffer
+  if (st.exec_segment == NULL) {
+    // Anything in the buffer? If so, load and initialize next step segment.
+    if (segment_buffer_head != segment_buffer_tail) {
+      // Initialize new step segment and load number of steps to execute
+      st.exec_segment = &segment_buffer[segment_buffer_tail];
+
+      #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+        // With AMASS is disabled, set timer prescaler for segments with slow step frequencies (< 250Hz).
+#ifdef AVRTARGET
+        TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (st.exec_segment->prescaler<<CS10);
+#endif
+      #endif
+
+      // Initialize step segment timing per step and load number of steps to execute.
+#ifdef AVRTARGET
+      OCR1A = st.exec_segment->cycles_per_tick;
+#endif
+#ifdef WIN32
+#ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+	  nTimer1Out = st.exec_segment->cycles_per_tick * (st.exec_segment->prescaler + 1);
+#else
+	  nTimer1Out = st.exec_segment->cycles_per_tick;
+#endif
+#endif
+#ifdef STM32F103C8
+	  TIM2->ARR = st.exec_segment->cycles_per_tick - 1;
+	  /* Set the Autoreload value */
+#ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING        
+	  TIM2->PSC = st.exec_segment->prescaler;
+#endif
+#endif
+      st.step_count = st.exec_segment->n_step; // NOTE: Can sometimes be zero when moving slow.
+      // If the new segment starts a new planner block, initialize stepper variables and counters.
+      // NOTE: When the segment data index changes, this indicates a new planner block.
+      if ( st.exec_block_index != st.exec_segment->st_block_index ) {
+        st.exec_block_index = st.exec_segment->st_block_index;
+        st.exec_block = &st_block_buffer[st.exec_block_index];
+
+        // Initialize Bresenham line and distance counters
+        st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1);
+      }
+      st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask;
+
+      #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+        // With AMASS enabled, adjust Bresenham axis increment counters according to AMASS level.
+        st.steps[X_AXIS] = st.exec_block->steps[X_AXIS] >> st.exec_segment->amass_level;
+        st.steps[Y_AXIS] = st.exec_block->steps[Y_AXIS] >> st.exec_segment->amass_level;
+        st.steps[Z_AXIS] = st.exec_block->steps[Z_AXIS] >> st.exec_segment->amass_level;
+      #endif
+
+      #ifdef VARIABLE_SPINDLE
+        // Set real-time spindle output as segment is loaded, just prior to the first step.
+        spindle_set_speed(st.exec_segment->spindle_pwm);
+      #endif
+
+    } else {
+      // Segment buffer empty. Shutdown.
+      st_go_idle();
+      // Ensure pwm is set properly upon completion of rate-controlled motion.
+      #ifdef VARIABLE_SPINDLE
+      if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); }
+      #endif
+      system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end
+      return; // Nothing to do but exit.
+    }
+  }
+
+
+  // Check probing state.
+  if (sys_probe_state == PROBE_ACTIVE) { probe_state_monitor(); }
+
+  // Reset step out bits.
+  st.step_outbits = 0;
+
+  // Execute step displacement profile by Bresenham line algorithm
+  #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+    st.counter_x += st.steps[X_AXIS];
+  #else
+    st.counter_x += st.exec_block->steps[X_AXIS];
+  #endif
+  if (st.counter_x > st.exec_block->step_event_count) {
+    st.step_outbits |= (1<<X_STEP_BIT);
+    st.counter_x -= st.exec_block->step_event_count;
+    if (st.exec_block->direction_bits & (1<<X_DIRECTION_BIT)) { sys_position[X_AXIS]--; }
+    else { sys_position[X_AXIS]++; }
+  }
+  #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+    st.counter_y += st.steps[Y_AXIS];
+  #else
+    st.counter_y += st.exec_block->steps[Y_AXIS];
+  #endif
+  if (st.counter_y > st.exec_block->step_event_count) {
+    st.step_outbits |= (1<<Y_STEP_BIT);
+    st.counter_y -= st.exec_block->step_event_count;
+    if (st.exec_block->direction_bits & (1<<Y_DIRECTION_BIT)) { sys_position[Y_AXIS]--; }
+    else { sys_position[Y_AXIS]++; }
+  }
+  #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+    st.counter_z += st.steps[Z_AXIS];
+  #else
+    st.counter_z += st.exec_block->steps[Z_AXIS];
+  #endif
+  if (st.counter_z > st.exec_block->step_event_count) {
+    st.step_outbits |= (1<<Z_STEP_BIT);
+    st.counter_z -= st.exec_block->step_event_count;
+    if (st.exec_block->direction_bits & (1<<Z_DIRECTION_BIT)) { sys_position[Z_AXIS]--; }
+    else { sys_position[Z_AXIS]++; }
+  }
+
+  // During a homing cycle, lock out and prevent desired axes from moving.
+  if (sys.state == STATE_HOMING) { st.step_outbits &= sys.homing_axis_lock; }
+
+  st.step_count--; // Decrement step events count
+  if (st.step_count == 0) {
+    // Segment is complete. Discard current segment and advance segment indexing.
+    st.exec_segment = NULL;
+#ifndef WIN32
+	uint8_t segment_tail_next = segment_buffer_tail + 1;
+	if (segment_tail_next == SEGMENT_BUFFER_SIZE)
+		segment_tail_next = 0;
+	segment_buffer_tail = segment_tail_next;
+#else
+    if ( ++segment_buffer_tail == SEGMENT_BUFFER_SIZE) 
+	{ 
+		segment_buffer_tail = 0; 
+	}
+#endif
+  }
+
+  st.step_outbits ^= step_port_invert_mask;  // Apply step port invert mask
+  busy = false;
+}
+
+
+/* The Stepper Port Reset Interrupt: Timer0 OVF interrupt handles the falling edge of the step
+   pulse. This should always trigger before the next Timer1 COMPA interrupt and independently
+   finish, if Timer1 is disabled after completing a move.
+   NOTE: Interrupt collisions between the serial and stepper interrupts can cause delays by
+   a few microseconds, if they execute right before one another. Not a big deal, but can
+   cause issues at high step rates if another high frequency asynchronous interrupt is
+   added to Grbl.
+*/
+// This interrupt is enabled by ISR_TIMER1_COMPAREA when it sets the motor port bits to execute
+// a step. This ISR resets the motor port after a short period (settings.pulse_microseconds)
+// completing one step cycle.
+#ifdef STM32F103C8
+void TIM3_IRQHandler(void)
+#endif
+#ifdef AVRTARGET
+ISR(TIMER0_OVF_vect)
+#endif
+#ifdef WIN32
+void Timer0Proc()
+#endif
+{
+#ifdef STM32F103C8
+	if ((TIM3->SR & 0x0001) != 0)                  // check interrupt source
+	{
+		TIM3->SR &= ~(1<<0);                          // clear UIF flag
+		TIM3->CNT = 0;
+		NVIC_DisableIRQ(TIM3_IRQn);
+		GPIO_Write(STEP_PORT, (GPIO_ReadOutputData(STEP_PORT) & ~STEP_MASK) | (step_port_invert_mask & STEP_MASK));
+	}
+#endif
+#ifdef AVRTARGET
+  // Reset stepping pins (leave the direction pins)
+  STEP_PORT = (STEP_PORT & ~STEP_MASK) | (step_port_invert_mask & STEP_MASK);
+  TCCR0B = 0; // Disable Timer0 to prevent re-entering this interrupt when it's not needed.
+#endif
+#ifdef WIN32
+  nTimer0Out = 0;
+#endif
+}
+#ifdef STEP_PULSE_DELAY
+  // This interrupt is used only when STEP_PULSE_DELAY is enabled. Here, the step pulse is
+  // initiated after the STEP_PULSE_DELAY time period has elapsed. The ISR TIMER2_OVF interrupt
+  // will then trigger after the appropriate settings.pulse_microseconds, as in normal operation.
+  // The new timing between direction, step pulse, and step complete events are setup in the
+  // st_wake_up() routine.
+  ISR(TIMER0_COMPA_vect)
+  {
+    STEP_PORT = st.step_bits; // Begin step pulse.
+  }
+#endif
+
+
+// Generates the step and direction port invert masks used in the Stepper Interrupt Driver.
+void st_generate_step_dir_invert_masks()
+{
+  uint8_t idx;
+  step_port_invert_mask = 0;
+  dir_port_invert_mask = 0;
+  for (idx=0; idx<N_AXIS; idx++) {
+    if (bit_istrue(settings.step_invert_mask,bit(idx))) { step_port_invert_mask |= step_pin_mask[idx]; }
+    if (bit_istrue(settings.dir_invert_mask,bit(idx))) { dir_port_invert_mask |= direction_pin_mask[idx]; }
+  }
+}
+
+
+// Reset and clear stepper subsystem variables
+void st_reset()
+{
+  // Initialize stepper driver idle state.
+  st_go_idle();
+
+  // Initialize stepper algorithm variables.
+  memset(&prep, 0, sizeof(st_prep_t));
+  memset(&st, 0, sizeof(stepper_t));
+  st.exec_segment = NULL;
+  pl_block = NULL;  // Planner block pointer used by segment buffer
+  segment_buffer_tail = 0;
+  segment_buffer_head = 0; // empty = tail
+  segment_next_head = 1;
+  busy = false;
+
+  st_generate_step_dir_invert_masks();
+  st.dir_outbits = dir_port_invert_mask; // Initialize direction bits to default.
+
+  // Initialize step and direction port pins.
+#ifdef AVRTARGET
+  STEP_PORT = (STEP_PORT & ~STEP_MASK) | step_port_invert_mask;
+  DIRECTION_PORT = (DIRECTION_PORT & ~DIRECTION_MASK) | dir_port_invert_mask;
+#endif
+#ifdef STM32F103C8
+  GPIO_Write(STEP_PORT, (GPIO_ReadOutputData(STEP_PORT) & ~STEP_MASK) | (step_port_invert_mask & STEP_MASK));
+  GPIO_Write(DIRECTION_PORT, (GPIO_ReadOutputData(DIRECTION_PORT) & ~DIRECTION_MASK) | (dir_port_invert_mask & DIRECTION_MASK));
+#endif
+}
+
+#ifdef WIN32
+void Timer1Thread(void *pVoid)
+{
+	LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
+
+	for (;;)
+	{
+		while (nTimer1Out == 0)
+			Sleep(0);
+		QueryPerformanceCounter(&StartingTime);
+		do
+		{
+			QueryPerformanceCounter(&EndingTime);
+			ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
+		} while (ElapsedMicroseconds.QuadPart < nTimer1Out);
+		Timer1Proc();
+	}
+}
+
+void Timer0Thread(void *pVoid)
+{
+	LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
+
+	for (;;)
+	{
+		while (nTimer0Out == 0)
+			Sleep(0);
+		QueryPerformanceCounter(&StartingTime);
+		do
+		{
+			QueryPerformanceCounter(&EndingTime);
+			ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
+		} while (ElapsedMicroseconds.QuadPart < nTimer0Out);
+		Timer0Proc();
+	}
+}
+
+#endif
+
+// Initialize and start the stepper motor subsystem
+void stepper_init()
+{
+  // Configure step and direction interface pins
+#ifdef STM32F103C8
+	GPIO_InitTypeDef GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(RCC_STEPPERS_DISABLE_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_InitStructure.GPIO_Pin = STEPPERS_DISABLE_MASK;
+	GPIO_Init(STEPPERS_DISABLE_PORT, &GPIO_InitStructure);
+
+	RCC_APB2PeriphClockCmd(RCC_STEP_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = STEP_MASK;
+	GPIO_Init(STEP_PORT, &GPIO_InitStructure);
+
+	RCC_APB2PeriphClockCmd(RCC_DIRECTION_PORT, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = DIRECTION_MASK;
+	GPIO_Init(DIRECTION_PORT, &GPIO_InitStructure);
+
+	RCC->APB1ENR |= RCC_APB1Periph_TIM2;
+	TIM_Configuration(TIM2, 1, 1, 1);
+	RCC->APB1ENR |= RCC_APB1Periph_TIM3;
+	TIM_Configuration(TIM3, 1, 1, 1);
+	NVIC_DisableIRQ(TIM3_IRQn);
+	NVIC_DisableIRQ(TIM2_IRQn);
+#endif
+#ifdef AVRTARGET
+  STEP_DDR |= STEP_MASK;
+  STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;
+  DIRECTION_DDR |= DIRECTION_MASK;
+
+  // Configure Timer 1: Stepper Driver Interrupt
+  TCCR1B &= ~(1<<WGM13); // waveform generation = 0100 = CTC
+  TCCR1B |=  (1<<WGM12);
+  TCCR1A &= ~((1<<WGM11) | (1<<WGM10));
+  TCCR1A &= ~((1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0)); // Disconnect OC1 output
+  // TCCR1B = (TCCR1B & ~((1<<CS12) | (1<<CS11))) | (1<<CS10); // Set in st_go_idle().
+  // TIMSK1 &= ~(1<<OCIE1A);  // Set in st_go_idle().
+
+  // Configure Timer 0: Stepper Port Reset Interrupt
+  TIMSK0 &= ~((1<<OCIE0B) | (1<<OCIE0A) | (1<<TOIE0)); // Disconnect OC0 outputs and OVF interrupt.
+  TCCR0A = 0; // Normal operation
+  TCCR0B = 0; // Disable Timer0 until needed
+  TIMSK0 |= (1<<TOIE0); // Enable Timer0 overflow interrupt
+  #ifdef STEP_PULSE_DELAY
+    TIMSK0 |= (1<<OCIE0A); // Enable Timer0 Compare Match A interrupt
+  #endif
+#endif
+#ifdef WIN32
+	QueryPerformanceFrequency(&Win32Frequency);
+
+	_beginthread(Timer1Thread, 0, NULL);
+	_beginthread(Timer0Thread, 0, NULL);
+#endif
+}
+
+
+// Called by planner_recalculate() when the executing block is updated by the new plan.
+void st_update_plan_block_parameters()
+{
+  if (pl_block != NULL) { // Ignore if at start of a new block.
+    prep.recalculate_flag |= PREP_FLAG_RECALCULATE;
+    pl_block->entry_speed_sqr = prep.current_speed*prep.current_speed; // Update entry speed.
+    pl_block = NULL; // Flag st_prep_segment() to load and check active velocity profile.
+  }
+}
+
+
+// Increments the step segment buffer block data ring buffer.
+static uint8_t st_next_block_index(uint8_t block_index)
+{
+  block_index++;
+  if ( block_index == (SEGMENT_BUFFER_SIZE-1) ) { return(0); }
+  return(block_index);
+}
+
+
+#ifdef PARKING_ENABLE
+  // Changes the run state of the step segment buffer to execute the special parking motion.
+  void st_parking_setup_buffer()
+  {
+    // Store step execution data of partially completed block, if necessary.
+    if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) {
+      prep.last_st_block_index = prep.st_block_index;
+      prep.last_steps_remaining = prep.steps_remaining;
+      prep.last_dt_remainder = prep.dt_remainder;
+      prep.last_step_per_mm = prep.step_per_mm;
+    }
+    // Set flags to execute a parking motion
+    prep.recalculate_flag |= PREP_FLAG_PARKING;
+    prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE);
+    pl_block = NULL; // Always reset parking motion to reload new block.
+  }
+
+
+  // Restores the step segment buffer to the normal run state after a parking motion.
+  void st_parking_restore_buffer()
+  {
+    // Restore step execution data and flags of partially completed block, if necessary.
+    if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) {
+      st_prep_block = &st_block_buffer[prep.last_st_block_index];
+      prep.st_block_index = prep.last_st_block_index;
+      prep.steps_remaining = prep.last_steps_remaining;
+      prep.dt_remainder = prep.last_dt_remainder;
+      prep.step_per_mm = prep.last_step_per_mm;
+      prep.recalculate_flag = (PREP_FLAG_HOLD_PARTIAL_BLOCK | PREP_FLAG_RECALCULATE);
+      prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; // Recompute this value.
+    } else {
+      prep.recalculate_flag = false;
+    }
+    pl_block = NULL; // Set to reload next block.
+  }
+#endif
+
+
+/* Prepares step segment buffer. Continuously called from main program.
+
+   The segment buffer is an intermediary buffer interface between the execution of steps
+   by the stepper algorithm and the velocity profiles generated by the planner. The stepper
+   algorithm only executes steps within the segment buffer and is filled by the main program
+   when steps are "checked-out" from the first block in the planner buffer. This keeps the
+   step execution and planning optimization processes atomic and protected from each other.
+   The number of steps "checked-out" from the planner buffer and the number of segments in
+   the segment buffer is sized and computed such that no operation in the main program takes
+   longer than the time it takes the stepper algorithm to empty it before refilling it.
+   Currently, the segment buffer conservatively holds roughly up to 40-50 msec of steps.
+   NOTE: Computation units are in steps, millimeters, and minutes.
+*/
+void st_prep_buffer()
+{
+  // Block step prep buffer, while in a suspend state and there is no suspend motion to execute.
+  if (bit_istrue(sys.step_control,STEP_CONTROL_END_MOTION)) { return; }
+
+  while (segment_buffer_tail != segment_next_head) { // Check if we need to fill the buffer.
+
+    // Determine if we need to load a new planner block or if the block needs to be recomputed.
+    if (pl_block == NULL) {
+
+      // Query planner for a queued block
+      if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { pl_block = plan_get_system_motion_block(); }
+      else { pl_block = plan_get_current_block(); }
+      if (pl_block == NULL) { return; } // No planner blocks. Exit.
+
+      // Check if we need to only recompute the velocity profile or load a new block.
+      if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) {
+
+        #ifdef PARKING_ENABLE
+          if (prep.recalculate_flag & PREP_FLAG_PARKING) { prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); }
+          else { prep.recalculate_flag = false; }
+        #else
+          prep.recalculate_flag = false;
+        #endif
+
+      } else {
+
+        // Load the Bresenham stepping data for the block.
+        prep.st_block_index = st_next_block_index(prep.st_block_index);
+
+        // Prepare and copy Bresenham algorithm segment data from the new planner block, so that
+        // when the segment buffer completes the planner block, it may be discarded when the
+        // segment buffer finishes the prepped block, but the stepper ISR is still executing it.
+        st_prep_block = &st_block_buffer[prep.st_block_index];
+        st_prep_block->direction_bits = pl_block->direction_bits;
+        uint8_t idx;
+        #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+          for (idx=0; idx<N_AXIS; idx++) { st_prep_block->steps[idx] = (pl_block->steps[idx] << 1); }
+          st_prep_block->step_event_count = (pl_block->step_event_count << 1);
+        #else
+          // With AMASS enabled, simply bit-shift multiply all Bresenham data by the max AMASS
+          // level, such that we never divide beyond the original data anywhere in the algorithm.
+          // If the original data is divided, we can lose a step from integer roundoff.
+          for (idx=0; idx<N_AXIS; idx++) { st_prep_block->steps[idx] = pl_block->steps[idx] << MAX_AMASS_LEVEL; }
+          st_prep_block->step_event_count = pl_block->step_event_count << MAX_AMASS_LEVEL;
+        #endif
+
+        // Initialize segment buffer data for generating the segments.
+        prep.steps_remaining = (float)pl_block->step_event_count;
+        prep.step_per_mm = prep.steps_remaining/pl_block->millimeters;
+        prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm;
+        prep.dt_remainder = 0.0f; // Reset for new segment block
+
+        if ((sys.step_control & STEP_CONTROL_EXECUTE_HOLD) || (prep.recalculate_flag & PREP_FLAG_DECEL_OVERRIDE)) {
+          // New block loaded mid-hold. Override planner block entry speed to enforce deceleration.
+          prep.current_speed = prep.exit_speed;
+          pl_block->entry_speed_sqr = prep.exit_speed*prep.exit_speed;
+          prep.recalculate_flag &= ~(PREP_FLAG_DECEL_OVERRIDE);
+        } else {
+          prep.current_speed = sqrtf(pl_block->entry_speed_sqr);
+        }
+#ifdef VARIABLE_SPINDLE
+        // Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the
+        // spindle off. 
+        st_prep_block->is_pwm_rate_adjusted = false;
+        if (settings.flags & BITFLAG_LASER_MODE) {
+          if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) {
+            // Pre-compute inverse programmed rate to speed up PWM updating per step segment.
+            prep.inv_rate = 1.0 / pl_block->programmed_rate;
+            st_prep_block->is_pwm_rate_adjusted = true;
+          }
+        }
+#endif
+      }
+
+			/* ---------------------------------------------------------------------------------
+			 Compute the velocity profile of a new planner block based on its entry and exit
+			 speeds, or recompute the profile of a partially-completed planner block if the
+			 planner has updated it. For a commanded forced-deceleration, such as from a feed
+			 hold, override the planner velocities and decelerate to the target exit speed.
+			*/
+			prep.mm_complete = 0.0f; // Default velocity profile complete at 0.0mm from end of block.
+			float inv_2_accel = 0.5f/pl_block->acceleration;
+			if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { // [Forced Deceleration to Zero Velocity]
+				// Compute velocity profile parameters for a feed hold in-progress. This profile overrides
+				// the planner block profile, enforcing a deceleration to zero speed.
+				prep.ramp_type = RAMP_DECEL;
+				// Compute decelerate distance relative to end of block.
+				float decel_dist = pl_block->millimeters - inv_2_accel*pl_block->entry_speed_sqr;
+				if (decel_dist < 0.0f) {
+					// Deceleration through entire planner block. End of feed hold is not in this block.
+					prep.exit_speed = sqrtf(pl_block->entry_speed_sqr-2*pl_block->acceleration*pl_block->millimeters);
+				} else {
+					prep.mm_complete = decel_dist; // End of feed hold.
+					prep.exit_speed = 0.0f;
+				}
+			} else { // [Normal Operation]
+				// Compute or recompute velocity profile parameters of the prepped planner block.
+				prep.ramp_type = RAMP_ACCEL; // Initialize as acceleration ramp.
+				prep.accelerate_until = pl_block->millimeters;
+
+				float exit_speed_sqr;
+				float nominal_speed;
+        if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) {
+          prep.exit_speed = exit_speed_sqr = 0.0f; // Enforce stop at end of system motion.
+        } else {
+          exit_speed_sqr = plan_get_exec_block_exit_speed_sqr();
+          prep.exit_speed = sqrtf(exit_speed_sqr);
+        }
+
+        nominal_speed = plan_compute_profile_nominal_speed(pl_block);
+				float nominal_speed_sqr = nominal_speed*nominal_speed;
+				float intersect_distance =
+								0.5f*(pl_block->millimeters+inv_2_accel*(pl_block->entry_speed_sqr-exit_speed_sqr));
+
+        if (pl_block->entry_speed_sqr > nominal_speed_sqr) { // Only occurs during override reductions.
+          prep.accelerate_until = pl_block->millimeters - inv_2_accel*(pl_block->entry_speed_sqr-nominal_speed_sqr);
+          if (prep.accelerate_until <= 0.0f) { // Deceleration-only.
+            prep.ramp_type = RAMP_DECEL;
+            // prep.decelerate_after = pl_block->millimeters;
+            // prep.maximum_speed = prep.current_speed;
+
+            // Compute override block exit speed since it doesn't match the planner exit speed.
+            prep.exit_speed = sqrtf(pl_block->entry_speed_sqr - 2*pl_block->acceleration*pl_block->millimeters);
+            prep.recalculate_flag |= PREP_FLAG_DECEL_OVERRIDE; // Flag to load next block as deceleration override.
+
+            // TODO: Determine correct handling of parameters in deceleration-only.
+            // Can be tricky since entry speed will be current speed, as in feed holds.
+            // Also, look into near-zero speed handling issues with this.
+
+          } else {
+            // Decelerate to cruise or cruise-decelerate types. Guaranteed to intersect updated plan.
+            prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr);
+            prep.maximum_speed = nominal_speed;
+            prep.ramp_type = RAMP_DECEL_OVERRIDE;
+          }
+				} else if (intersect_distance > 0.0f) {
+					if (intersect_distance < pl_block->millimeters) { // Either trapezoid or triangle types
+						// NOTE: For acceleration-cruise and cruise-only types, following calculation will be 0.0.
+						prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr);
+						if (prep.decelerate_after < intersect_distance) { // Trapezoid type
+							prep.maximum_speed = nominal_speed;
+							if (pl_block->entry_speed_sqr == nominal_speed_sqr) {
+								// Cruise-deceleration or cruise-only type.
+								prep.ramp_type = RAMP_CRUISE;
+							} else {
+								// Full-trapezoid or acceleration-cruise types
+								prep.accelerate_until -= inv_2_accel*(nominal_speed_sqr-pl_block->entry_speed_sqr);
+							}
+						} else { // Triangle type
+							prep.accelerate_until = intersect_distance;
+							prep.decelerate_after = intersect_distance;
+							prep.maximum_speed = sqrtf(2.0f*pl_block->acceleration*intersect_distance+exit_speed_sqr);
+						}
+					} else { // Deceleration-only type
+            prep.ramp_type = RAMP_DECEL;
+            // prep.decelerate_after = pl_block->millimeters;
+            // prep.maximum_speed = prep.current_speed;
+					}
+				} else { // Acceleration-only type
+					prep.accelerate_until = 0.0f;
+					// prep.decelerate_after = 0.0f;
+					prep.maximum_speed = prep.exit_speed;
+				}
+			}
+      
+      #ifdef VARIABLE_SPINDLE
+        bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block.
+      #endif
+    }
+    
+    // Initialize new segment
+    segment_t *prep_segment = &segment_buffer[segment_buffer_head];
+
+    // Set new segment to point to the current segment data block.
+    prep_segment->st_block_index = prep.st_block_index;
+
+    /*------------------------------------------------------------------------------------
+        Compute the average velocity of this new segment by determining the total distance
+      traveled over the segment time DT_SEGMENT. The following code first attempts to create
+      a full segment based on the current ramp conditions. If the segment time is incomplete
+      when terminating at a ramp state change, the code will continue to loop through the
+      progressing ramp states to fill the remaining segment execution time. However, if
+      an incomplete segment terminates at the end of the velocity profile, the segment is
+      considered completed despite having a truncated execution time less than DT_SEGMENT.
+        The velocity profile is always assumed to progress through the ramp sequence:
+      acceleration ramp, cruising state, and deceleration ramp. Each ramp's travel distance
+      may range from zero to the length of the block. Velocity profiles can end either at
+      the end of planner block (typical) or mid-block at the end of a forced deceleration,
+      such as from a feed hold.
+    */
+    float dt_max = DT_SEGMENT; // Maximum segment time
+    float dt = 0.0f; // Initialize segment time
+    float time_var = dt_max; // Time worker variable
+    float mm_var; // mm-Distance worker variable
+    float speed_var; // Speed worker variable
+    float mm_remaining = pl_block->millimeters; // New segment distance from end of block.
+    float minimum_mm = mm_remaining-prep.req_mm_increment; // Guarantee at least one step.
+    if (minimum_mm < 0.0f) { minimum_mm = 0.0f; }
+
+    do {
+      switch (prep.ramp_type) {
+        case RAMP_DECEL_OVERRIDE:
+          speed_var = pl_block->acceleration*time_var;
+          mm_var = time_var*(prep.current_speed - 0.5f*speed_var);
+          mm_remaining -= mm_var;
+          if ((mm_remaining < prep.accelerate_until) || (mm_var <= 0)) {
+            // Cruise or cruise-deceleration types only for deceleration override.
+            mm_remaining = prep.accelerate_until; // NOTE: 0.0 at EOB
+            time_var = 2.0f*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed);
+            prep.ramp_type = RAMP_CRUISE;
+            prep.current_speed = prep.maximum_speed;
+          } else { // Mid-deceleration override ramp.
+            prep.current_speed -= speed_var;
+          }
+          break;
+        case RAMP_ACCEL:
+          // NOTE: Acceleration ramp only computes during first do-while loop.
+          speed_var = pl_block->acceleration*time_var;
+          mm_remaining -= time_var*(prep.current_speed + 0.5f*speed_var);
+          if (mm_remaining < prep.accelerate_until) { // End of acceleration ramp.
+            // Acceleration-cruise, acceleration-deceleration ramp junction, or end of block.
+            mm_remaining = prep.accelerate_until; // NOTE: 0.0 at EOB
+            time_var = 2.0f*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed);
+            if (mm_remaining == prep.decelerate_after) { prep.ramp_type = RAMP_DECEL; }
+            else { prep.ramp_type = RAMP_CRUISE; }
+            prep.current_speed = prep.maximum_speed;
+          } else { // Acceleration only.
+            prep.current_speed += speed_var;
+          }
+          break;
+        case RAMP_CRUISE:
+          // NOTE: mm_var used to retain the last mm_remaining for incomplete segment time_var calculations.
+          // NOTE: If maximum_speed*time_var value is too low, round-off can cause mm_var to not change. To
+          //   prevent this, simply enforce a minimum speed threshold in the planner.
+          mm_var = mm_remaining - prep.maximum_speed*time_var;
+          if (mm_var < prep.decelerate_after) { // End of cruise.
+            // Cruise-deceleration junction or end of block.
+            time_var = (mm_remaining - prep.decelerate_after)/prep.maximum_speed;
+            mm_remaining = prep.decelerate_after; // NOTE: 0.0 at EOB
+            prep.ramp_type = RAMP_DECEL;
+          } else { // Cruising only.
+            mm_remaining = mm_var;
+          }
+          break;
+        default: // case RAMP_DECEL:
+          // NOTE: mm_var used as a misc worker variable to prevent errors when near zero speed.
+          speed_var = pl_block->acceleration*time_var; // Used as delta speed (mm/min)
+          if (prep.current_speed > speed_var) { // Check if at or below zero speed.
+            // Compute distance from end of segment to end of block.
+            mm_var = mm_remaining - time_var*(prep.current_speed - 0.5f*speed_var); // (mm)
+            if (mm_var > prep.mm_complete) { // Typical case. In deceleration ramp.
+              mm_remaining = mm_var;
+              prep.current_speed -= speed_var;
+              break; // Segment complete. Exit switch-case statement. Continue do-while loop.
+            }
+          }
+          // Otherwise, at end of block or end of forced-deceleration.
+          time_var = 2.0f*(mm_remaining-prep.mm_complete)/(prep.current_speed+prep.exit_speed);
+          mm_remaining = prep.mm_complete;
+          prep.current_speed = prep.exit_speed;
+      }
+      dt += time_var; // Add computed ramp time to total segment time.
+      if (dt < dt_max) { time_var = dt_max - dt; } // **Incomplete** At ramp junction.
+      else {
+        if (mm_remaining > minimum_mm) { // Check for very slow segments with zero steps.
+          // Increase segment time to ensure at least one step in segment. Override and loop
+          // through distance calculations until minimum_mm or mm_complete.
+          dt_max += DT_SEGMENT;
+          time_var = dt_max - dt;
+        } else {
+          break; // **Complete** Exit loop. Segment execution time maxed.
+        }
+      }
+    } while (mm_remaining > prep.mm_complete); // **Complete** Exit loop. Profile complete.
+
+    #ifdef VARIABLE_SPINDLE
+      /* -----------------------------------------------------------------------------------
+        Compute spindle speed PWM output for step segment
+      */
+
+      if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) {
+        if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
+          float rpm = pl_block->spindle_speed;
+          // NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.        
+          if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); }
+          // If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE)
+          // but this would be instantaneous only and during a motion. May not matter at all.
+          prep.current_spindle_pwm = spindle_compute_pwm_value(rpm);
+        }
+        else {
+          sys.spindle_speed = 0.0;
+          prep.current_spindle_pwm = SPINDLE_PWM_OFF_VALUE;
+        }
+        bit_false(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM);
+      }
+      prep_segment->spindle_pwm = prep.current_spindle_pwm; // Reload segment PWM value
+
+    #endif
+    
+    /* -----------------------------------------------------------------------------------
+       Compute segment step rate, steps to execute, and apply necessary rate corrections.
+       NOTE: Steps are computed by direct scalar conversion of the millimeter distance
+       remaining in the block, rather than incrementally tallying the steps executed per
+       segment. This helps in removing floating point round-off issues of several additions.
+       However, since floats have only 7.2 significant digits, long moves with extremely
+       high step counts can exceed the precision of floats, which can lead to lost steps.
+       Fortunately, this scenario is highly unlikely and unrealistic in CNC machines
+       supported by Grbl (i.e. exceeding 10 meters axis travel at 200 step/mm).
+    */
+    float step_dist_remaining = prep.step_per_mm*mm_remaining; // Convert mm_remaining to steps
+    float n_steps_remaining = ceilf(step_dist_remaining); // Round-up current steps remaining
+    float last_n_steps_remaining = ceilf(prep.steps_remaining); // Round-up last steps remaining
+	prep_segment->n_step = (uint16_t)(last_n_steps_remaining - n_steps_remaining); // Compute number of steps to execute.
+
+    // Bail if we are at the end of a feed hold and don't have a step to execute.
+    if (prep_segment->n_step == 0) {
+      if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) {
+        // Less than one step to decelerate to zero speed, but already very close. AMASS
+        // requires full steps to execute. So, just bail.
+        bit_true(sys.step_control,STEP_CONTROL_END_MOTION);
+        #ifdef PARKING_ENABLE
+          if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; }
+        #endif
+        return; // Segment not generated, but current step data still retained.
+      }
+    }
+
+    // Compute segment step rate. Since steps are integers and mm distances traveled are not,
+    // the end of every segment can have a partial step of varying magnitudes that are not
+    // executed, because the stepper ISR requires whole steps due to the AMASS algorithm. To
+    // compensate, we track the time to execute the previous segment's partial step and simply
+    // apply it with the partial step distance to the current segment, so that it minutely
+    // adjusts the whole segment rate to keep step output exact. These rate adjustments are
+    // typically very small and do not adversely effect performance, but ensures that Grbl
+    // outputs the exact acceleration and velocity profiles as computed by the planner.
+    dt += prep.dt_remainder; // Apply previous segment partial step execute time
+    float inv_rate = dt/(last_n_steps_remaining - step_dist_remaining); // Compute adjusted step rate inverse
+
+    // Compute CPU cycles per step for the prepped segment.
+	uint32_t cycles = (uint32_t)ceilf((TICKS_PER_MICROSECOND * 1000000) *inv_rate * 60); // (cycles/step)
+
+    #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
+      // Compute step timing and multi-axis smoothing level.
+      // NOTE: AMASS overdrives the timer with each level, so only one prescalar is required.
+      if (cycles < AMASS_LEVEL1) { prep_segment->amass_level = 0; }
+      else {
+        if (cycles < AMASS_LEVEL2) { prep_segment->amass_level = 1; }
+        else if (cycles < AMASS_LEVEL3) { prep_segment->amass_level = 2; }
+        else { prep_segment->amass_level = 3; }
+        cycles >>= prep_segment->amass_level;
+        prep_segment->n_step <<= prep_segment->amass_level;
+      }
+      if (cycles < (1UL << 16)) { prep_segment->cycles_per_tick = cycles; } // < 65536 (4.1ms @ 16MHz)
+      else { prep_segment->cycles_per_tick = 0xffff; } // Just set the slowest speed possible.
+    #else
+      // Compute step timing and timer prescalar for normal step generation.
+      if (cycles < (1UL << 16)) { // < 65536  (4.1ms @ 16MHz)
+        prep_segment->prescaler = 1; // prescaler: 0
+        prep_segment->cycles_per_tick = cycles;
+      } else if (cycles < (1UL << 19)) { // < 524288 (32.8ms@16MHz)
+        prep_segment->prescaler = 2; // prescaler: 8
+        prep_segment->cycles_per_tick = cycles >> 3;
+      } else {
+        prep_segment->prescaler = 3; // prescaler: 64
+        if (cycles < (1UL << 22)) { // < 4194304 (262ms@16MHz)
+          prep_segment->cycles_per_tick =  cycles >> 6;
+        } else { // Just set the slowest speed possible. (Around 4 step/sec.)
+          prep_segment->cycles_per_tick = 0xffff;
+        }
+      }
+    #endif
+
+    // Segment complete! Increment segment buffer indices, so stepper ISR can immediately execute it.
+    segment_buffer_head = segment_next_head;
+    if ( ++segment_next_head == SEGMENT_BUFFER_SIZE ) { segment_next_head = 0; }
+
+    // Update the appropriate planner and segment data.
+    pl_block->millimeters = mm_remaining;
+    prep.steps_remaining = n_steps_remaining;
+    prep.dt_remainder = (n_steps_remaining - step_dist_remaining)*inv_rate;
+
+    // Check for exit conditions and flag to load next planner block.
+    if (mm_remaining == prep.mm_complete) {
+      // End of planner block or forced-termination. No more distance to be executed.
+      if (mm_remaining > 0.0f) { // At end of forced-termination.
+        // Reset prep parameters for resuming and then bail. Allow the stepper ISR to complete
+        // the segment queue, where realtime protocol will set new state upon receiving the
+        // cycle stop flag from the ISR. Prep_segment is blocked until then.
+        bit_true(sys.step_control,STEP_CONTROL_END_MOTION);
+        #ifdef PARKING_ENABLE
+          if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; }
+        #endif
+        return; // Bail!
+      } else { // End of planner block
+        // The planner block is complete. All steps are set to be executed in the segment buffer.
+        if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) {
+          bit_true(sys.step_control,STEP_CONTROL_END_MOTION);
+          return;
+        }
+        pl_block = NULL; // Set pointer to indicate check and load next planner block.
+        plan_discard_current_block();
+      }
+    }
+
+  }
+}
+
+
+// Called by realtime status reporting to fetch the current speed being executed. This value
+// however is not exactly the current speed, but the speed computed in the last step segment
+// in the segment buffer. It will always be behind by up to the number of segment blocks (-1)
+// divided by the ACCELERATION TICKS PER SECOND in seconds.
+float st_get_realtime_rate()
+{
+  if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)){
+    return prep.current_speed;
+  }
+  return 0.0f;
+}
+#ifdef STM32F103C8
+void TIM_Configuration(TIM_TypeDef* TIMER, u16 Period, u16 Prescaler, u8 PP)
+{
+	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
+	NVIC_InitTypeDef NVIC_InitStructure;
+
+	TIM_TimeBaseStructure.TIM_Period = Period - 1;
+	TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
+	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+	TIM_TimeBaseInit(TIMER, &TIM_TimeBaseStructure);
+
+	TIM_ClearITPendingBit(TIMER, TIM_IT_Update);
+	TIM_ITConfig(TIMER, TIM_IT_Update, ENABLE);
+	TIM_Cmd(TIMER, ENABLE);
+
+	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
+	if (TIMER == TIM2) { NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; }
+	else if (TIMER == TIM3) { NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; }
+	else if (TIMER == TIM4) { NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; }
+
+	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PP;
+	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+	NVIC_Init(&NVIC_InitStructure);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/stepper.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,67 @@
+/*
+  stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef stepper_h
+#define stepper_h
+
+#ifndef SEGMENT_BUFFER_SIZE
+#ifdef AVRTARGET
+#define SEGMENT_BUFFER_SIZE 6
+#else
+#define SEGMENT_BUFFER_SIZE 10
+#endif
+#endif
+
+// Initialize and setup the stepper motor subsystem
+void stepper_init();
+
+// Enable steppers, but cycle does not start unless called by motion control or realtime command.
+void st_wake_up();
+
+// Immediately disables steppers
+void st_go_idle();
+
+// Generate the step and direction port invert masks.
+void st_generate_step_dir_invert_masks();
+
+// Reset the stepper subsystem variables
+void st_reset();
+
+// Changes the run state of the step segment buffer to execute the special parking motion.
+void st_parking_setup_buffer();
+
+// Restores the step segment buffer to the normal run state after a parking motion.
+void st_parking_restore_buffer();
+
+// Reloads step segment buffer. Called continuously by realtime execution system.
+void st_prep_buffer();
+
+// Called by planner_recalculate() when the executing block is updated by the new plan.
+void st_update_plan_block_parameters();
+
+// Called by realtime status reporting if realtime rate reporting is enabled in config.h.
+float st_get_realtime_rate();
+
+extern const PORTPINDEF step_pin_mask[N_AXIS];
+extern const PORTPINDEF direction_pin_mask[N_AXIS];
+extern const PORTPINDEF limit_pin_mask[N_AXIS];
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/stepper.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,63 @@
+/*
+  stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
+  Part of Grbl
+
+  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
+  Copyright (c) 2009-2011 Simen Svale Skogsrud
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef stepper_h
+#define stepper_h
+
+#ifndef SEGMENT_BUFFER_SIZE
+  #define SEGMENT_BUFFER_SIZE 6
+#endif
+
+// Initialize and setup the stepper motor subsystem
+void stepper_init();
+
+// Enable steppers, but cycle does not start unless called by motion control or realtime command.
+void st_wake_up();
+
+// Immediately disables steppers
+void st_go_idle();
+
+// Generate the step and direction port invert masks.
+void st_generate_step_dir_invert_masks();
+
+// Reset the stepper subsystem variables
+void st_reset();
+
+// Changes the run state of the step segment buffer to execute the special parking motion.
+void st_parking_setup_buffer();
+
+// Restores the step segment buffer to the normal run state after a parking motion.
+void st_parking_restore_buffer();
+
+// Reloads step segment buffer. Called continuously by realtime execution system.
+void st_prep_buffer();
+
+// Called by planner_recalculate() when the executing block is updated by the new plan.
+void st_update_plan_block_parameters();
+
+// Called by realtime status reporting if realtime rate reporting is enabled in config.h.
+float st_get_realtime_rate();
+
+extern const PORTPINDEF step_pin_mask[N_AXIS];
+extern const PORTPINDEF direction_pin_mask[N_AXIS];
+extern const PORTPINDEF limit_pin_mask[N_AXIS];
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/system.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,578 @@
+/*
+  system.c - Handles system level commands and real-time processes
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+void system_init()
+{
+#ifdef AVRTARGET
+  CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins
+  #ifdef DISABLE_CONTROL_PIN_PULL_UP
+    CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down.
+  #else
+    CONTROL_PORT |= CONTROL_MASK;   // Enable internal pull-up resistors. Normal high operation.
+  #endif
+  CONTROL_PCMSK |= CONTROL_MASK;  // Enable specific pins of the Pin Change Interrupt
+  PCICR |= (1 << CONTROL_INT);   // Enable Pin Change Interrupt
+#endif
+#ifdef STM32F103C8
+  GPIO_InitTypeDef GPIO_InitStructure;
+  RCC_APB2PeriphClockCmd(RCC_CONTROL_PORT | RCC_APB2Periph_AFIO, ENABLE);
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+#ifdef DISABLE_CONTROL_PIN_PULL_UP
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+#else
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+#endif
+  GPIO_InitStructure.GPIO_Pin = CONTROL_MASK;
+  GPIO_Init(CONTROL_PORT, &GPIO_InitStructure);
+
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_RESET_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_FEED_HOLD_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_CYCLE_START_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_SAFETY_DOOR_BIT);
+
+  EXTI_InitTypeDef EXTI_InitStructure;
+  EXTI_InitStructure.EXTI_Line = CONTROL_MASK;    //
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Interrupt mode, optional values for the interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event.
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Trigger mode, can be a falling edge trigger EXTI_Trigger_Falling, the rising edge triggered EXTI_Trigger_Rising, or any level (rising edge and falling edge trigger EXTI_Trigger_Rising_Falling)
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+
+  NVIC_InitTypeDef NVIC_InitStructure;
+  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //Enable keypad external interrupt channel
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Priority 2,
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Sub priority 2
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel
+  NVIC_Init(&NVIC_InitStructure);
+#endif
+}
+
+
+// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where
+// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is
+// defined by the CONTROL_PIN_INDEX in the header file.
+uint8_t system_control_get_state()
+{
+  uint8_t control_state = 0;
+#ifdef AVRTARGET
+  uint8_t pin = (CONTROL_PIN & CONTROL_MASK);
+#endif
+#ifdef WIN32
+  uint8_t pin = 0;
+#endif
+#ifdef STM32F103C8
+  uint16_t pin= GPIO_ReadInputData(CONTROL_PIN_PORT);
+#endif
+  #ifdef INVERT_CONTROL_PIN_MASK
+    pin ^= INVERT_CONTROL_PIN_MASK;
+  #endif
+  if (pin) {
+    #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+      if (bit_isfalse(pin,(1<<CONTROL_SAFETY_DOOR_BIT))) { control_state |= CONTROL_PIN_INDEX_SAFETY_DOOR; }
+    #endif
+    if (bit_isfalse(pin,(1<<CONTROL_RESET_BIT))) { control_state |= CONTROL_PIN_INDEX_RESET; }
+    if (bit_isfalse(pin,(1<<CONTROL_FEED_HOLD_BIT))) { control_state |= CONTROL_PIN_INDEX_FEED_HOLD; }
+    if (bit_isfalse(pin,(1<<CONTROL_CYCLE_START_BIT))) { control_state |= CONTROL_PIN_INDEX_CYCLE_START; }
+  }
+  return(control_state);
+}
+
+
+// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
+// only the realtime command execute variable to have the main program execute these when
+// its ready. This works exactly like the character-based realtime commands when picked off
+// directly from the incoming serial data stream.
+#ifdef AVRTARGET
+ISR(CONTROL_INT_vect)
+{
+  uint8_t pin = system_control_get_state();
+  if (pin) {
+    if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) {
+      mc_reset();
+    } else if (bit_istrue(pin,CONTROL_PIN_INDEX_CYCLE_START)) {
+      bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
+    #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN
+      } else if (bit_istrue(pin,CONTROL_PIN_INDEX_FEED_HOLD)) {
+        bit_true(sys_rt_exec_state, EXEC_FEED_HOLD);
+    #else
+      } else if (bit_istrue(pin,CONTROL_PIN_INDEX_SAFETY_DOOR)) {
+        bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
+    #endif
+    }
+  }
+}
+#endif
+#if defined (STM32F103C8)
+void EXTI9_5_IRQHandler(void)
+{
+    EXTI_ClearITPendingBit((1 << CONTROL_RESET_BIT) | (1 << CONTROL_FEED_HOLD_BIT) | (1 << CONTROL_CYCLE_START_BIT) | (1 << CONTROL_SAFETY_DOOR_BIT));
+	uint8_t pin = system_control_get_state();
+	if (pin) 
+	{ 
+		if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) 
+		{
+			mc_reset();
+		}
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_CYCLE_START))
+		{
+			bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
+		}
+#ifndef ENABLE_SAFETY_DOOR_INPUT_PIN
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_FEED_HOLD))
+		{
+			bit_true(sys_rt_exec_state, EXEC_FEED_HOLD);
+		}
+#else
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_SAFETY_DOOR))
+		{
+			bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
+		}
+#endif
+		NVIC_ClearPendingIRQ(EXTI9_5_IRQn);
+}
+}
+#endif
+
+// Returns if safety door is ajar(T) or closed(F), based on pin state.
+uint8_t system_check_safety_door_ajar()
+{
+  #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+    return(system_control_get_state() & CONTROL_PIN_INDEX_SAFETY_DOOR);
+  #else
+    return(false); // Input pin not enabled, so just return that it's closed.
+  #endif
+}
+
+
+// Executes user startup script, if stored.
+void system_execute_startup(char *line)
+{
+  uint8_t n;
+  for (n=0; n < N_STARTUP_LINE; n++) {
+    if (!(settings_read_startup_line(n, line))) {
+      line[0] = 0;
+      report_execute_startup_message(line,STATUS_SETTING_READ_FAIL);
+    } else {
+      if (line[0] != 0) {
+        uint8_t status_code = gc_execute_line(line);
+        report_execute_startup_message(line,status_code);
+      }
+    }
+  }
+}
+
+
+// Directs and executes one line of formatted input from protocol_process. While mostly
+// incoming streaming g-code blocks, this also executes Grbl internal commands, such as
+// settings, initiating the homing cycle, and toggling switch states. This differs from
+// the realtime command module by being susceptible to when Grbl is ready to execute the
+// next line during a cycle, so for switches like block delete, the switch only effects
+// the lines that are processed afterward, not necessarily real-time during a cycle,
+// since there are motions already stored in the buffer. However, this 'lag' should not
+// be an issue, since these commands are not typically used during a cycle.
+uint8_t system_execute_line(char *line)
+{
+  uint8_t char_counter = 1;
+  uint8_t helper_var = 0; // Helper variable
+  float parameter, value;
+  switch( line[char_counter] ) {
+    case 0 : report_grbl_help(); break;
+    case 'J' : // Jogging
+      // Execute only if in IDLE or JOG states.
+      if (sys.state != STATE_IDLE && sys.state != STATE_JOG) { return(STATUS_IDLE_ERROR); }
+      if(line[2] != '=') { return(STATUS_INVALID_STATEMENT); }
+      return(gc_execute_line(line)); // NOTE: $J= is ignored inside g-code parser and used to detect jog motions.
+      break;
+    case '$': case 'G': case 'C': case 'X':
+      if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); }
+      switch( line[1] ) {
+        case '$' : // Prints Grbl settings
+          if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print.
+          else { report_grbl_settings(); }
+          break;
+        case 'G' : // Prints gcode parser state
+          // TODO: Move this to realtime commands for GUIs to request this data during suspend-state.
+          report_gcode_modes();
+          break;
+        case 'C' : // Set check g-code mode [IDLE/CHECK]
+          // Perform reset when toggling off. Check g-code mode should only work if Grbl
+          // is idle and ready, regardless of alarm locks. This is mainly to keep things
+          // simple and consistent.
+          if ( sys.state == STATE_CHECK_MODE ) {
+            mc_reset();
+            report_feedback_message(MESSAGE_DISABLED);
+          } else {
+            if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode.
+            sys.state = STATE_CHECK_MODE;
+            report_feedback_message(MESSAGE_ENABLED);
+          }
+          break;
+        case 'X' : // Disable alarm lock [ALARM]
+          if (sys.state == STATE_ALARM) {
+            // Block if safety door is ajar.
+            if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); }
+            report_feedback_message(MESSAGE_ALARM_UNLOCK);
+            sys.state = STATE_IDLE;
+            // Don't run startup script. Prevents stored moves in startup from causing accidents.
+          } // Otherwise, no effect.
+          break;
+      }
+      break;
+    default :
+      // Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing)
+      if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); }
+      switch( line[1] ) {
+        case '#' : // Print Grbl NGC parameters
+          if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); }
+          else { report_ngc_parameters(); }
+          break;
+        case 'H' : // Perform homing cycle [IDLE/ALARM]
+          if (bit_isfalse(settings.flags,BITFLAG_HOMING_ENABLE)) {return(STATUS_SETTING_DISABLED); }
+          if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); } // Block if safety door is ajar.
+          sys.state = STATE_HOMING; // Set system state variable
+          if (line[2] == 0) {
+            mc_homing_cycle(HOMING_CYCLE_ALL);
+          #ifdef HOMING_SINGLE_AXIS_COMMANDS
+            } else if (line[3] == 0) {
+              switch (line[2]) {
+                case 'X': mc_homing_cycle(HOMING_CYCLE_X); break;
+                case 'Y': mc_homing_cycle(HOMING_CYCLE_Y); break;
+                case 'Z': mc_homing_cycle(HOMING_CYCLE_Z); break;
+                default: return(STATUS_INVALID_STATEMENT);
+              }
+          #endif
+          } else { return(STATUS_INVALID_STATEMENT); }
+          if (!sys.abort) {  // Execute startup scripts after successful homing.
+            sys.state = STATE_IDLE; // Set to IDLE when complete.
+            st_go_idle(); // Set steppers to the settings idle state before returning.
+            if (line[2] == 0) { system_execute_startup(line); }
+          }
+          break;
+        case 'S' : // Puts Grbl to sleep [IDLE/ALARM]
+          if ((line[2] != 'L') || (line[3] != 'P') || (line[4] != 0)) { return(STATUS_INVALID_STATEMENT); }
+          system_set_exec_state_flag(EXEC_SLEEP); // Set to execute sleep mode immediately
+          break;
+        case 'I' : // Print or store build info. [IDLE/ALARM]
+          if ( line[++char_counter] == 0 ) {
+            settings_read_build_info(line);
+            report_build_info(line);
+          #ifdef ENABLE_BUILD_INFO_WRITE_COMMAND
+            } else { // Store startup line [IDLE/ALARM]
+              if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); }
+              helper_var = char_counter; // Set helper variable as counter to start of user info line.
+              do {
+                line[char_counter-helper_var] = line[char_counter];
+              } while (line[char_counter++] != 0);
+              settings_store_build_info(line);
+          #endif
+          }
+          break;
+        case 'R' : // Restore defaults [IDLE/ALARM]
+          if ((line[2] != 'S') || (line[3] != 'T') || (line[4] != '=') || (line[6] != 0)) { return(STATUS_INVALID_STATEMENT); }
+          switch (line[5]) {
+            #ifdef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS
+              case '$': settings_restore(SETTINGS_RESTORE_DEFAULTS); break;
+            #endif
+            #ifdef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS
+              case '#': settings_restore(SETTINGS_RESTORE_PARAMETERS); break;
+            #endif
+            #ifdef ENABLE_RESTORE_EEPROM_WIPE_ALL
+              case '*': settings_restore(SETTINGS_RESTORE_ALL); break;
+            #endif
+            default: return(STATUS_INVALID_STATEMENT);
+          }
+          report_feedback_message(MESSAGE_RESTORE_DEFAULTS);
+          mc_reset(); // Force reset to ensure settings are initialized correctly.
+          break;
+        case 'N' : // Startup lines. [IDLE/ALARM]
+          if ( line[++char_counter] == 0 ) { // Print startup lines
+            for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) {
+              if (!(settings_read_startup_line(helper_var, line))) {
+                report_status_message(STATUS_SETTING_READ_FAIL);
+              } else {
+                report_startup_line(helper_var,line);
+              }
+            }
+            break;
+          } else { // Store startup line [IDLE Only] Prevents motion during ALARM.
+            if (sys.state != STATE_IDLE) { return(STATUS_IDLE_ERROR); } // Store only when idle.
+            helper_var = true;  // Set helper_var to flag storing method.
+            // No break. Continues into default: to read remaining command characters.
+          }
+        default :  // Storing setting methods [IDLE/ALARM]
+          if(!read_float(line, &char_counter, &parameter)) { return(STATUS_BAD_NUMBER_FORMAT); }
+          if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); }
+          if (helper_var) { // Store startup line
+            // Prepare sending gcode block to gcode parser by shifting all characters
+            helper_var = char_counter; // Set helper variable as counter to start of gcode block
+            do {
+              line[char_counter-helper_var] = line[char_counter];
+            } while (line[char_counter++] != 0);
+            // Execute gcode block to ensure block is valid.
+            helper_var = gc_execute_line(line); // Set helper_var to returned status code.
+            if (helper_var) { return(helper_var); }
+            else {
+              helper_var = truncf(parameter); // Set helper_var to int value of parameter
+              settings_store_startup_line(helper_var,line);
+            }
+          } else { // Store global setting.
+            if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
+            if((line[char_counter] != 0) || (parameter > 255)) { return(STATUS_INVALID_STATEMENT); }
+            return(settings_store_global_setting((uint8_t)parameter, value));
+          }
+      }
+  }
+  return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
+}
+
+
+
+void system_flag_wco_change()
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE
+    protocol_buffer_synchronize();
+  #endif
+  sys.report_wco_counter = 0;
+}
+
+
+// Returns machine position of axis 'idx'. Must be sent a 'step' array.
+// NOTE: If motor steps and machine position are not in the same coordinate frame, this function
+//   serves as a central place to compute the transformation.
+float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
+{
+  float pos;
+  #ifdef COREXY
+    if (idx==X_AXIS) {
+      pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx];
+    } else if (idx==Y_AXIS) {
+      pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx];
+    } else {
+      pos = steps[idx]/settings.steps_per_mm[idx];
+    }
+  #else
+    pos = steps[idx]/settings.steps_per_mm[idx];
+  #endif
+  return(pos);
+}
+
+
+void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
+{
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    position[idx] = system_convert_axis_steps_to_mpos(steps, idx);
+  }
+  return;
+}
+
+
+// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
+#ifdef COREXY
+  int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
+  {
+    return( (steps[A_MOTOR] + steps[B_MOTOR])/2 );
+  }
+  int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps)
+  {
+    return( (steps[A_MOTOR] - steps[B_MOTOR])/2 );
+  }
+#endif
+
+
+// Checks and reports if target array exceeds machine travel limits.
+uint8_t system_check_travel_limits(float *target)
+{
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    #ifdef HOMING_FORCE_SET_ORIGIN
+      // When homing forced set origin is enabled, soft limits checks need to account for directionality.
+      // NOTE: max_travel is stored as negative
+      if (bit_istrue(settings.homing_dir_mask,bit(idx))) {
+        if (target[idx] < 0 || target[idx] > -settings.max_travel[idx]) { return(true); }
+      } else {
+        if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
+      }
+    #else
+      // NOTE: max_travel is stored as negative
+      if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
+    #endif
+  }
+  return(false);
+}
+
+#ifdef WIN32
+extern CRITICAL_SECTION CriticalSection;
+#endif
+
+// Special handlers for setting and clearing Grbl's real-time execution flags.
+void system_set_exec_state_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_state |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_state |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_state |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_state_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_state &= ~(mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_state &= ~(mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_state &= ~(mask);
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_alarm(uint8_t code) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_alarm = code;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_alarm |= (code);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_alarm |= (code);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_alarm() {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_alarm = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_alarm = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_alarm = 0;
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_motion_override_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_motion_override |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_motion_override |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_motion_override |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_accessory_override_flag(uint8_t mask) {
+#ifdef AVRTARGET
+	uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_accessory_override |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_accessory_override |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_accessory_override |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_motion_overrides() {
+#ifdef AVRTARGET
+	uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_motion_override = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_motion_override = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_motion_override = 0;
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_accessory_overrides() {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_accessory_override = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_accessory_override = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_accessory_override = 0;
+  __enable_irq();
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/system.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,577 @@
+/*
+  system.c - Handles system level commands and real-time processes
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "grbl.h"
+
+
+void system_init()
+{
+#ifdef AVRTARGET
+  CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins
+  #ifdef DISABLE_CONTROL_PIN_PULL_UP
+    CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down.
+  #else
+    CONTROL_PORT |= CONTROL_MASK;   // Enable internal pull-up resistors. Normal high operation.
+  #endif
+  CONTROL_PCMSK |= CONTROL_MASK;  // Enable specific pins of the Pin Change Interrupt
+  PCICR |= (1 << CONTROL_INT);   // Enable Pin Change Interrupt
+#endif
+#ifdef STM32F103C8
+  GPIO_InitTypeDef GPIO_InitStructure;
+  RCC_APB2PeriphClockCmd(RCC_CONTROL_PORT | RCC_APB2Periph_AFIO, ENABLE);
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+#ifdef DISABLE_CONTROL_PIN_PULL_UP
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+#else
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+#endif
+  GPIO_InitStructure.GPIO_Pin = CONTROL_MASK;
+  GPIO_Init(CONTROL_PORT, &GPIO_InitStructure);
+
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_RESET_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_FEED_HOLD_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_CYCLE_START_BIT);
+  GPIO_EXTILineConfig(GPIO_CONTROL_PORT, CONTROL_SAFETY_DOOR_BIT);
+
+  EXTI_InitTypeDef EXTI_InitStructure;
+  EXTI_InitStructure.EXTI_Line = CONTROL_MASK;    //
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Interrupt mode, optional values for the interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event.
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Trigger mode, can be a falling edge trigger EXTI_Trigger_Falling, the rising edge triggered EXTI_Trigger_Rising, or any level (rising edge and falling edge trigger EXTI_Trigger_Rising_Falling)
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+
+  NVIC_InitTypeDef NVIC_InitStructure;
+  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //Enable keypad external interrupt channel
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Priority 2,
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Sub priority 2
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel
+  NVIC_Init(&NVIC_InitStructure);
+#endif
+}
+
+
+// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where
+// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is
+// defined by the CONTROL_PIN_INDEX in the header file.
+uint8_t system_control_get_state()
+{
+  uint8_t control_state = 0;
+#ifdef AVRTARGET
+  uint8_t pin = (CONTROL_PIN & CONTROL_MASK);
+#endif
+#ifdef WIN32
+  uint8_t pin = 0;
+#endif
+#ifdef STM32F103C8
+  uint16_t pin= GPIO_ReadInputData(CONTROL_PIN_PORT);
+#endif
+  #ifdef INVERT_CONTROL_PIN_MASK
+    pin ^= INVERT_CONTROL_PIN_MASK;
+  #endif
+  if (pin) {
+    #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+      if (bit_isfalse(pin,(1<<CONTROL_SAFETY_DOOR_BIT))) { control_state |= CONTROL_PIN_INDEX_SAFETY_DOOR; }
+    #endif
+    if (bit_isfalse(pin,(1<<CONTROL_RESET_BIT))) { control_state |= CONTROL_PIN_INDEX_RESET; }
+    if (bit_isfalse(pin,(1<<CONTROL_FEED_HOLD_BIT))) { control_state |= CONTROL_PIN_INDEX_FEED_HOLD; }
+    if (bit_isfalse(pin,(1<<CONTROL_CYCLE_START_BIT))) { control_state |= CONTROL_PIN_INDEX_CYCLE_START; }
+  }
+  return(control_state);
+}
+
+
+// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
+// only the realtime command execute variable to have the main program execute these when
+// its ready. This works exactly like the character-based realtime commands when picked off
+// directly from the incoming serial data stream.
+#ifdef AVRTARGET
+ISR(CONTROL_INT_vect)
+{
+  uint8_t pin = system_control_get_state();
+  if (pin) {
+    if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) {
+      mc_reset();
+    } else if (bit_istrue(pin,CONTROL_PIN_INDEX_CYCLE_START)) {
+      bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
+    #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN
+      } else if (bit_istrue(pin,CONTROL_PIN_INDEX_FEED_HOLD)) {
+        bit_true(sys_rt_exec_state, EXEC_FEED_HOLD);
+    #else
+      } else if (bit_istrue(pin,CONTROL_PIN_INDEX_SAFETY_DOOR)) {
+        bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
+    #endif
+    }
+  }
+}
+#endif
+#if defined (STM32F103C8)
+void EXTI9_5_IRQHandler(void)
+{
+	uint8_t pin = system_control_get_state();
+	if (pin) 
+	{ 
+		if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) 
+		{
+			mc_reset();
+		}
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_CYCLE_START))
+		{
+			bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
+		}
+#ifndef ENABLE_SAFETY_DOOR_INPUT_PIN
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_FEED_HOLD))
+		{
+			bit_true(sys_rt_exec_state, EXEC_FEED_HOLD);
+		}
+#else
+		else if (bit_istrue(pin, CONTROL_PIN_INDEX_SAFETY_DOOR))
+		{
+			bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
+		}
+#endif
+		NVIC_ClearPendingIRQ(EXTI9_5_IRQn);
+}
+}
+#endif
+
+// Returns if safety door is ajar(T) or closed(F), based on pin state.
+uint8_t system_check_safety_door_ajar()
+{
+  #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+    return(system_control_get_state() & CONTROL_PIN_INDEX_SAFETY_DOOR);
+  #else
+    return(false); // Input pin not enabled, so just return that it's closed.
+  #endif
+}
+
+
+// Executes user startup script, if stored.
+void system_execute_startup(char *line)
+{
+  uint8_t n;
+  for (n=0; n < N_STARTUP_LINE; n++) {
+    if (!(settings_read_startup_line(n, line))) {
+      line[0] = 0;
+      report_execute_startup_message(line,STATUS_SETTING_READ_FAIL);
+    } else {
+      if (line[0] != 0) {
+        uint8_t status_code = gc_execute_line(line);
+        report_execute_startup_message(line,status_code);
+      }
+    }
+  }
+}
+
+
+// Directs and executes one line of formatted input from protocol_process. While mostly
+// incoming streaming g-code blocks, this also executes Grbl internal commands, such as
+// settings, initiating the homing cycle, and toggling switch states. This differs from
+// the realtime command module by being susceptible to when Grbl is ready to execute the
+// next line during a cycle, so for switches like block delete, the switch only effects
+// the lines that are processed afterward, not necessarily real-time during a cycle,
+// since there are motions already stored in the buffer. However, this 'lag' should not
+// be an issue, since these commands are not typically used during a cycle.
+uint8_t system_execute_line(char *line)
+{
+  uint8_t char_counter = 1;
+  uint8_t helper_var = 0; // Helper variable
+  float parameter, value;
+  switch( line[char_counter] ) {
+    case 0 : report_grbl_help(); break;
+    case 'J' : // Jogging
+      // Execute only if in IDLE or JOG states.
+      if (sys.state != STATE_IDLE && sys.state != STATE_JOG) { return(STATUS_IDLE_ERROR); }
+      if(line[2] != '=') { return(STATUS_INVALID_STATEMENT); }
+      return(gc_execute_line(line)); // NOTE: $J= is ignored inside g-code parser and used to detect jog motions.
+      break;
+    case '$': case 'G': case 'C': case 'X':
+      if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); }
+      switch( line[1] ) {
+        case '$' : // Prints Grbl settings
+          if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print.
+          else { report_grbl_settings(); }
+          break;
+        case 'G' : // Prints gcode parser state
+          // TODO: Move this to realtime commands for GUIs to request this data during suspend-state.
+          report_gcode_modes();
+          break;
+        case 'C' : // Set check g-code mode [IDLE/CHECK]
+          // Perform reset when toggling off. Check g-code mode should only work if Grbl
+          // is idle and ready, regardless of alarm locks. This is mainly to keep things
+          // simple and consistent.
+          if ( sys.state == STATE_CHECK_MODE ) {
+            mc_reset();
+            report_feedback_message(MESSAGE_DISABLED);
+          } else {
+            if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode.
+            sys.state = STATE_CHECK_MODE;
+            report_feedback_message(MESSAGE_ENABLED);
+          }
+          break;
+        case 'X' : // Disable alarm lock [ALARM]
+          if (sys.state == STATE_ALARM) {
+            // Block if safety door is ajar.
+            if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); }
+            report_feedback_message(MESSAGE_ALARM_UNLOCK);
+            sys.state = STATE_IDLE;
+            // Don't run startup script. Prevents stored moves in startup from causing accidents.
+          } // Otherwise, no effect.
+          break;
+      }
+      break;
+    default :
+      // Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing)
+      if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); }
+      switch( line[1] ) {
+        case '#' : // Print Grbl NGC parameters
+          if ( line[2] != 0 ) { return(STATUS_INVALID_STATEMENT); }
+          else { report_ngc_parameters(); }
+          break;
+        case 'H' : // Perform homing cycle [IDLE/ALARM]
+          if (bit_isfalse(settings.flags,BITFLAG_HOMING_ENABLE)) {return(STATUS_SETTING_DISABLED); }
+          if (system_check_safety_door_ajar()) { return(STATUS_CHECK_DOOR); } // Block if safety door is ajar.
+          sys.state = STATE_HOMING; // Set system state variable
+          if (line[2] == 0) {
+            mc_homing_cycle(HOMING_CYCLE_ALL);
+          #ifdef HOMING_SINGLE_AXIS_COMMANDS
+            } else if (line[3] == 0) {
+              switch (line[2]) {
+                case 'X': mc_homing_cycle(HOMING_CYCLE_X); break;
+                case 'Y': mc_homing_cycle(HOMING_CYCLE_Y); break;
+                case 'Z': mc_homing_cycle(HOMING_CYCLE_Z); break;
+                default: return(STATUS_INVALID_STATEMENT);
+              }
+          #endif
+          } else { return(STATUS_INVALID_STATEMENT); }
+          if (!sys.abort) {  // Execute startup scripts after successful homing.
+            sys.state = STATE_IDLE; // Set to IDLE when complete.
+            st_go_idle(); // Set steppers to the settings idle state before returning.
+            if (line[2] == 0) { system_execute_startup(line); }
+          }
+          break;
+        case 'S' : // Puts Grbl to sleep [IDLE/ALARM]
+          if ((line[2] != 'L') || (line[3] != 'P') || (line[4] != 0)) { return(STATUS_INVALID_STATEMENT); }
+          system_set_exec_state_flag(EXEC_SLEEP); // Set to execute sleep mode immediately
+          break;
+        case 'I' : // Print or store build info. [IDLE/ALARM]
+          if ( line[++char_counter] == 0 ) {
+            settings_read_build_info(line);
+            report_build_info(line);
+          #ifdef ENABLE_BUILD_INFO_WRITE_COMMAND
+            } else { // Store startup line [IDLE/ALARM]
+              if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); }
+              helper_var = char_counter; // Set helper variable as counter to start of user info line.
+              do {
+                line[char_counter-helper_var] = line[char_counter];
+              } while (line[char_counter++] != 0);
+              settings_store_build_info(line);
+          #endif
+          }
+          break;
+        case 'R' : // Restore defaults [IDLE/ALARM]
+          if ((line[2] != 'S') || (line[3] != 'T') || (line[4] != '=') || (line[6] != 0)) { return(STATUS_INVALID_STATEMENT); }
+          switch (line[5]) {
+            #ifdef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS
+              case '$': settings_restore(SETTINGS_RESTORE_DEFAULTS); break;
+            #endif
+            #ifdef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS
+              case '#': settings_restore(SETTINGS_RESTORE_PARAMETERS); break;
+            #endif
+            #ifdef ENABLE_RESTORE_EEPROM_WIPE_ALL
+              case '*': settings_restore(SETTINGS_RESTORE_ALL); break;
+            #endif
+            default: return(STATUS_INVALID_STATEMENT);
+          }
+          report_feedback_message(MESSAGE_RESTORE_DEFAULTS);
+          mc_reset(); // Force reset to ensure settings are initialized correctly.
+          break;
+        case 'N' : // Startup lines. [IDLE/ALARM]
+          if ( line[++char_counter] == 0 ) { // Print startup lines
+            for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) {
+              if (!(settings_read_startup_line(helper_var, line))) {
+                report_status_message(STATUS_SETTING_READ_FAIL);
+              } else {
+                report_startup_line(helper_var,line);
+              }
+            }
+            break;
+          } else { // Store startup line [IDLE Only] Prevents motion during ALARM.
+            if (sys.state != STATE_IDLE) { return(STATUS_IDLE_ERROR); } // Store only when idle.
+            helper_var = true;  // Set helper_var to flag storing method.
+            // No break. Continues into default: to read remaining command characters.
+          }
+        default :  // Storing setting methods [IDLE/ALARM]
+          if(!read_float(line, &char_counter, &parameter)) { return(STATUS_BAD_NUMBER_FORMAT); }
+          if(line[char_counter++] != '=') { return(STATUS_INVALID_STATEMENT); }
+          if (helper_var) { // Store startup line
+            // Prepare sending gcode block to gcode parser by shifting all characters
+            helper_var = char_counter; // Set helper variable as counter to start of gcode block
+            do {
+              line[char_counter-helper_var] = line[char_counter];
+            } while (line[char_counter++] != 0);
+            // Execute gcode block to ensure block is valid.
+            helper_var = gc_execute_line(line); // Set helper_var to returned status code.
+            if (helper_var) { return(helper_var); }
+            else {
+              helper_var = trunc(parameter); // Set helper_var to int value of parameter
+              settings_store_startup_line(helper_var,line);
+            }
+          } else { // Store global setting.
+            if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
+            if((line[char_counter] != 0) || (parameter > 255)) { return(STATUS_INVALID_STATEMENT); }
+            return(settings_store_global_setting((uint8_t)parameter, value));
+          }
+      }
+  }
+  return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
+}
+
+
+
+void system_flag_wco_change()
+{
+  #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE
+    protocol_buffer_synchronize();
+  #endif
+  sys.report_wco_counter = 0;
+}
+
+
+// Returns machine position of axis 'idx'. Must be sent a 'step' array.
+// NOTE: If motor steps and machine position are not in the same coordinate frame, this function
+//   serves as a central place to compute the transformation.
+float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
+{
+  float pos;
+  #ifdef COREXY
+    if (idx==X_AXIS) {
+      pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx];
+    } else if (idx==Y_AXIS) {
+      pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx];
+    } else {
+      pos = steps[idx]/settings.steps_per_mm[idx];
+    }
+  #else
+    pos = steps[idx]/settings.steps_per_mm[idx];
+  #endif
+  return(pos);
+}
+
+
+void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
+{
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    position[idx] = system_convert_axis_steps_to_mpos(steps, idx);
+  }
+  return;
+}
+
+
+// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
+#ifdef COREXY
+  int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
+  {
+    return( (steps[A_MOTOR] + steps[B_MOTOR])/2 );
+  }
+  int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps)
+  {
+    return( (steps[A_MOTOR] - steps[B_MOTOR])/2 );
+  }
+#endif
+
+
+// Checks and reports if target array exceeds machine travel limits.
+uint8_t system_check_travel_limits(float *target)
+{
+  uint8_t idx;
+  for (idx=0; idx<N_AXIS; idx++) {
+    #ifdef HOMING_FORCE_SET_ORIGIN
+      // When homing forced set origin is enabled, soft limits checks need to account for directionality.
+      // NOTE: max_travel is stored as negative
+      if (bit_istrue(settings.homing_dir_mask,bit(idx))) {
+        if (target[idx] < 0 || target[idx] > -settings.max_travel[idx]) { return(true); }
+      } else {
+        if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
+      }
+    #else
+      // NOTE: max_travel is stored as negative
+      if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
+    #endif
+  }
+  return(false);
+}
+
+#ifdef WIN32
+extern CRITICAL_SECTION CriticalSection;
+#endif
+
+// Special handlers for setting and clearing Grbl's real-time execution flags.
+void system_set_exec_state_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_state |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_state |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_state |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_state_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_state &= ~(mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_state &= ~(mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_state &= ~(mask);
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_alarm(uint8_t code) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_alarm = code;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_alarm |= (code);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_alarm |= (code);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_alarm() {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_alarm = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_alarm = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_alarm = 0;
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_motion_override_flag(uint8_t mask) {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_motion_override |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_motion_override |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_motion_override |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_set_exec_accessory_override_flag(uint8_t mask) {
+#ifdef AVRTARGET
+	uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_accessory_override |= (mask);
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_accessory_override |= (mask);
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_accessory_override |= (mask);
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_motion_overrides() {
+#ifdef AVRTARGET
+	uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_motion_override = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_motion_override = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_motion_override = 0;
+  __enable_irq();
+#endif
+}
+
+void system_clear_exec_accessory_overrides() {
+#ifdef AVRTARGET
+  uint8_t sreg = SREG;
+  cli();
+  sys_rt_exec_accessory_override = 0;
+  SREG = sreg;
+#endif
+#ifdef WIN32
+  EnterCriticalSection(&CriticalSection);
+  sys_rt_exec_accessory_override = 0;
+  LeaveCriticalSection(&CriticalSection);
+#endif
+#ifdef STM32F103C8
+  __disable_irq();
+  sys_rt_exec_accessory_override = 0;
+  __enable_irq();
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/system.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,208 @@
+/*
+  system.h - Header for system level commands and real-time processes
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef system_h
+#define system_h
+
+#include "grbl.h"
+
+// Define system executor bit map. Used internally by realtime protocol as realtime command flags,
+// which notifies the main program to execute the specified realtime command asynchronously.
+// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default
+// flags are always false, so the realtime protocol only needs to check for a non-zero value to
+// know when there is a realtime command to execute.
+#define EXEC_STATUS_REPORT  bit(0) // bitmask 00000001
+#define EXEC_CYCLE_START    bit(1) // bitmask 00000010
+#define EXEC_CYCLE_STOP     bit(2) // bitmask 00000100
+#define EXEC_FEED_HOLD      bit(3) // bitmask 00001000
+#define EXEC_RESET          bit(4) // bitmask 00010000
+#define EXEC_SAFETY_DOOR    bit(5) // bitmask 00100000
+#define EXEC_MOTION_CANCEL  bit(6) // bitmask 01000000
+#define EXEC_SLEEP          bit(7) // bitmask 10000000
+
+// Alarm executor codes. Valid values (1-255). Zero is reserved.
+#define EXEC_ALARM_HARD_LIMIT           1
+#define EXEC_ALARM_SOFT_LIMIT           2
+#define EXEC_ALARM_ABORT_CYCLE          3
+#define EXEC_ALARM_PROBE_FAIL_INITIAL   4
+#define EXEC_ALARM_PROBE_FAIL_CONTACT   5
+#define EXEC_ALARM_HOMING_FAIL_RESET    6
+#define EXEC_ALARM_HOMING_FAIL_DOOR     7
+#define EXEC_ALARM_HOMING_FAIL_PULLOFF  8
+#define EXEC_ALARM_HOMING_FAIL_APPROACH 9
+
+// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides.
+// Spindle/coolant and feed/rapids are separated into two controlling flag variables.
+#define EXEC_FEED_OVR_RESET         bit(0)
+#define EXEC_FEED_OVR_COARSE_PLUS   bit(1)
+#define EXEC_FEED_OVR_COARSE_MINUS  bit(2)
+#define EXEC_FEED_OVR_FINE_PLUS     bit(3)
+#define EXEC_FEED_OVR_FINE_MINUS    bit(4)
+#define EXEC_RAPID_OVR_RESET        bit(5)
+#define EXEC_RAPID_OVR_MEDIUM       bit(6)
+#define EXEC_RAPID_OVR_LOW          bit(7)
+// #define EXEC_RAPID_OVR_EXTRA_LOW   bit(*) // *NOT SUPPORTED*
+
+#define EXEC_SPINDLE_OVR_RESET         bit(0)
+#define EXEC_SPINDLE_OVR_COARSE_PLUS   bit(1)
+#define EXEC_SPINDLE_OVR_COARSE_MINUS  bit(2)
+#define EXEC_SPINDLE_OVR_FINE_PLUS     bit(3)
+#define EXEC_SPINDLE_OVR_FINE_MINUS    bit(4)
+#define EXEC_SPINDLE_OVR_STOP          bit(5)
+#define EXEC_COOLANT_FLOOD_OVR_TOGGLE  bit(6)
+#define EXEC_COOLANT_MIST_OVR_TOGGLE   bit(7)
+
+// Define system state bit map. The state variable primarily tracks the individual functions
+// of Grbl to manage each without overlapping. It is also used as a messaging flag for
+// critical events.
+#define STATE_IDLE          0      // Must be zero. No flags.
+#define STATE_ALARM         bit(0) // In alarm state. Locks out all g-code processes. Allows settings access.
+#define STATE_CHECK_MODE    bit(1) // G-code check mode. Locks out planner and motion only.
+#define STATE_HOMING        bit(2) // Performing homing cycle
+#define STATE_CYCLE         bit(3) // Cycle is running or motions are being executed.
+#define STATE_HOLD          bit(4) // Active feed hold
+#define STATE_JOG           bit(5) // Jogging mode.
+#define STATE_SAFETY_DOOR   bit(6) // Safety door is ajar. Feed holds and de-energizes system.
+#define STATE_SLEEP         bit(7) // Sleep state.
+
+// Define system suspend flags. Used in various ways to manage suspend states and procedures.
+#define SUSPEND_DISABLE           0      // Must be zero.
+#define SUSPEND_HOLD_COMPLETE     bit(0) // Indicates initial feed hold is complete.
+#define SUSPEND_RESTART_RETRACT   bit(1) // Flag to indicate a retract from a restore parking motion.
+#define SUSPEND_RETRACT_COMPLETE  bit(2) // (Safety door only) Indicates retraction and de-energizing is complete.
+#define SUSPEND_INITIATE_RESTORE  bit(3) // (Safety door only) Flag to initiate resume procedures from a cycle start.
+#define SUSPEND_RESTORE_COMPLETE  bit(4) // (Safety door only) Indicates ready to resume normal operation.
+#define SUSPEND_SAFETY_DOOR_AJAR  bit(5) // Tracks safety door state for resuming.
+#define SUSPEND_MOTION_CANCEL     bit(6) // Indicates a canceled resume motion. Currently used by probing routine.
+#define SUSPEND_JOG_CANCEL        bit(7) // Indicates a jog cancel in process and to reset buffers when complete.
+
+// Define step segment generator state flags.
+#define STEP_CONTROL_NORMAL_OP            0  // Must be zero.
+#define STEP_CONTROL_END_MOTION           bit(0)
+#define STEP_CONTROL_EXECUTE_HOLD         bit(1)
+#define STEP_CONTROL_EXECUTE_SYS_MOTION   bit(2)
+#define STEP_CONTROL_UPDATE_SPINDLE_PWM   bit(3)
+
+// Define control pin index for Grbl internal use. Pin maps may change, but these values don't.
+#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+  #define N_CONTROL_PIN 4
+  #define CONTROL_PIN_INDEX_SAFETY_DOOR   bit(0)
+  #define CONTROL_PIN_INDEX_RESET         bit(1)
+  #define CONTROL_PIN_INDEX_FEED_HOLD     bit(2)
+  #define CONTROL_PIN_INDEX_CYCLE_START   bit(3)
+#else
+  #define N_CONTROL_PIN 3
+  #define CONTROL_PIN_INDEX_RESET         bit(0)
+  #define CONTROL_PIN_INDEX_FEED_HOLD     bit(1)
+  #define CONTROL_PIN_INDEX_CYCLE_START   bit(2)
+#endif
+
+// Define spindle stop override control states.
+#define SPINDLE_STOP_OVR_DISABLED       0  // Must be zero.
+#define SPINDLE_STOP_OVR_ENABLED        bit(0)
+#define SPINDLE_STOP_OVR_INITIATE       bit(1)
+#define SPINDLE_STOP_OVR_RESTORE        bit(2)
+#define SPINDLE_STOP_OVR_RESTORE_CYCLE  bit(3)
+
+
+// Define global system variables
+typedef struct {
+  uint8_t state;               // Tracks the current system state of Grbl.
+  uint8_t abort;               // System abort flag. Forces exit back to main loop for reset.             
+  uint8_t suspend;             // System suspend bitflag variable that manages holds, cancels, and safety door.
+  uint8_t soft_limit;          // Tracks soft limit errors for the state machine. (boolean)
+  uint8_t step_control;        // Governs the step segment generator depending on system state.
+  uint8_t probe_succeeded;     // Tracks if last probing cycle was successful.
+  uint8_t homing_axis_lock;    // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR.
+  uint8_t f_override;          // Feed rate override value in percent
+  uint8_t r_override;          // Rapids override value in percent
+  uint8_t spindle_speed_ovr;   // Spindle speed value in percent
+  uint8_t spindle_stop_ovr;    // Tracks spindle stop override states
+  uint8_t report_ovr_counter;  // Tracks when to add override data to status reports.
+  uint8_t report_wco_counter;  // Tracks when to add work coordinate offset data to status reports.
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		uint8_t override_ctrl;     // Tracks override control states.
+	#endif
+	#ifdef VARIABLE_SPINDLE
+    float spindle_speed;
+  #endif
+} system_t;
+extern system_t sys;
+
+// NOTE: These position variables may need to be declared as volatiles, if problems arise.
+extern int32_t sys_position[N_AXIS];      // Real-time machine (aka home) position vector in steps.
+extern int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
+
+extern volatile uint8_t sys_probe_state;   // Probing state value.  Used to coordinate the probing cycle with stepper ISR.
+extern volatile uint8_t sys_rt_exec_state;   // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
+extern volatile uint8_t sys_rt_exec_alarm;   // Global realtime executor bitflag variable for setting various alarms.
+extern volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
+extern volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
+
+#ifdef DEBUG
+  #define EXEC_DEBUG_REPORT  bit(0)
+	extern volatile uint8_t sys_rt_exec_debug;
+#endif
+
+// Initialize the serial protocol
+void system_init();
+
+// Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered).
+uint8_t system_control_get_state();
+
+// Returns if safety door is open or closed, based on pin state.
+uint8_t system_check_safety_door_ajar();
+
+// Executes an internal system command, defined as a string starting with a '$'
+uint8_t system_execute_line(char *line);
+
+// Execute the startup script lines stored in EEPROM upon initialization
+void system_execute_startup(char *line);
+
+
+void system_flag_wco_change();
+
+// Returns machine position of axis 'idx'. Must be sent a 'step' array.
+float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
+
+// Updates a machine 'position' array based on the 'step' array sent.
+void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
+
+// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
+#ifdef COREXY
+  int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
+  int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
+#endif
+
+// Checks and reports if target array exceeds machine travel limits.
+uint8_t system_check_travel_limits(float *target);
+
+// Special handlers for setting and clearing Grbl's real-time execution flags.
+void system_set_exec_state_flag(uint8_t mask);
+void system_clear_exec_state_flag(uint8_t mask);
+void system_set_exec_alarm(uint8_t code);
+void system_clear_exec_alarm();
+void system_set_exec_motion_override_flag(uint8_t mask);
+void system_set_exec_accessory_override_flag(uint8_t mask);
+void system_clear_exec_motion_overrides();
+void system_clear_exec_accessory_overrides();
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grbl/system.h.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,208 @@
+/*
+  system.h - Header for system level commands and real-time processes
+  Part of Grbl
+
+  Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
+
+  Grbl is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  Grbl is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef system_h
+#define system_h
+
+#include "grbl.h"
+
+// Define system executor bit map. Used internally by realtime protocol as realtime command flags,
+// which notifies the main program to execute the specified realtime command asynchronously.
+// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default
+// flags are always false, so the realtime protocol only needs to check for a non-zero value to
+// know when there is a realtime command to execute.
+#define EXEC_STATUS_REPORT  bit(0) // bitmask 00000001
+#define EXEC_CYCLE_START    bit(1) // bitmask 00000010
+#define EXEC_CYCLE_STOP     bit(2) // bitmask 00000100
+#define EXEC_FEED_HOLD      bit(3) // bitmask 00001000
+#define EXEC_RESET          bit(4) // bitmask 00010000
+#define EXEC_SAFETY_DOOR    bit(5) // bitmask 00100000
+#define EXEC_MOTION_CANCEL  bit(6) // bitmask 01000000
+#define EXEC_SLEEP          bit(7) // bitmask 10000000
+
+// Alarm executor codes. Valid values (1-255). Zero is reserved.
+#define EXEC_ALARM_HARD_LIMIT           1
+#define EXEC_ALARM_SOFT_LIMIT           2
+#define EXEC_ALARM_ABORT_CYCLE          3
+#define EXEC_ALARM_PROBE_FAIL_INITIAL   4
+#define EXEC_ALARM_PROBE_FAIL_CONTACT   5
+#define EXEC_ALARM_HOMING_FAIL_RESET    6
+#define EXEC_ALARM_HOMING_FAIL_DOOR     7
+#define EXEC_ALARM_HOMING_FAIL_PULLOFF  8
+#define EXEC_ALARM_HOMING_FAIL_APPROACH 9
+
+// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides.
+// Spindle/coolant and feed/rapids are separated into two controlling flag variables.
+#define EXEC_FEED_OVR_RESET         bit(0)
+#define EXEC_FEED_OVR_COARSE_PLUS   bit(1)
+#define EXEC_FEED_OVR_COARSE_MINUS  bit(2)
+#define EXEC_FEED_OVR_FINE_PLUS     bit(3)
+#define EXEC_FEED_OVR_FINE_MINUS    bit(4)
+#define EXEC_RAPID_OVR_RESET        bit(5)
+#define EXEC_RAPID_OVR_MEDIUM       bit(6)
+#define EXEC_RAPID_OVR_LOW          bit(7)
+// #define EXEC_RAPID_OVR_EXTRA_LOW   bit(*) // *NOT SUPPORTED*
+
+#define EXEC_SPINDLE_OVR_RESET         bit(0)
+#define EXEC_SPINDLE_OVR_COARSE_PLUS   bit(1)
+#define EXEC_SPINDLE_OVR_COARSE_MINUS  bit(2)
+#define EXEC_SPINDLE_OVR_FINE_PLUS     bit(3)
+#define EXEC_SPINDLE_OVR_FINE_MINUS    bit(4)
+#define EXEC_SPINDLE_OVR_STOP          bit(5)
+#define EXEC_COOLANT_FLOOD_OVR_TOGGLE  bit(6)
+#define EXEC_COOLANT_MIST_OVR_TOGGLE   bit(7)
+
+// Define system state bit map. The state variable primarily tracks the individual functions
+// of Grbl to manage each without overlapping. It is also used as a messaging flag for
+// critical events.
+#define STATE_IDLE          0      // Must be zero. No flags.
+#define STATE_ALARM         bit(0) // In alarm state. Locks out all g-code processes. Allows settings access.
+#define STATE_CHECK_MODE    bit(1) // G-code check mode. Locks out planner and motion only.
+#define STATE_HOMING        bit(2) // Performing homing cycle
+#define STATE_CYCLE         bit(3) // Cycle is running or motions are being executed.
+#define STATE_HOLD          bit(4) // Active feed hold
+#define STATE_JOG           bit(5) // Jogging mode.
+#define STATE_SAFETY_DOOR   bit(6) // Safety door is ajar. Feed holds and de-energizes system.
+#define STATE_SLEEP         bit(7) // Sleep state.
+
+// Define system suspend flags. Used in various ways to manage suspend states and procedures.
+#define SUSPEND_DISABLE           0      // Must be zero.
+#define SUSPEND_HOLD_COMPLETE     bit(0) // Indicates initial feed hold is complete.
+#define SUSPEND_RESTART_RETRACT   bit(1) // Flag to indicate a retract from a restore parking motion.
+#define SUSPEND_RETRACT_COMPLETE  bit(2) // (Safety door only) Indicates retraction and de-energizing is complete.
+#define SUSPEND_INITIATE_RESTORE  bit(3) // (Safety door only) Flag to initiate resume procedures from a cycle start.
+#define SUSPEND_RESTORE_COMPLETE  bit(4) // (Safety door only) Indicates ready to resume normal operation.
+#define SUSPEND_SAFETY_DOOR_AJAR  bit(5) // Tracks safety door state for resuming.
+#define SUSPEND_MOTION_CANCEL     bit(6) // Indicates a canceled resume motion. Currently used by probing routine.
+#define SUSPEND_JOG_CANCEL        bit(7) // Indicates a jog cancel in process and to reset buffers when complete.
+
+// Define step segment generator state flags.
+#define STEP_CONTROL_NORMAL_OP            0  // Must be zero.
+#define STEP_CONTROL_END_MOTION           bit(0)
+#define STEP_CONTROL_EXECUTE_HOLD         bit(1)
+#define STEP_CONTROL_EXECUTE_SYS_MOTION   bit(2)
+#define STEP_CONTROL_UPDATE_SPINDLE_PWM   bit(3)
+
+// Define control pin index for Grbl internal use. Pin maps may change, but these values don't.
+#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
+  #define N_CONTROL_PIN 4
+  #define CONTROL_PIN_INDEX_SAFETY_DOOR   bit(0)
+  #define CONTROL_PIN_INDEX_RESET         bit(1)
+  #define CONTROL_PIN_INDEX_FEED_HOLD     bit(2)
+  #define CONTROL_PIN_INDEX_CYCLE_START   bit(3)
+#else
+  #define N_CONTROL_PIN 3
+  #define CONTROL_PIN_INDEX_RESET         bit(0)
+  #define CONTROL_PIN_INDEX_FEED_HOLD     bit(1)
+  #define CONTROL_PIN_INDEX_CYCLE_START   bit(2)
+#endif
+
+// Define spindle stop override control states.
+#define SPINDLE_STOP_OVR_DISABLED       0  // Must be zero.
+#define SPINDLE_STOP_OVR_ENABLED        bit(0)
+#define SPINDLE_STOP_OVR_INITIATE       bit(1)
+#define SPINDLE_STOP_OVR_RESTORE        bit(2)
+#define SPINDLE_STOP_OVR_RESTORE_CYCLE  bit(3)
+
+
+// Define global system variables
+typedef struct {
+  uint8_t state;               // Tracks the current system state of Grbl.
+  uint8_t abort;               // System abort flag. Forces exit back to main loop for reset.             
+  uint8_t suspend;             // System suspend bitflag variable that manages holds, cancels, and safety door.
+  uint8_t soft_limit;          // Tracks soft limit errors for the state machine. (boolean)
+  uint8_t step_control;        // Governs the step segment generator depending on system state.
+  uint8_t probe_succeeded;     // Tracks if last probing cycle was successful.
+  uint8_t homing_axis_lock;    // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR.
+  uint8_t f_override;          // Feed rate override value in percent
+  uint8_t r_override;          // Rapids override value in percent
+  uint8_t spindle_speed_ovr;   // Spindle speed value in percent
+  uint8_t spindle_stop_ovr;    // Tracks spindle stop override states
+  uint8_t report_ovr_counter;  // Tracks when to add override data to status reports.
+  uint8_t report_wco_counter;  // Tracks when to add work coordinate offset data to status reports.
+	#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
+		uint8_t override_ctrl;     // Tracks override control states.
+	#endif
+	#ifdef VARIABLE_SPINDLE
+    float spindle_speed;
+  #endif
+} system_t;
+extern system_t sys;
+
+// NOTE: These position variables may need to be declared as volatiles, if problems arise.
+extern int32_t sys_position[N_AXIS];      // Real-time machine (aka home) position vector in steps.
+extern int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
+
+extern volatile uint8_t sys_probe_state;   // Probing state value.  Used to coordinate the probing cycle with stepper ISR.
+extern volatile uint8_t sys_rt_exec_state;   // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
+extern volatile uint8_t sys_rt_exec_alarm;   // Global realtime executor bitflag variable for setting various alarms.
+extern volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
+extern volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
+
+#ifdef DEBUG
+  #define EXEC_DEBUG_REPORT  bit(0)
+	extern volatile uint8_t sys_rt_exec_debug; 
+#endif
+
+// Initialize the serial protocol
+void system_init();
+
+// Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered).
+uint8_t system_control_get_state();
+
+// Returns if safety door is open or closed, based on pin state.
+uint8_t system_check_safety_door_ajar();
+
+// Executes an internal system command, defined as a string starting with a '$'
+uint8_t system_execute_line(char *line);
+
+// Execute the startup script lines stored in EEPROM upon initialization
+void system_execute_startup(char *line);
+
+
+void system_flag_wco_change();
+
+// Returns machine position of axis 'idx'. Must be sent a 'step' array.
+float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
+
+// Updates a machine 'position' array based on the 'step' array sent.
+void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
+
+// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
+#ifdef COREXY
+  int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
+  int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
+#endif
+
+// Checks and reports if target array exceeds machine travel limits.
+uint8_t system_check_travel_limits(float *target);
+
+// Special handlers for setting and clearing Grbl's real-time execution flags.
+void system_set_exec_state_flag(uint8_t mask);
+void system_clear_exec_state_flag(uint8_t mask);
+void system_set_exec_alarm(uint8_t code);
+void system_clear_exec_alarm();
+void system_set_exec_motion_override_flag(uint8_t mask);
+void system_set_exec_accessory_override_flag(uint8_t mask);
+void system_clear_exec_motion_overrides();
+void system_clear_exec_accessory_overrides();
+
+
+#endif
Binary file grblwin/.vs/grblwin/v14/.suo has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grblwin/ReadMe.txt	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,40 @@
+========================================================================
+    CONSOLE APPLICATION : grblwin Project Overview
+========================================================================
+
+AppWizard has created this grblwin application for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your grblwin application.
+
+
+grblwin.vcxproj
+    This is the main project file for VC++ projects generated using an Application Wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+grblwin.vcxproj.filters
+    This is the filters file for VC++ projects generated using an Application Wizard. 
+    It contains information about the association between the files in your project 
+    and the filters. This association is used in the IDE to show grouping of files with
+    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+    "Source Files" filter).
+
+grblwin.cpp
+    This is the main application source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named grblwin.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
Binary file grblwin/eeprom.bin has changed
Binary file grblwin/grblwin.VC.db has changed
Binary file grblwin/grblwin.sdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grblwin/grblwin.sln	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grblwin", "grblwin.vcxproj", "{8785D33C-F44C-44FA-9A16-0C93B895F459}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8785D33C-F44C-44FA-9A16-0C93B895F459}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8785D33C-F44C-44FA-9A16-0C93B895F459}.Debug|Win32.Build.0 = Debug|Win32
+		{8785D33C-F44C-44FA-9A16-0C93B895F459}.Release|Win32.ActiveCfg = Release|Win32
+		{8785D33C-F44C-44FA-9A16-0C93B895F459}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Binary file grblwin/grblwin.suo has changed
Binary file grblwin/grblwin.v12.suo has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grblwin/grblwin.vcxproj	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8785D33C-F44C-44FA-9A16-0C93B895F459}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>grblwin</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>j:\buildoutput\grblwin11\Debug\</OutDir>
+    <IntDir>$(OutDir)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>j:\buildoutput\grblwin11\Release\</OutDir>
+    <IntDir>$(OutDir)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\grbl\config.h" />
+    <ClInclude Include="..\grbl\coolant_control.h" />
+    <ClInclude Include="..\grbl\cpu_map.h" />
+    <ClInclude Include="..\grbl\defaults.h" />
+    <ClInclude Include="..\grbl\eeprom.h" />
+    <ClInclude Include="..\grbl\gcode.h" />
+    <ClInclude Include="..\grbl\grbl.h" />
+    <ClInclude Include="..\grbl\jog.h" />
+    <ClInclude Include="..\grbl\limits.h" />
+    <ClInclude Include="..\grbl\motion_control.h" />
+    <ClInclude Include="..\grbl\nuts_bolts.h" />
+    <ClInclude Include="..\grbl\planner.h" />
+    <ClInclude Include="..\grbl\print.h" />
+    <ClInclude Include="..\grbl\probe.h" />
+    <ClInclude Include="..\grbl\protocol.h" />
+    <ClInclude Include="..\grbl\report.h" />
+    <ClInclude Include="..\grbl\serial.h" />
+    <ClInclude Include="..\grbl\settings.h" />
+    <ClInclude Include="..\grbl\spindle_control.h" />
+    <ClInclude Include="..\grbl\stepper.h" />
+    <ClInclude Include="..\grbl\system.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\grbl\coolant_control.c" />
+    <ClCompile Include="..\grbl\eeprom.c" />
+    <ClCompile Include="..\grbl\gcode.c" />
+    <ClCompile Include="..\grbl\jog.c" />
+    <ClCompile Include="..\grbl\limits.c" />
+    <ClCompile Include="..\grbl\main.c" />
+    <ClCompile Include="..\grbl\motion_control.c" />
+    <ClCompile Include="..\grbl\nuts_bolts.c" />
+    <ClCompile Include="..\grbl\planner.c" />
+    <ClCompile Include="..\grbl\print.c" />
+    <ClCompile Include="..\grbl\probe.c" />
+    <ClCompile Include="..\grbl\protocol.c" />
+    <ClCompile Include="..\grbl\report.c" />
+    <ClCompile Include="..\grbl\serial.c" />
+    <ClCompile Include="..\grbl\settings.c" />
+    <ClCompile Include="..\grbl\spindle_control.c" />
+    <ClCompile Include="..\grbl\stepper.c" />
+    <ClCompile Include="..\grbl\system.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grblwin/grblwin.vcxproj.filters	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\grbl\config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\coolant_control.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\cpu_map.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\defaults.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\eeprom.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\gcode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\grbl.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\jog.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\limits.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\motion_control.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\nuts_bolts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\planner.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\print.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\probe.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\protocol.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\report.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\serial.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\settings.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\spindle_control.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\stepper.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\grbl\system.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\grbl\coolant_control.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\eeprom.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\gcode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\jog.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\limits.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\main.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\motion_control.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\nuts_bolts.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\planner.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\print.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\probe.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\protocol.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\report.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\serial.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\settings.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\spindle_control.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\stepper.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\grbl\system.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grblwin/grblwin.vcxproj.user	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommandArguments>COM4</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
Binary file grblwin/ipch/grblwin-905085aa/grblwin-3bc7f0ad.ipch has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32grbl.cogui	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workbench version="2.0">
+<workbenchAdvisor/>
+<window>
+<fastViewData fastViewLocation="1024"/>
+<perspectiveBar/>
+<page focus="true" label="Workspace - CooCox CoBuilder">
+<editors>
+<editorArea activeWorkbook="DefaultEditorWorkbook">
+<info part="DefaultEditorWorkbook">
+<folder appearance="1" expanded="2">
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+<part id="1"/>
+<part id="2"/>
+<part id="3"/>
+<part id="4"/>
+<part id="5"/>
+<part id="6"/>
+<part id="7"/>
+</presentation>
+</folder>
+</info>
+</editorArea>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="spindle_control.c" partName="spindle_control.c" path="J:/github/grbl/grbl/spindle_control.c" title="spindle_control.c" tooltip="J:/github/grbl/grbl/spindle_control.c" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/stm32grbl/grbl/src/spindle_control.c"/>
+<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="6198" selectionTopPixel="1924"/>
+</editor>
+<editor activePart="true" focus="true" id="org.coocox.builder.ui.editors.ConfigEditor" name="" partName="Configuration" title="Configuration" tooltip="" workbook="DefaultEditorWorkbook">
+<input factoryID="org.coocox.builder.ui.persistent.PersistentElementFactory">
+<org.coocox.builder.ui.editors.ConfigEditor horizontalPosition="0" subTagIndex="0" verticalPosition="0"/>
+</input>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="cpu_map.h" partName="cpu_map.h" title="cpu_map.h" tooltip="E:\usbjtagproj\Code\grbl1.1\grbl-edgestm32\grbl\cpu_map.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.ide.FileStoreEditorInputFactory" uri="file:/E:/usbjtagproj/Code/grbl1.1/grbl-edgestm32/grbl/cpu_map.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="21" selectionOffset="17467" selectionTopPixel="6307"/>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="grbl.h" partName="grbl.h" path="J:/github/grbl/grbl/grbl.h" title="grbl.h" tooltip="J:/github/grbl/grbl/grbl.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/stm32grbl/grbl/inc/grbl.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="11" selectionOffset="892" selectionTopPixel="90"/>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="config.h" partName="config.h" path="J:/github/grbl/grbl/config.h" title="config.h" tooltip="J:/github/grbl/grbl/config.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/stm32grbl/grbl/inc/config.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="8" selectionOffset="19768" selectionTopPixel="5032"/>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="cpu_map.h" partName="cpu_map.h" title="cpu_map.h" tooltip="J:\github\grbl\grbl\cpu_map.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.ide.FileStoreEditorInputFactory" uri="file:/J:/github/grbl/grbl/cpu_map.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="0" selectionTopPixel="6245"/>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="stm32f10x_exti.h" partName="stm32f10x_exti.h" path="J:/github/grbl/stm_lib/inc/stm32f10x_exti.h" title="stm32f10x_exti.h" tooltip="J:/github/grbl/stm_lib/inc/stm32f10x_exti.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/stm32grbl/stm_lib/inc/stm32f10x_exti.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="0" selectionTopPixel="0"/>
+</editor>
+<editor id="org.eclipse.cdt.ui.editor.CEditor" name="spindle_control.h" partName="spindle_control.h" path="J:/github/grbl/grbl/spindle_control.h" title="spindle_control.h" tooltip="J:/github/grbl/grbl/spindle_control.h" workbook="DefaultEditorWorkbook">
+<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/stm32grbl/grbl/inc/spindle_control.h"/>
+<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="0" selectionTopPixel="0"/>
+</editor>
+</editors>
+<views>
+<view id="org.coocox.builder.ui.views.ProjectView" partName="Project">
+<viewState CommonNavigator.LINKING_ENABLED="0" horizontalPosition="0" org.eclipse.ui.navigator.resources.workingSets.showTopLevelWorkingSets="0" verticalPosition="0">
+<expanded>
+<element path="/stm32grbl"/>
+<element path="/stm32grbl/grbl"/>
+<element path="/stm32grbl/grbl/inc"/>
+<element path="/stm32grbl/util"/>
+</expanded>
+<selection>
+<element path="/stm32grbl"/>
+</selection>
+</viewState>
+</view>
+<view id="org.coocox.codebugger.trace.ui.traceview" partName="Semihosting">
+<viewState/>
+</view>
+<view id="org.eclipse.debug.ui.DebugView" partName="Debug"/>
+<view id="org.eclipse.ui.console.ConsoleView" partName="Console">
+<viewState/>
+</view>
+<view id="org.eclipse.debug.ui.VariableView" partName="Variables"/>
+</views>
+<perspectives activePart="org.coocox.builder.ui.editors.ConfigEditor" activePerspective="org.coocox.builder.perspective.CoBuilder">
+<perspective editorAreaTrimState="2" editorAreaVisible="1" fixed="0" version="0.016">
+<descriptor class="org.coocox.builder.ui.PerspectiveCoBuilder" id="org.coocox.builder.perspective.CoBuilder" label="CooCox CoBuilder"/>
+<alwaysOnActionSet id="org.coocox.welcome.ui.actionSet"/>
+<alwaysOnActionSet id="org.eclipse.search.searchActionSet"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.annotationNavigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.navigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.keyBindings"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.openFiles"/>
+<alwaysOnActionSet id="org.eclipse.debug.ui.breakpointActionSet"/>
+<alwaysOnActionSet id="org.coocox.userspace.actionSet"/>
+<alwaysOnActionSet id="org.coocox.component.ui.actionSet"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showMemoryAction"/>
+<hide_menu_item_id id="org.eclipse.jdt.ui.refactoring.menu"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.ShowDisassemblyAction"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showExpressionsAction"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showDebugAction"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showConsoleAction"/>
+<hide_menu_item_id id="org.eclipse.cdt.debug.internal.ui.actions.ToggleInstructionStepModeAction"/>
+<hide_menu_item_id id="org.eclipse.jdt.ui.source.menu"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showMemoryBrowserAction"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showVariablesAction"/>
+<hide_menu_item_id id="org.coocox.builder.ui.openProjectExplorerAction"/>
+<hide_menu_item_id id="org.coocox.codebugger.trace.actions.ShowTraceControlAction"/>
+<hide_menu_item_id id="org.eclipse.debug.ui.commands.TerminateAndRelaunch"/>
+<hide_menu_item_id id="org.coocox.codebugger.configuration.showRegistersAction"/>
+<hide_toolbar_item_id id="org.eclipse.cdt.debug.internal.ui.actions.ToggleInstructionStepModeAction"/>
+<hide_toolbar_item_id id="org.eclipse.ui.edit.text.toggleShowSelectedElementOnly"/>
+<hide_toolbar_item_id id="org.eclipse.debug.ui.commands.TerminateAndRelaunch"/>
+<view id="org.coocox.builder.ui.views.ProjectView"/>
+<view id="org.eclipse.ui.console.ConsoleView"/>
+<fastViewBars/>
+<layout>
+<mainWindow>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@d8749">
+<folder activePageID="org.coocox.component.ui.ComponentView" appearance="2" expanded="2">
+<page content="org.coocox.component.ui.ComponentView" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="stickyFolderRight" ratio="0.75" ratioLeft="1434" ratioRight="478" relationship="2" relative="org.eclipse.ui.internal.ViewStack@d8749">
+<folder appearance="2" expanded="2">
+<page content="org.eclipse.help.ui.HelpView" label="LabelNotFound"/>
+<page content="org.eclipse.ui.internal.introview" label="LabelNotFound"/>
+</folder>
+</info>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@66a7f5" ratio="0.771855" ratioLeft="724" ratioRight="214" relationship="4" relative="org.eclipse.ui.internal.ViewStack@d8749">
+<folder activePageID="org.eclipse.ui.console.ConsoleView" appearance="2" expanded="2">
+<page content="org.eclipse.ui.console.ConsoleView" label="Console"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info part="org.coocox.builder.ui.exampleView" ratio="0.19591409" ratioLeft="374" ratioRight="1535" relationship="2" relative="org.eclipse.ui.internal.ViewStack@d8749"/>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@f0921d" ratio="0.71983916" ratioLeft="1074" ratioRight="418" relationship="2" relative="org.coocox.builder.ui.exampleView">
+<folder activePageID="org.coocox.component.ui.Help" appearance="2" expanded="2">
+<page content="org.coocox.component.ui.Help" label="LabelNotFound"/>
+<page content="org.eclipse.debug.ui.BreakpointView" label="LabelNotFound"/>
+<page content="org.eclipse.ui.views.ContentOutline" label="LabelNotFound"/>
+<page content="org.coocox.coassistant.view.CoAssistantView" label="LabelNotFound"/>
+<page content="org.coocox.builder.ui.MoreExampleView" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info part="org.eclipse.ui.editorss" ratio="0.44952178" ratioLeft="423" ratioRight="518" relationship="4" relative="org.coocox.builder.ui.exampleView"/>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@2cf2ae" ratio="0.36981934" ratioLeft="348" ratioRight="593" relationship="4" relative="org.eclipse.ui.internal.ViewStack@d8749">
+<folder activePageID="org.coocox.builder.ui.views.ProjectView" appearance="2" expanded="2">
+<page content="org.coocox.builder.ui.views.ProjectView" label="Project"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+</mainWindow>
+</layout>
+</perspective>
+<perspective editorAreaTrimState="2" editorAreaVisible="1" fixed="0" version="0.016">
+<descriptor class="org.coocox.codebugger.configuration.ui.Perspective" id="org.coocox.codebugger.configuration.perspective" label="CoDebugger"/>
+<alwaysOnActionSet id="org.coocox.component.ui.actionSet"/>
+<alwaysOnActionSet id="org.coocox.welcome.ui.actionSet"/>
+<alwaysOnActionSet id="org.eclipse.search.searchActionSet"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.annotationNavigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.navigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.keyBindings"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.openFiles"/>
+<alwaysOnActionSet id="org.eclipse.debug.ui.breakpointActionSet"/>
+<alwaysOnActionSet id="org.eclipse.debug.ui.debugActionSet"/>
+<hide_menu_item_id id="org.coocox.builder.ui.newFile"/>
+<hide_menu_item_id id="org.coocox.builder.ui.newFolder"/>
+<hide_menu_item_id id="org.coocox.builder.ui.openFile"/>
+<hide_menu_item_id id="org.eclipse.ui.file.save"/>
+<hide_menu_item_id id="org.eclipse.ui.file.saveAs"/>
+<hide_menu_item_id id="org.eclipse.ui.file.saveAll"/>
+<hide_menu_item_id id="org.coocox.builder.rcp.projectMenu"/>
+<hide_menu_item_id id="org.coocox.builder.rcp.flashMenu"/>
+<hide_menu_item_id id="org.coocox.builder.ui.showHelpViewAction"/>
+<hide_menu_item_id id="org.coocox.component.ui.ShowRepositoryAction"/>
+<hide_menu_item_id id="org.coocox.builder.ui.debug"/>
+<hide_menu_item_id id="org.coocox.builder.ui.build"/>
+<hide_menu_item_id id="org.coocox.builder.ui.rebuild"/>
+<hide_menu_item_id id="org.eclipse.jdt.ui.refactoring.menu"/>
+<hide_menu_item_id id="org.eclipse.jdt.ui.source.menu"/>
+<hide_menu_item_id id="org.coocox.builder.ui.actions.ConfigurationAction"/>
+<hide_menu_item_id id="org.coocox.welcome.ui.action.welcome"/>
+<hide_menu_item_id id="org.coocox.welcome.ui.action.repository"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.newProject"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.newFile"/>
+<hide_toolbar_item_id id="org.eclipse.ui.file.save"/>
+<hide_toolbar_item_id id="org.coocox.component.ui.ShowRepositoryAction"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.build"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.rebuild"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.debug"/>
+<hide_toolbar_item_id id="org.coocox.codebugger.configuration.coideProgramDownloadAction"/>
+<hide_toolbar_item_id id="org.coocox.codebugger.configuration.coideFlashEraseAction"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.actions.TargetManageAction"/>
+<hide_toolbar_item_id id="org.coocox.builder.ui.actions.ConfigurationAction"/>
+<hide_toolbar_item_id id="org.coocox.welcome.ui.action.welcome"/>
+<hide_toolbar_item_id id="org.coocox.welcome.ui.action.repository"/>
+<hide_toolbar_item_id id="org.eclipse.ui.edit.text.toggleShowSelectedElementOnly"/>
+<view id="org.eclipse.ui.console.ConsoleView"/>
+<view id="org.eclipse.debug.ui.DebugView"/>
+<view id="org.coocox.codebugger.trace.ui.traceview"/>
+<view id="org.eclipse.debug.ui.VariableView"/>
+<view id="org.coocox.builder.ui.views.ProjectView"/>
+<fastViewBars/>
+<viewLayoutRec closeable="false" id="org.eclipse.debug.ui.DebugView"/>
+<layout>&#x0A;<mainWindow>&#x0A;<info folder="true" part="org.eclipse.ui.internal.ViewStack@44c832">&#x0A;<folder activePageID="org.coocox.builder.ui.views.ProjectView" appearance="2" expanded="2">&#x0A;<page content="org.coocox.builder.ui.views.ProjectView" label="Project"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">&#x0A;<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="stickyFolderRight" ratio="0.75" ratioLeft="1434" ratioRight="478" relationship="2" relative="org.eclipse.ui.internal.ViewStack@44c832">&#x0A;<folder appearance="2" expanded="2">&#x0A;<page content="org.eclipse.help.ui.HelpView" label="LabelNotFound"/>
+<page content="org.eclipse.ui.internal.introview" label="LabelNotFound"/>
+</folder>
+</info>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@78c1cc" ratio="0.6993402" ratioLeft="742" ratioRight="319" relationship="4" relative="org.eclipse.ui.internal.ViewStack@44c832">&#x0A;<folder activePageID="org.eclipse.ui.console.ConsoleView" appearance="2" expanded="2">&#x0A;<page content="org.eclipse.ui.console.ConsoleView" label="Console"/>
+<page content="org.eclipse.debug.ui.DebugView" label="Debug"/>
+<page content="org.eclipse.debug.ui.BreakpointView" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">&#x0A;<part id="0"/>
+<part id="1"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@1fb49c2" ratio="0.5" ratioLeft="956" ratioRight="956" relationship="2" relative="org.eclipse.ui.internal.ViewStack@78c1cc">&#x0A;<folder activePageID="org.coocox.codebugger.trace.ui.traceview" appearance="2" expanded="2">&#x0A;<page content="org.coocox.codebugger.trace.ui.traceview" label="Semihosting"/>
+<page content="org.eclipse.debug.ui.VariableView" label="Variables"/>
+<page content="org.eclipse.debug.ui.ExpressionView" label="LabelNotFound"/>
+<page content="org.eclipse.debug.ui.MemoryView" label="LabelNotFound"/>
+<page content="org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">&#x0A;<part id="0"/>
+<part id="1"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@a77309" ratio="0.75" ratioLeft="1434" ratioRight="478" relationship="2" relative="org.eclipse.ui.internal.ViewStack@44c832">&#x0A;<folder appearance="2" expanded="2">&#x0A;<page content="org.eclipse.cdt.dsf.debug.ui.disassembly.view" label="LabelNotFound"/>
+<page content="org.eclipse.ui.views.ContentOutline" label="LabelNotFound"/>
+<page content="org.eclipse.debug.ui.RegisterView" label="LabelNotFound"/>
+<page content="org.coocox.coassistant.view.CoAssistantView_debug" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory"/>
+</folder>
+</info>
+<info part="org.eclipse.ui.editorss" ratio="0.29986054" ratioLeft="430" ratioRight="1004" relationship="2" relative="org.eclipse.ui.internal.ViewStack@44c832"/>
+</mainWindow>
+</layout>
+</perspective>
+</perspectives>
+<workingSets/>
+<navigationHistory>
+<editors>
+<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" path="/stm32grbl/grbl/src/spindle_control.c"/>
+<editor factoryID="org.coocox.builder.ui.persistent.PersistentElementFactory" id="org.coocox.builder.ui.editors.ConfigEditor">
+<org.coocox.builder.ui.editors.ConfigEditor horizontalPosition="0" subTagIndex="0" verticalPosition="0"/>
+</editor>
+<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" path="/stm32grbl/stm_lib/inc/stm32f10x_exti.h"/>
+<editor factoryID="org.eclipse.ui.ide.FileStoreEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" uri="file:/J:/github/grbl/grbl/cpu_map.h"/>
+<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" path="/stm32grbl/grbl/inc/config.h"/>
+</editors>
+<item historyLabel="spindle_control.c" index="0">
+<position info="not_deleted" x="6198" y="0"/>
+</item>
+<item historyLabel="Configuration" index="1"/>
+<item historyLabel="stm32f10x_exti.h" index="2">
+<position info="not_deleted" x="0" y="0"/>
+</item>
+<item historyLabel="Configuration" index="1"/>
+<item historyLabel="cpu_map.h" index="3">
+<position info="not_deleted" x="0" y="0"/>
+</item>
+<item historyLabel="config.h" index="4">
+<position info="not_deleted" x="19768" y="8"/>
+</item>
+<item historyLabel="spindle_control.c" index="0">
+<position info="not_deleted" x="6198" y="0"/>
+</item>
+<item active="true" historyLabel="Configuration" index="1"/>
+</navigationHistory>
+<input factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/" type="8"/>
+</page>
+<workbenchWindowAdvisor/>
+<actionBarAdvisor/>
+</window>
+<mruList>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="protocol.c" tooltip="stm32grbl/grbl/src/protocol.c">
+<persistable path="/stm32grbl/grbl/src/protocol.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="usb_endp.c" tooltip="stm32grbl/usb/usb_endp.c">
+<persistable path="/stm32grbl/usb/usb_endp.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="coolant_control.h" tooltip="stm32grbl/grbl/inc/coolant_control.h">
+<persistable path="/stm32grbl/grbl/inc/coolant_control.h"/>
+</file>
+<file factoryID="org.coocox.component.ui.editors.repository.RepositoryElementFactory" id="org.coocox.builder.ui.editors.repository.RepositoryBrowser" name="Repository" tooltip="Repository">
+<persistable>&#x0A;<subPage/>
+</persistable>
+</file>
+<file factoryID="org.coocox.component.ui.editors.repository.RepositoryElementFactory" id="org.coocox.builder.ui.editors.repository.RepositoryBrowser" name="Repository" tooltip="Repository">
+<persistable>&#x0A;<subPage/>
+</persistable>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="motion_control.h" tooltip="stm32grbl/grbl/inc/motion_control.h">
+<persistable path="/stm32grbl/grbl/inc/motion_control.h"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="config.h" tooltip="stm32grbl/grbl/inc/config.h">
+<persistable path="/stm32grbl/grbl/inc/config.h"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="motion_control.c" tooltip="stm32grbl/grbl/src/motion_control.c">
+<persistable path="/stm32grbl/grbl/src/motion_control.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="stepper.c" tooltip="stm32grbl/grbl/src/stepper.c">
+<persistable path="/stm32grbl/grbl/src/stepper.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="main.c" tooltip="stm32grbl/main.c">
+<persistable path="/stm32grbl/main.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="eeprom.c" tooltip="stmf4grbl/grbl/eeprom.c">
+<persistable path="/stmf4grbl/grbl/eeprom.c"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="nuts_bolts.h" tooltip="stmf4grbl/grbl/nuts_bolts.h">
+<persistable path="/stmf4grbl/grbl/nuts_bolts.h"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="usbd_def.h" tooltip="stmf4grbl/Drivers/STM32_USB_Device_Library/Core/inc/usbd_def.h">
+<persistable path="/stmf4grbl/Drivers/STM32_USB_Device_Library/Core/inc/usbd_def.h"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="usb_core.h" tooltip="stmf4grbl/Drivers/STM32_USB_OTG_Driver/inc/usb_core.h">
+<persistable path="/stmf4grbl/Drivers/STM32_USB_OTG_Driver/inc/usb_core.h"/>
+</file>
+<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.cdt.ui.editor.CEditor" name="usb_endp.c" tooltip="stm32grbl/usb/usb_endp.c">
+<persistable path="/stm32grbl/usb/usb_endp.c"/>
+</file>
+</mruList>
+</workbench>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32grbl.comarker	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<breakpoints/>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32grbl11.coproj	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Project version="2G - 2.0.6" name="stm32grbl">
+  <Target name="stm32grbl" isCurrent="1">
+    <Device manufacturerId="9" manufacturerName="ST" chipId="599" chipName="STM32F103C8T6" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
+    <BuildOption>
+      <Compile>
+        <Option name="OptimizationLevel" value="4"/>
+        <Option name="UseFPU" value="0"/>
+        <Option name="UserEditCompiler" value="-ffunction-sections;"/>
+        <Option name="SupportCPlusplus" value="0"/>
+        <Option name="DEBUG" value="0"/>
+        <Option name="WARNING" value="0"/>
+        <Includepaths>
+          <Includepath path="."/>
+          <Includepath path="usb"/>
+          <Includepath path="util"/>
+          <Includepath path="useusb"/>
+          <Includepath path="grbl"/>
+        </Includepaths>
+        <DefinedSymbols>
+          <Define name="USE_STDPERIPH_DRIVER"/>
+          <Define name="__ASSEMBLY__"/>
+          <Define name="_GRBL_"/>
+          <Define name="STM32F103C8T6"/>
+          <Define name="STM32F10X_MD"/>
+          <Define name="LEDBLINK"/>
+          <Define name="USEUSB"/>
+          <Define name="STM32F103C8"/>
+        </DefinedSymbols>
+      </Compile>
+      <Link useDefault="0">
+        <Option name="DiscardUnusedSection" value="0"/>
+        <Option name="UserEditLinkder" value=""/>
+        <Option name="UseMemoryLayout" value="1"/>
+        <Option name="nostartfiles" value="1"/>
+        <Option name="LTO" value="0"/>
+        <Option name="IsNewStartupCode" value="1"/>
+        <Option name="Library" value="Not use C Library"/>
+        <Option name="UserEditLinker" value=""/>
+        <LinkedLibraries>
+          <Libset dir="" libs="m"/>
+        </LinkedLibraries>
+        <MemoryAreas debugInFlashNotRAM="1">
+          <Memory name="IROM1" type="ReadOnly" size="0x00020000" startValue="0x08000000"/>
+          <Memory name="IRAM1" type="ReadWrite" size="0x00005000" startValue="0x20000000"/>
+          <Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
+          <Memory name="IRAM2" type="ReadWrite" size="" startValue=""/>
+        </MemoryAreas>
+        <LocateLinkFile path="c:/users/li shao/appdata/roaming/coocox/coide/configuration/programdata/stm32grbl/arm-gcc-link.ld" type="0"/>
+      </Link>
+      <Output>
+        <Option name="OutputFileType" value="0"/>
+        <Option name="Path" value="../../buildoutput/grbl11e/"/>
+        <Option name="Name" value="stm32grbl"/>
+        <Option name="HEX" value="1"/>
+        <Option name="BIN" value="1"/>
+      </Output>
+      <User>
+        <UserRun name="Run#1" type="Before" checked="0" value=""/>
+        <UserRun name="Run#1" type="After" checked="0" value=""/>
+      </User>
+    </BuildOption>
+    <DebugOption>
+      <Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="2M"/>
+      <Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="d:/coocox/coide/flash/stm32f10x_md_64.elf;"/>
+      <Option name="org.coocox.codebugger.gdbjtag.coredebugInRamInitCommands" value="cd j:/buildoutput/stm3211/stm32grbl/Debug/bin restore stm32grbl.elf set {unsigned int*}0xE000ED08 = 0x20000000 set $sp = {unsigned int*}0x20000000 set $pc = {unsigned int*}0x20000004 "/>
+    </DebugOption>
+    <ExcludeFile/>
+  </Target>
+  <Components path="./"/>
+  <LocalComponents/>
+  <Files>
+    <File name="stm_usb_fs_lib/inc/usb_init.h" path="stm_usb_fs_lib/inc/usb_init.h" type="1"/>
+    <File name="grbl/inc/probe.h" path="grbl/probe.h" type="1"/>
+    <File name="grbl" path="" type="2"/>
+    <File name="stm_usb_fs_lib/src" path="" type="2"/>
+    <File name="usb/usb_desc.c" path="usb/usb_desc.c" type="1"/>
+    <File name="grbl/src/stepper.c" path="grbl/stepper.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_core.h" path="stm_usb_fs_lib/inc/usb_core.h" type="1"/>
+    <File name="cmsis_boot" path="" type="2"/>
+    <File name="usb/hw_config.c" path="usb/hw_config.c" type="1"/>
+    <File name="grbl/inc/eeprom.h" path="grbl/eeprom.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_mem.h" path="stm_usb_fs_lib/inc/usb_mem.h" type="1"/>
+    <File name="grbl/inc/print.h" path="grbl/print.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_tim.c" path="stm_lib/src/stm32f10x_tim.c" type="1"/>
+    <File name="cmsis_boot/startup" path="" type="2"/>
+    <File name="stm_usb_fs_lib/inc/usb_regs.h" path="stm_usb_fs_lib/inc/usb_regs.h" type="1"/>
+    <File name="cmsis/core_cmFunc.h" path="cmsis/core_cmFunc.h" type="1"/>
+    <File name="grbl/inc/system.h" path="grbl/system.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_int.h" path="stm_usb_fs_lib/inc/usb_int.h" type="1"/>
+    <File name="stm_lib/src/misc.c" path="stm_lib/src/misc.c" type="1"/>
+    <File name="grbl/src/jog.c" path="grbl/jog.c" type="1"/>
+    <File name="cmsis_boot/stm32f10x.h" path="cmsis_boot/stm32f10x.h" type="1"/>
+    <File name="grbl/src/coolant_control.c" path="grbl/coolant_control.c" type="1"/>
+    <File name="cmsis_boot/stm32f10x_conf.h" path="cmsis_boot/stm32f10x_conf.h" type="1"/>
+    <File name="grbl/src/limits.c" path="grbl/limits.c" type="1"/>
+    <File name="grbl/src/serial.c" path="grbl/serial.c" type="1"/>
+    <File name="grbl/src/protocol.c" path="grbl/protocol.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_mem.c" path="stm_usb_fs_lib/src/usb_mem.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_spi.h" path="stm_lib/inc/stm32f10x_spi.h" type="1"/>
+    <File name="usb" path="" type="2"/>
+    <File name="grbl/src/probe.c" path="grbl/probe.c" type="1"/>
+    <File name="grbl/inc/planner.h" path="grbl/planner.h" type="1"/>
+    <File name="grbl/inc/stepper.h" path="grbl/stepper.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_usart.c" path="stm_lib/src/stm32f10x_usart.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_sil.c" path="stm_usb_fs_lib/src/usb_sil.c" type="1"/>
+    <File name="grbl/inc/spindle_control.h" path="grbl/spindle_control.h" type="1"/>
+    <File name="grbl/src/nuts_bolts.c" path="grbl/nuts_bolts.c" type="1"/>
+    <File name="cmsis_boot/startup/startup_stm32f10x_md.c" path="cmsis_boot/startup/startup_stm32f10x_md.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_gpio.c" path="stm_lib/src/stm32f10x_gpio.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_gpio.h" path="stm_lib/inc/stm32f10x_gpio.h" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_usart.h" path="stm_lib/inc/stm32f10x_usart.h" type="1"/>
+    <File name="grbl/inc/report.h" path="grbl/report.h" type="1"/>
+    <File name="grbl/inc/config.h" path="grbl/config.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_sil.h" path="stm_usb_fs_lib/inc/usb_sil.h" type="1"/>
+    <File name="cmsis_boot/system_stm32f10x.c" path="cmsis_boot/system_stm32f10x.c" type="1"/>
+    <File name="stm_lib/inc/misc.h" path="stm_lib/inc/misc.h" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_int.c" path="stm_usb_fs_lib/src/usb_int.c" type="1"/>
+    <File name="grbl/inc/gcode.h" path="grbl/gcode.h" type="1"/>
+    <File name="cmsis/core_cmInstr.h" path="cmsis/core_cmInstr.h" type="1"/>
+    <File name="util" path="" type="2"/>
+    <File name="grbl/src/spindle_control.c" path="grbl/spindle_control.c" type="1"/>
+    <File name="stm_usb_fs_lib" path="" type="2"/>
+    <File name="cmsis/core_cm3.h" path="cmsis/core_cm3.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc" path="" type="2"/>
+    <File name="grbl/src/sleep.c" path="grbl/sleep.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_exti.c" path="stm_lib/src/stm32f10x_exti.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_init.c" path="stm_usb_fs_lib/src/usb_init.c" type="1"/>
+    <File name="usb/usb_pwr.c" path="usb/usb_pwr.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_core.c" path="stm_usb_fs_lib/src/usb_core.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_rcc.c" path="stm_lib/src/stm32f10x_rcc.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_conf.h" path="stm_usb_fs_lib/inc/usb_conf.h" type="1"/>
+    <File name="grbl/src/gcode.c" path="grbl/gcode.c" type="1"/>
+    <File name="grbl/inc/limits.h" path="grbl/limits.h" type="1"/>
+    <File name="grbl/inc/serial.h" path="grbl/serial.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_def.h" path="stm_usb_fs_lib/inc/usb_def.h" type="1"/>
+    <File name="grbl/src/eeprom.c" path="grbl/eeprom.c" type="1"/>
+    <File name="usb/usb_prop.c" path="usb/usb_prop.c" type="1"/>
+    <File name="grbl/inc/coolant_control.h" path="grbl/coolant_control.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_type.h" path="stm_usb_fs_lib/inc/usb_type.h" type="1"/>
+    <File name="grbl/inc/protocol.h" path="grbl/protocol.h" type="1"/>
+    <File name="grbl/src" path="" type="2"/>
+    <File name="usb/usb_istr.c" path="usb/usb_istr.c" type="1"/>
+    <File name="stm_lib/src" path="" type="2"/>
+    <File name="grbl/inc/motion_control.h" path="grbl/motion_control.h" type="1"/>
+    <File name="cmsis" path="" type="2"/>
+    <File name="stm_lib" path="" type="2"/>
+    <File name="grbl/src/planner.c" path="grbl/planner.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_exti.h" path="stm_lib/inc/stm32f10x_exti.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_flash.c" path="stm_lib/src/stm32f10x_flash.c" type="1"/>
+    <File name="grbl/src/print.c" path="grbl/print.c" type="1"/>
+    <File name="usb/usb_endp.c" path="usb/usb_endp.c" type="1"/>
+    <File name="cmsis_boot/system_stm32f10x.h" path="cmsis_boot/system_stm32f10x.h" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_rcc.h" path="stm_lib/inc/stm32f10x_rcc.h" type="1"/>
+    <File name="grbl/inc" path="" type="2"/>
+    <File name="stm_usb_fs_lib/src/usb_regs.c" path="stm_usb_fs_lib/src/usb_regs.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_lib.h" path="stm_usb_fs_lib/inc/usb_lib.h" type="1"/>
+    <File name="grbl/inc/nuts_bolts.h" path="grbl/nuts_bolts.h" type="1"/>
+    <File name="grbl/inc/jog.h" path="grbl/jog.h" type="1"/>
+    <File name="grbl/src/settings.c" path="grbl/settings.c" type="1"/>
+    <File name="util/stm32f10x_it.c" path="util/stm32f10x_it.c" type="1"/>
+    <File name="grbl/src/report.c" path="grbl/report.c" type="1"/>
+    <File name="grbl/src/system.c" path="grbl/system.c" type="1"/>
+    <File name="grbl/inc/settings.h" path="grbl/settings.h" type="1"/>
+    <File name="stm_lib/inc" path="" type="2"/>
+    <File name="grbl/src/motion_control.c" path="grbl/motion_control.c" type="1"/>
+    <File name="grbl/inc/grbl.h" path="grbl/grbl.h" type="1"/>
+    <File name="main.c" path="grbl/main.c" type="1"/>
+  </Files>
+  <Bookmarks/>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32grbl11d.coproj	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Project version="2G - 1.7.8" name="stm32grbl">
+  <Target name="stm32grbl" isCurrent="1">
+    <Device manufacturerId="9" manufacturerName="ST" chipId="305" chipName="STM32F103C8" boardId="" boardName=""/>
+    <BuildOption>
+      <Compile>
+        <Option name="OptimizationLevel" value="4"/>
+        <Option name="UseFPU" value="0"/>
+        <Option name="UserEditCompiler" value=""/>
+        <Option name="SupportCPlusplus" value="0"/>
+        <Includepaths>
+          <Includepath path="."/>
+          <Includepath path="usb"/>
+          <Includepath path="util"/>
+          <Includepath path="useusb"/>
+          <Includepath path="grbl"/>
+        </Includepaths>
+        <DefinedSymbols>
+          <Define name="USE_STDPERIPH_DRIVER"/>
+          <Define name="__ASSEMBLY__"/>
+          <Define name="_GRBL_"/>
+          <Define name="STM32F103C8"/>
+          <Define name="STM32F10X_MD"/>
+          <Define name="LEDBLINK"/>
+          <Define name="USEUSB"/>
+        </DefinedSymbols>
+      </Compile>
+      <Link useDefault="0">
+        <Option name="DiscardUnusedSection" value="0"/>
+        <Option name="UserEditLinkder" value=""/>
+        <Option name="UseMemoryLayout" value="1"/>
+        <Option name="nostartfiles" value="1"/>
+        <Option name="LTO" value="0"/>
+        <Option name="IsNewStartupCode" value="1"/>
+        <Option name="Library" value="Not use C Library"/>
+        <Option name="UserEditLinker" value=""/>
+        <LinkedLibraries>
+          <Libset dir="" libs="m"/>
+        </LinkedLibraries>
+        <MemoryAreas debugInFlashNotRAM="1">
+          <Memory name="IROM1" type="ReadOnly" size="0x00020000" startValue="0x08000000"/>
+          <Memory name="IRAM1" type="ReadWrite" size="0x00005000" startValue="0x20000000"/>
+          <Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
+          <Memory name="IRAM2" type="ReadWrite" size="" startValue=""/>
+        </MemoryAreas>
+        <LocateLinkFile path="d:/coocox/coide/configuration/programdata/stm32grbl/arm-gcc-link.ld" type="0"/>
+      </Link>
+      <Output>
+        <Option name="OutputFileType" value="0"/>
+        <Option name="Path" value="j:/buildoutput/grbl11e/"/>
+        <Option name="Name" value="stm32grbl"/>
+        <Option name="HEX" value="1"/>
+        <Option name="BIN" value="1"/>
+      </Output>
+      <User>
+        <UserRun name="Run#1" type="Before" checked="0" value=""/>
+        <UserRun name="Run#1" type="After" checked="0" value=""/>
+      </User>
+    </BuildOption>
+    <DebugOption>
+      <Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="2M"/>
+      <Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
+      <Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="./stm32f10x_md_64.elf"/>
+      <Option name="org.coocox.codebugger.gdbjtag.coredebugInRamInitCommands" value="cd j:/buildoutput/stm3211d/stm32grbl/Debug/bin restore stm32grbl.elf set {unsigned int*}0xE000ED08 = 0x20000000 set $sp = {unsigned int*}0x20000000 set $pc = {unsigned int*}0x20000004 "/>
+    </DebugOption>
+    <ExcludeFile/>
+  </Target>
+  <Components path="./"/>
+  <Files>
+    <File name="stm_usb_fs_lib/inc/usb_init.h" path="stm_usb_fs_lib/inc/usb_init.h" type="1"/>
+    <File name="stm_usb_fs_lib/src" path="" type="2"/>
+    <File name="grbl/inc/probe.h" path="grbl/probe.h" type="1"/>
+    <File name="grbl" path="" type="2"/>
+    <File name="usb/usb_desc.c" path="usb/usb_desc.c" type="1"/>
+    <File name="grbl/src/stepper.c" path="grbl/stepper.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_core.h" path="stm_usb_fs_lib/inc/usb_core.h" type="1"/>
+    <File name="cmsis_boot" path="" type="2"/>
+    <File name="usb/hw_config.c" path="usb/hw_config.c" type="1"/>
+    <File name="grbl/inc/eeprom.h" path="grbl/eeprom.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_mem.h" path="stm_usb_fs_lib/inc/usb_mem.h" type="1"/>
+    <File name="grbl/inc/print.h" path="grbl/print.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_tim.c" path="stm_lib/src/stm32f10x_tim.c" type="1"/>
+    <File name="cmsis_boot/startup" path="" type="2"/>
+    <File name="stm_usb_fs_lib/inc/usb_regs.h" path="stm_usb_fs_lib/inc/usb_regs.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_int.h" path="stm_usb_fs_lib/inc/usb_int.h" type="1"/>
+    <File name="cmsis/core_cmFunc.h" path="cmsis/core_cmFunc.h" type="1"/>
+    <File name="grbl/inc/system.h" path="grbl/system.h" type="1"/>
+    <File name="stm_lib/src/misc.c" path="stm_lib/src/misc.c" type="1"/>
+    <File name="grbl/src/jog.c" path="grbl/jog.c" type="1"/>
+    <File name="cmsis_boot/stm32f10x.h" path="cmsis_boot/stm32f10x.h" type="1"/>
+    <File name="grbl/src/coolant_control.c" path="grbl/coolant_control.c" type="1"/>
+    <File name="cmsis_boot/stm32f10x_conf.h" path="cmsis_boot/stm32f10x_conf.h" type="1"/>
+    <File name="grbl/src/limits.c" path="grbl/limits.c" type="1"/>
+    <File name="grbl/src/serial.c" path="grbl/serial.c" type="1"/>
+    <File name="grbl/src/protocol.c" path="grbl/protocol.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_mem.c" path="stm_usb_fs_lib/src/usb_mem.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_spi.h" path="stm_lib/inc/stm32f10x_spi.h" type="1"/>
+    <File name="usb" path="" type="2"/>
+    <File name="grbl/src/probe.c" path="grbl/probe.c" type="1"/>
+    <File name="grbl/inc/planner.h" path="grbl/planner.h" type="1"/>
+    <File name="grbl/inc/stepper.h" path="grbl/stepper.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_usart.c" path="stm_lib/src/stm32f10x_usart.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_sil.c" path="stm_usb_fs_lib/src/usb_sil.c" type="1"/>
+    <File name="grbl/inc/spindle_control.h" path="grbl/spindle_control.h" type="1"/>
+    <File name="grbl/src/nuts_bolts.c" path="grbl/nuts_bolts.c" type="1"/>
+    <File name="cmsis_boot/startup/startup_stm32f10x_md.c" path="cmsis_boot/startup/startup_stm32f10x_md.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_gpio.c" path="stm_lib/src/stm32f10x_gpio.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_gpio.h" path="stm_lib/inc/stm32f10x_gpio.h" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_usart.h" path="stm_lib/inc/stm32f10x_usart.h" type="1"/>
+    <File name="grbl/inc/report.h" path="grbl/report.h" type="1"/>
+    <File name="grbl/inc/config.h" path="grbl/config.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_sil.h" path="stm_usb_fs_lib/inc/usb_sil.h" type="1"/>
+    <File name="cmsis_boot/system_stm32f10x.c" path="cmsis_boot/system_stm32f10x.c" type="1"/>
+    <File name="stm_lib/inc/misc.h" path="stm_lib/inc/misc.h" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_int.c" path="stm_usb_fs_lib/src/usb_int.c" type="1"/>
+    <File name="util" path="" type="2"/>
+    <File name="grbl/src/spindle_control.c" path="grbl/spindle_control.c" type="1"/>
+    <File name="grbl/inc/gcode.h" path="grbl/gcode.h" type="1"/>
+    <File name="cmsis/core_cmInstr.h" path="cmsis/core_cmInstr.h" type="1"/>
+    <File name="stm_usb_fs_lib" path="" type="2"/>
+    <File name="cmsis/core_cm3.h" path="cmsis/core_cm3.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc" path="" type="2"/>
+    <File name="grbl/src/sleep.c" path="grbl/sleep.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_exti.c" path="stm_lib/src/stm32f10x_exti.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_init.c" path="stm_usb_fs_lib/src/usb_init.c" type="1"/>
+    <File name="usb/usb_pwr.c" path="usb/usb_pwr.c" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_core.c" path="stm_usb_fs_lib/src/usb_core.c" type="1"/>
+    <File name="stm_lib/src/stm32f10x_rcc.c" path="stm_lib/src/stm32f10x_rcc.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_conf.h" path="stm_usb_fs_lib/inc/usb_conf.h" type="1"/>
+    <File name="grbl/src/gcode.c" path="grbl/gcode.c" type="1"/>
+    <File name="grbl/inc/limits.h" path="grbl/limits.h" type="1"/>
+    <File name="grbl/inc/serial.h" path="grbl/serial.h" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_def.h" path="stm_usb_fs_lib/inc/usb_def.h" type="1"/>
+    <File name="grbl/inc/coolant_control.h" path="grbl/coolant_control.h" type="1"/>
+    <File name="grbl/src/eeprom.c" path="grbl/eeprom.c" type="1"/>
+    <File name="usb/usb_prop.c" path="usb/usb_prop.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_type.h" path="stm_usb_fs_lib/inc/usb_type.h" type="1"/>
+    <File name="grbl/inc/protocol.h" path="grbl/protocol.h" type="1"/>
+    <File name="grbl/src" path="" type="2"/>
+    <File name="usb/usb_istr.c" path="usb/usb_istr.c" type="1"/>
+    <File name="stm_lib/src" path="" type="2"/>
+    <File name="grbl/inc/motion_control.h" path="grbl/motion_control.h" type="1"/>
+    <File name="cmsis" path="" type="2"/>
+    <File name="stm_lib" path="" type="2"/>
+    <File name="grbl/src/planner.c" path="grbl/planner.c" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_exti.h" path="stm_lib/inc/stm32f10x_exti.h" type="1"/>
+    <File name="stm_lib/src/stm32f10x_flash.c" path="stm_lib/src/stm32f10x_flash.c" type="1"/>
+    <File name="grbl/src/print.c" path="grbl/print.c" type="1"/>
+    <File name="usb/usb_endp.c" path="usb/usb_endp.c" type="1"/>
+    <File name="cmsis_boot/system_stm32f10x.h" path="cmsis_boot/system_stm32f10x.h" type="1"/>
+    <File name="stm_lib/inc/stm32f10x_rcc.h" path="stm_lib/inc/stm32f10x_rcc.h" type="1"/>
+    <File name="grbl/inc" path="" type="2"/>
+    <File name="grbl/inc/nuts_bolts.h" path="grbl/nuts_bolts.h" type="1"/>
+    <File name="stm_usb_fs_lib/src/usb_regs.c" path="stm_usb_fs_lib/src/usb_regs.c" type="1"/>
+    <File name="stm_usb_fs_lib/inc/usb_lib.h" path="stm_usb_fs_lib/inc/usb_lib.h" type="1"/>
+    <File name="grbl/inc/jog.h" path="grbl/jog.h" type="1"/>
+    <File name="grbl/src/settings.c" path="grbl/settings.c" type="1"/>
+    <File name="util/stm32f10x_it.c" path="util/stm32f10x_it.c" type="1"/>
+    <File name="grbl/src/report.c" path="grbl/report.c" type="1"/>
+    <File name="grbl/src/system.c" path="grbl/system.c" type="1"/>
+    <File name="grbl/inc/settings.h" path="grbl/settings.h" type="1"/>
+    <File name="stm_lib/inc" path="" type="2"/>
+    <File name="grbl/src/motion_control.c" path="grbl/motion_control.c" type="1"/>
+    <File name="grbl/inc/grbl.h" path="grbl/grbl.h" type="1"/>
+    <File name="grbl/inc/cpu_map.h" path="grbl/cpu_map.h" type="1"/>
+    <File name="main.c" path="grbl/main.c" type="1"/>
+  </Files>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/misc.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,220 @@
+/**
+  ******************************************************************************
+  * @file    misc.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the miscellaneous
+  *          firmware library functions (add-on to CMSIS functions).
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MISC_H
+#define __MISC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup MISC
+  * @{
+  */
+
+/** @defgroup MISC_Exported_Types
+  * @{
+  */
+
+/** 
+  * @brief  NVIC Init Structure definition  
+  */
+
+typedef struct
+{
+  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
+                                                   This parameter can be a value of @ref IRQn_Type 
+                                                   (For the complete STM32 Devices IRQ Channels list, please
+                                                    refer to stm32f10x.h file) */
+
+  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
+                                                   specified in NVIC_IRQChannel. This parameter can be a value
+                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */
+
+  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
+                                                   in NVIC_IRQChannel. This parameter can be a value
+                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */
+
+  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
+                                                   will be enabled or disabled. 
+                                                   This parameter can be set either to ENABLE or DISABLE */   
+} NVIC_InitTypeDef;
+ 
+/**
+  * @}
+  */
+
+/** @defgroup NVIC_Priority_Table 
+  * @{
+  */
+
+/**
+@code  
+ The table below gives the allowed values of the pre-emption priority and subpriority according
+ to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
+  ============================================================================================================================
+    NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  | Description
+  ============================================================================================================================
+   NVIC_PriorityGroup_0  |                0                  |            0-15             |   0 bits for pre-emption priority
+                         |                                   |                             |   4 bits for subpriority
+  ----------------------------------------------------------------------------------------------------------------------------
+   NVIC_PriorityGroup_1  |                0-1                |            0-7              |   1 bits for pre-emption priority
+                         |                                   |                             |   3 bits for subpriority
+  ----------------------------------------------------------------------------------------------------------------------------    
+   NVIC_PriorityGroup_2  |                0-3                |            0-3              |   2 bits for pre-emption priority
+                         |                                   |                             |   2 bits for subpriority
+  ----------------------------------------------------------------------------------------------------------------------------    
+   NVIC_PriorityGroup_3  |                0-7                |            0-1              |   3 bits for pre-emption priority
+                         |                                   |                             |   1 bits for subpriority
+  ----------------------------------------------------------------------------------------------------------------------------    
+   NVIC_PriorityGroup_4  |                0-15               |            0                |   4 bits for pre-emption priority
+                         |                                   |                             |   0 bits for subpriority                       
+  ============================================================================================================================
+@endcode
+*/
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Exported_Constants
+  * @{
+  */
+
+/** @defgroup Vector_Table_Base 
+  * @{
+  */
+
+#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
+#define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
+#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
+                                  ((VECTTAB) == NVIC_VectTab_FLASH))
+/**
+  * @}
+  */
+
+/** @defgroup System_Low_Power 
+  * @{
+  */
+
+#define NVIC_LP_SEVONPEND            ((uint8_t)0x10)
+#define NVIC_LP_SLEEPDEEP            ((uint8_t)0x04)
+#define NVIC_LP_SLEEPONEXIT          ((uint8_t)0x02)
+#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
+                        ((LP) == NVIC_LP_SLEEPDEEP) || \
+                        ((LP) == NVIC_LP_SLEEPONEXIT))
+/**
+  * @}
+  */
+
+/** @defgroup Preemption_Priority_Group 
+  * @{
+  */
+
+#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
+                                                            4 bits for subpriority */
+#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
+                                                            3 bits for subpriority */
+#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
+                                                            2 bits for subpriority */
+#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
+                                                            1 bits for subpriority */
+#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
+                                                            0 bits for subpriority */
+
+#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
+                                       ((GROUP) == NVIC_PriorityGroup_1) || \
+                                       ((GROUP) == NVIC_PriorityGroup_2) || \
+                                       ((GROUP) == NVIC_PriorityGroup_3) || \
+                                       ((GROUP) == NVIC_PriorityGroup_4))
+
+#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY)  ((PRIORITY) < 0x10)
+
+#define IS_NVIC_SUB_PRIORITY(PRIORITY)  ((PRIORITY) < 0x10)
+
+#define IS_NVIC_OFFSET(OFFSET)  ((OFFSET) < 0x000FFFFF)
+
+/**
+  * @}
+  */
+
+/** @defgroup SysTick_clock_source 
+  * @{
+  */
+
+#define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)
+#define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)
+#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
+                                       ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Exported_Functions
+  * @{
+  */
+
+void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
+void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
+void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MISC_H */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_exti.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,184 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_exti.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the EXTI firmware
+  *          library.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_EXTI_H
+#define __STM32F10x_EXTI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup EXTI
+  * @{
+  */
+
+/** @defgroup EXTI_Exported_Types
+  * @{
+  */
+
+/** 
+  * @brief  EXTI mode enumeration  
+  */
+
+typedef enum
+{
+  EXTI_Mode_Interrupt = 0x00,
+  EXTI_Mode_Event = 0x04
+}EXTIMode_TypeDef;
+
+#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event))
+
+/** 
+  * @brief  EXTI Trigger enumeration  
+  */
+
+typedef enum
+{
+  EXTI_Trigger_Rising = 0x08,
+  EXTI_Trigger_Falling = 0x0C,  
+  EXTI_Trigger_Rising_Falling = 0x10
+}EXTITrigger_TypeDef;
+
+#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \
+                                  ((TRIGGER) == EXTI_Trigger_Falling) || \
+                                  ((TRIGGER) == EXTI_Trigger_Rising_Falling))
+/** 
+  * @brief  EXTI Init Structure definition  
+  */
+
+typedef struct
+{
+  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
+                                         This parameter can be any combination of @ref EXTI_Lines */
+   
+  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
+                                         This parameter can be a value of @ref EXTIMode_TypeDef */
+
+  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
+                                         This parameter can be a value of @ref EXTIMode_TypeDef */
+
+  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
+                                         This parameter can be set either to ENABLE or DISABLE */ 
+}EXTI_InitTypeDef;
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Exported_Constants
+  * @{
+  */
+
+/** @defgroup EXTI_Lines 
+  * @{
+  */
+
+#define EXTI_Line0       ((uint32_t)0x00001)  /*!< External interrupt line 0 */
+#define EXTI_Line1       ((uint32_t)0x00002)  /*!< External interrupt line 1 */
+#define EXTI_Line2       ((uint32_t)0x00004)  /*!< External interrupt line 2 */
+#define EXTI_Line3       ((uint32_t)0x00008)  /*!< External interrupt line 3 */
+#define EXTI_Line4       ((uint32_t)0x00010)  /*!< External interrupt line 4 */
+#define EXTI_Line5       ((uint32_t)0x00020)  /*!< External interrupt line 5 */
+#define EXTI_Line6       ((uint32_t)0x00040)  /*!< External interrupt line 6 */
+#define EXTI_Line7       ((uint32_t)0x00080)  /*!< External interrupt line 7 */
+#define EXTI_Line8       ((uint32_t)0x00100)  /*!< External interrupt line 8 */
+#define EXTI_Line9       ((uint32_t)0x00200)  /*!< External interrupt line 9 */
+#define EXTI_Line10      ((uint32_t)0x00400)  /*!< External interrupt line 10 */
+#define EXTI_Line11      ((uint32_t)0x00800)  /*!< External interrupt line 11 */
+#define EXTI_Line12      ((uint32_t)0x01000)  /*!< External interrupt line 12 */
+#define EXTI_Line13      ((uint32_t)0x02000)  /*!< External interrupt line 13 */
+#define EXTI_Line14      ((uint32_t)0x04000)  /*!< External interrupt line 14 */
+#define EXTI_Line15      ((uint32_t)0x08000)  /*!< External interrupt line 15 */
+#define EXTI_Line16      ((uint32_t)0x10000)  /*!< External interrupt line 16 Connected to the PVD Output */
+#define EXTI_Line17      ((uint32_t)0x20000)  /*!< External interrupt line 17 Connected to the RTC Alarm event */
+#define EXTI_Line18      ((uint32_t)0x40000)  /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS
+                                                   Wakeup from suspend event */                                    
+#define EXTI_Line19      ((uint32_t)0x80000)  /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
+                                          
+#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFFF00000) == 0x00) && ((LINE) != (uint16_t)0x00))
+#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \
+                            ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \
+                            ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \
+                            ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \
+                            ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \
+                            ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \
+                            ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \
+                            ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \
+                            ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \
+                            ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19))
+
+                    
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Exported_Functions
+  * @{
+  */
+
+void EXTI_DeInit(void);
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
+void EXTI_ClearFlag(uint32_t EXTI_Line);
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_EXTI_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_flash.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,426 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_flash.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the FLASH 
+  *          firmware library.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_FLASH_H
+#define __STM32F10x_FLASH_H
+#define assert_param(expr) ((void)0)
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup FLASH
+  * @{
+  */
+
+/** @defgroup FLASH_Exported_Types
+  * @{
+  */
+
+/** 
+  * @brief  FLASH Status  
+  */
+
+typedef enum
+{ 
+  FLASH_BUSY = 1,
+  FLASH_ERROR_PG,
+  FLASH_ERROR_WRP,
+  FLASH_COMPLETE,
+  FLASH_TIMEOUT
+}FLASH_Status;
+
+/**
+  * @}
+  */
+
+/** @defgroup FLASH_Exported_Constants
+  * @{
+  */
+
+/** @defgroup Flash_Latency 
+  * @{
+  */
+
+#define FLASH_Latency_0                ((uint32_t)0x00000000)  /*!< FLASH Zero Latency cycle */
+#define FLASH_Latency_1                ((uint32_t)0x00000001)  /*!< FLASH One Latency cycle */
+#define FLASH_Latency_2                ((uint32_t)0x00000002)  /*!< FLASH Two Latency cycles */
+#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \
+                                   ((LATENCY) == FLASH_Latency_1) || \
+                                   ((LATENCY) == FLASH_Latency_2))
+/**
+  * @}
+  */
+
+/** @defgroup Half_Cycle_Enable_Disable 
+  * @{
+  */
+
+#define FLASH_HalfCycleAccess_Enable   ((uint32_t)0x00000008)  /*!< FLASH Half Cycle Enable */
+#define FLASH_HalfCycleAccess_Disable  ((uint32_t)0x00000000)  /*!< FLASH Half Cycle Disable */
+#define IS_FLASH_HALFCYCLEACCESS_STATE(STATE) (((STATE) == FLASH_HalfCycleAccess_Enable) || \
+                                               ((STATE) == FLASH_HalfCycleAccess_Disable)) 
+/**
+  * @}
+  */
+
+/** @defgroup Prefetch_Buffer_Enable_Disable 
+  * @{
+  */
+
+#define FLASH_PrefetchBuffer_Enable    ((uint32_t)0x00000010)  /*!< FLASH Prefetch Buffer Enable */
+#define FLASH_PrefetchBuffer_Disable   ((uint32_t)0x00000000)  /*!< FLASH Prefetch Buffer Disable */
+#define IS_FLASH_PREFETCHBUFFER_STATE(STATE) (((STATE) == FLASH_PrefetchBuffer_Enable) || \
+                                              ((STATE) == FLASH_PrefetchBuffer_Disable)) 
+/**
+  * @}
+  */
+
+/** @defgroup Option_Bytes_Write_Protection 
+  * @{
+  */
+
+/* Values to be used with STM32 Low and Medium density devices */
+#define FLASH_WRProt_Pages0to3         ((uint32_t)0x00000001) /*!< STM32 Low and Medium density devices: Write protection of page 0 to 3 */
+#define FLASH_WRProt_Pages4to7         ((uint32_t)0x00000002) /*!< STM32 Low and Medium density devices: Write protection of page 4 to 7 */
+#define FLASH_WRProt_Pages8to11        ((uint32_t)0x00000004) /*!< STM32 Low and Medium density devices: Write protection of page 8 to 11 */
+#define FLASH_WRProt_Pages12to15       ((uint32_t)0x00000008) /*!< STM32 Low and Medium density devices: Write protection of page 12 to 15 */
+#define FLASH_WRProt_Pages16to19       ((uint32_t)0x00000010) /*!< STM32 Low and Medium density devices: Write protection of page 16 to 19 */
+#define FLASH_WRProt_Pages20to23       ((uint32_t)0x00000020) /*!< STM32 Low and Medium density devices: Write protection of page 20 to 23 */
+#define FLASH_WRProt_Pages24to27       ((uint32_t)0x00000040) /*!< STM32 Low and Medium density devices: Write protection of page 24 to 27 */
+#define FLASH_WRProt_Pages28to31       ((uint32_t)0x00000080) /*!< STM32 Low and Medium density devices: Write protection of page 28 to 31 */
+
+/* Values to be used with STM32 Medium-density devices */
+#define FLASH_WRProt_Pages32to35       ((uint32_t)0x00000100) /*!< STM32 Medium-density devices: Write protection of page 32 to 35 */
+#define FLASH_WRProt_Pages36to39       ((uint32_t)0x00000200) /*!< STM32 Medium-density devices: Write protection of page 36 to 39 */
+#define FLASH_WRProt_Pages40to43       ((uint32_t)0x00000400) /*!< STM32 Medium-density devices: Write protection of page 40 to 43 */
+#define FLASH_WRProt_Pages44to47       ((uint32_t)0x00000800) /*!< STM32 Medium-density devices: Write protection of page 44 to 47 */
+#define FLASH_WRProt_Pages48to51       ((uint32_t)0x00001000) /*!< STM32 Medium-density devices: Write protection of page 48 to 51 */
+#define FLASH_WRProt_Pages52to55       ((uint32_t)0x00002000) /*!< STM32 Medium-density devices: Write protection of page 52 to 55 */
+#define FLASH_WRProt_Pages56to59       ((uint32_t)0x00004000) /*!< STM32 Medium-density devices: Write protection of page 56 to 59 */
+#define FLASH_WRProt_Pages60to63       ((uint32_t)0x00008000) /*!< STM32 Medium-density devices: Write protection of page 60 to 63 */
+#define FLASH_WRProt_Pages64to67       ((uint32_t)0x00010000) /*!< STM32 Medium-density devices: Write protection of page 64 to 67 */
+#define FLASH_WRProt_Pages68to71       ((uint32_t)0x00020000) /*!< STM32 Medium-density devices: Write protection of page 68 to 71 */
+#define FLASH_WRProt_Pages72to75       ((uint32_t)0x00040000) /*!< STM32 Medium-density devices: Write protection of page 72 to 75 */
+#define FLASH_WRProt_Pages76to79       ((uint32_t)0x00080000) /*!< STM32 Medium-density devices: Write protection of page 76 to 79 */
+#define FLASH_WRProt_Pages80to83       ((uint32_t)0x00100000) /*!< STM32 Medium-density devices: Write protection of page 80 to 83 */
+#define FLASH_WRProt_Pages84to87       ((uint32_t)0x00200000) /*!< STM32 Medium-density devices: Write protection of page 84 to 87 */
+#define FLASH_WRProt_Pages88to91       ((uint32_t)0x00400000) /*!< STM32 Medium-density devices: Write protection of page 88 to 91 */
+#define FLASH_WRProt_Pages92to95       ((uint32_t)0x00800000) /*!< STM32 Medium-density devices: Write protection of page 92 to 95 */
+#define FLASH_WRProt_Pages96to99       ((uint32_t)0x01000000) /*!< STM32 Medium-density devices: Write protection of page 96 to 99 */
+#define FLASH_WRProt_Pages100to103     ((uint32_t)0x02000000) /*!< STM32 Medium-density devices: Write protection of page 100 to 103 */
+#define FLASH_WRProt_Pages104to107     ((uint32_t)0x04000000) /*!< STM32 Medium-density devices: Write protection of page 104 to 107 */
+#define FLASH_WRProt_Pages108to111     ((uint32_t)0x08000000) /*!< STM32 Medium-density devices: Write protection of page 108 to 111 */
+#define FLASH_WRProt_Pages112to115     ((uint32_t)0x10000000) /*!< STM32 Medium-density devices: Write protection of page 112 to 115 */
+#define FLASH_WRProt_Pages116to119     ((uint32_t)0x20000000) /*!< STM32 Medium-density devices: Write protection of page 115 to 119 */
+#define FLASH_WRProt_Pages120to123     ((uint32_t)0x40000000) /*!< STM32 Medium-density devices: Write protection of page 120 to 123 */
+#define FLASH_WRProt_Pages124to127     ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 124 to 127 */
+
+/* Values to be used with STM32 High-density and STM32F10X Connectivity line devices */
+#define FLASH_WRProt_Pages0to1         ((uint32_t)0x00000001) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 0 to 1 */
+#define FLASH_WRProt_Pages2to3         ((uint32_t)0x00000002) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 2 to 3 */
+#define FLASH_WRProt_Pages4to5         ((uint32_t)0x00000004) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 4 to 5 */
+#define FLASH_WRProt_Pages6to7         ((uint32_t)0x00000008) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 6 to 7 */
+#define FLASH_WRProt_Pages8to9         ((uint32_t)0x00000010) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 8 to 9 */
+#define FLASH_WRProt_Pages10to11       ((uint32_t)0x00000020) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 10 to 11 */
+#define FLASH_WRProt_Pages12to13       ((uint32_t)0x00000040) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 12 to 13 */
+#define FLASH_WRProt_Pages14to15       ((uint32_t)0x00000080) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 14 to 15 */
+#define FLASH_WRProt_Pages16to17       ((uint32_t)0x00000100) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 16 to 17 */
+#define FLASH_WRProt_Pages18to19       ((uint32_t)0x00000200) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 18 to 19 */
+#define FLASH_WRProt_Pages20to21       ((uint32_t)0x00000400) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 20 to 21 */
+#define FLASH_WRProt_Pages22to23       ((uint32_t)0x00000800) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 22 to 23 */
+#define FLASH_WRProt_Pages24to25       ((uint32_t)0x00001000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 24 to 25 */
+#define FLASH_WRProt_Pages26to27       ((uint32_t)0x00002000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 26 to 27 */
+#define FLASH_WRProt_Pages28to29       ((uint32_t)0x00004000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 28 to 29 */
+#define FLASH_WRProt_Pages30to31       ((uint32_t)0x00008000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 30 to 31 */
+#define FLASH_WRProt_Pages32to33       ((uint32_t)0x00010000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 32 to 33 */
+#define FLASH_WRProt_Pages34to35       ((uint32_t)0x00020000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 34 to 35 */
+#define FLASH_WRProt_Pages36to37       ((uint32_t)0x00040000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 36 to 37 */
+#define FLASH_WRProt_Pages38to39       ((uint32_t)0x00080000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 38 to 39 */
+#define FLASH_WRProt_Pages40to41       ((uint32_t)0x00100000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 40 to 41 */
+#define FLASH_WRProt_Pages42to43       ((uint32_t)0x00200000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 42 to 43 */
+#define FLASH_WRProt_Pages44to45       ((uint32_t)0x00400000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 44 to 45 */
+#define FLASH_WRProt_Pages46to47       ((uint32_t)0x00800000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 46 to 47 */
+#define FLASH_WRProt_Pages48to49       ((uint32_t)0x01000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 48 to 49 */
+#define FLASH_WRProt_Pages50to51       ((uint32_t)0x02000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 50 to 51 */
+#define FLASH_WRProt_Pages52to53       ((uint32_t)0x04000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 52 to 53 */
+#define FLASH_WRProt_Pages54to55       ((uint32_t)0x08000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 54 to 55 */
+#define FLASH_WRProt_Pages56to57       ((uint32_t)0x10000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 56 to 57 */
+#define FLASH_WRProt_Pages58to59       ((uint32_t)0x20000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 58 to 59 */
+#define FLASH_WRProt_Pages60to61       ((uint32_t)0x40000000) /*!< STM32 High-density, XL-density and Connectivity line devices:
+                                                                   Write protection of page 60 to 61 */
+#define FLASH_WRProt_Pages62to127      ((uint32_t)0x80000000) /*!< STM32 Connectivity line devices: Write protection of page 62 to 127 */
+#define FLASH_WRProt_Pages62to255      ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 62 to 255 */
+#define FLASH_WRProt_Pages62to511      ((uint32_t)0x80000000) /*!< STM32 XL-density devices: Write protection of page 62 to 511 */
+
+#define FLASH_WRProt_AllPages          ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Pages */
+
+#define IS_FLASH_WRPROT_PAGE(PAGE) (((PAGE) != 0x00000000))
+
+#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x080FFFFF))
+
+#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == 0x1FFFF804) || ((ADDRESS) == 0x1FFFF806))
+
+/**
+  * @}
+  */
+
+/** @defgroup Option_Bytes_IWatchdog 
+  * @{
+  */
+
+#define OB_IWDG_SW                     ((uint16_t)0x0001)  /*!< Software IWDG selected */
+#define OB_IWDG_HW                     ((uint16_t)0x0000)  /*!< Hardware IWDG selected */
+#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
+
+/**
+  * @}
+  */
+
+/** @defgroup Option_Bytes_nRST_STOP 
+  * @{
+  */
+
+#define OB_STOP_NoRST                  ((uint16_t)0x0002) /*!< No reset generated when entering in STOP */
+#define OB_STOP_RST                    ((uint16_t)0x0000) /*!< Reset generated when entering in STOP */
+#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST))
+
+/**
+  * @}
+  */
+
+/** @defgroup Option_Bytes_nRST_STDBY 
+  * @{
+  */
+
+#define OB_STDBY_NoRST                 ((uint16_t)0x0004) /*!< No reset generated when entering in STANDBY */
+#define OB_STDBY_RST                   ((uint16_t)0x0000) /*!< Reset generated when entering in STANDBY */
+#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST))
+
+#ifdef STM32F10X_XL
+/**
+  * @}
+  */
+/** @defgroup FLASH_Boot
+  * @{
+  */
+#define FLASH_BOOT_Bank1  ((uint16_t)0x0000) /*!< At startup, if boot pins are set in boot from user Flash position
+                                                  and this parameter is selected the device will boot from Bank1(Default) */
+#define FLASH_BOOT_Bank2  ((uint16_t)0x0001) /*!< At startup, if boot pins are set in boot from user Flash position
+                                                  and this parameter is selected the device will boot from Bank 2 or Bank 1,
+                                                  depending on the activation of the bank */
+#define IS_FLASH_BOOT(BOOT) (((BOOT) == FLASH_BOOT_Bank1) || ((BOOT) == FLASH_BOOT_Bank2))
+#endif
+/**
+  * @}
+  */
+/** @defgroup FLASH_Interrupts 
+  * @{
+  */
+#ifdef STM32F10X_XL
+#define FLASH_IT_BANK2_ERROR                 ((uint32_t)0x80000400)  /*!< FPEC BANK2 error interrupt source */
+#define FLASH_IT_BANK2_EOP                   ((uint32_t)0x80001000)  /*!< End of FLASH BANK2 Operation Interrupt source */
+
+#define FLASH_IT_BANK1_ERROR                 FLASH_IT_ERROR          /*!< FPEC BANK1 error interrupt source */
+#define FLASH_IT_BANK1_EOP                   FLASH_IT_EOP            /*!< End of FLASH BANK1 Operation Interrupt source */
+
+#define FLASH_IT_ERROR                 ((uint32_t)0x00000400)  /*!< FPEC BANK1 error interrupt source */
+#define FLASH_IT_EOP                   ((uint32_t)0x00001000)  /*!< End of FLASH BANK1 Operation Interrupt source */
+#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0x7FFFEBFF) == 0x00000000) && (((IT) != 0x00000000)))
+#else
+#define FLASH_IT_ERROR                 ((uint32_t)0x00000400)  /*!< FPEC error interrupt source */
+#define FLASH_IT_EOP                   ((uint32_t)0x00001000)  /*!< End of FLASH Operation Interrupt source */
+#define FLASH_IT_BANK1_ERROR           FLASH_IT_ERROR          /*!< FPEC BANK1 error interrupt source */
+#define FLASH_IT_BANK1_EOP             FLASH_IT_EOP            /*!< End of FLASH BANK1 Operation Interrupt source */
+
+#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFFEBFF) == 0x00000000) && (((IT) != 0x00000000)))
+#endif
+
+/**
+  * @}
+  */
+
+/** @defgroup FLASH_Flags 
+  * @{
+  */
+#ifdef STM32F10X_XL
+#define FLASH_FLAG_BANK2_BSY                 ((uint32_t)0x80000001)  /*!< FLASH BANK2 Busy flag */
+#define FLASH_FLAG_BANK2_EOP                 ((uint32_t)0x80000020)  /*!< FLASH BANK2 End of Operation flag */
+#define FLASH_FLAG_BANK2_PGERR               ((uint32_t)0x80000004)  /*!< FLASH BANK2 Program error flag */
+#define FLASH_FLAG_BANK2_WRPRTERR            ((uint32_t)0x80000010)  /*!< FLASH BANK2 Write protected error flag */
+
+#define FLASH_FLAG_BANK1_BSY                 FLASH_FLAG_BSY       /*!< FLASH BANK1 Busy flag*/
+#define FLASH_FLAG_BANK1_EOP                 FLASH_FLAG_EOP       /*!< FLASH BANK1 End of Operation flag */
+#define FLASH_FLAG_BANK1_PGERR               FLASH_FLAG_PGERR     /*!< FLASH BANK1 Program error flag */
+#define FLASH_FLAG_BANK1_WRPRTERR            FLASH_FLAG_WRPRTERR  /*!< FLASH BANK1 Write protected error flag */
+
+#define FLASH_FLAG_BSY                 ((uint32_t)0x00000001)  /*!< FLASH Busy flag */
+#define FLASH_FLAG_EOP                 ((uint32_t)0x00000020)  /*!< FLASH End of Operation flag */
+#define FLASH_FLAG_PGERR               ((uint32_t)0x00000004)  /*!< FLASH Program error flag */
+#define FLASH_FLAG_WRPRTERR            ((uint32_t)0x00000010)  /*!< FLASH Write protected error flag */
+#define FLASH_FLAG_OPTERR              ((uint32_t)0x00000001)  /*!< FLASH Option Byte error flag */
+ 
+#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0x7FFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000))
+#define IS_FLASH_GET_FLAG(FLAG)  (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \
+                                  ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \
+                                  ((FLAG) == FLASH_FLAG_OPTERR)|| \
+                                  ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \
+                                  ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \
+                                  ((FLAG) == FLASH_FLAG_BANK2_BSY) || ((FLAG) == FLASH_FLAG_BANK2_EOP) || \
+                                  ((FLAG) == FLASH_FLAG_BANK2_PGERR) || ((FLAG) == FLASH_FLAG_BANK2_WRPRTERR))
+#else
+#define FLASH_FLAG_BSY                 ((uint32_t)0x00000001)  /*!< FLASH Busy flag */
+#define FLASH_FLAG_EOP                 ((uint32_t)0x00000020)  /*!< FLASH End of Operation flag */
+#define FLASH_FLAG_PGERR               ((uint32_t)0x00000004)  /*!< FLASH Program error flag */
+#define FLASH_FLAG_WRPRTERR            ((uint32_t)0x00000010)  /*!< FLASH Write protected error flag */
+#define FLASH_FLAG_OPTERR              ((uint32_t)0x00000001)  /*!< FLASH Option Byte error flag */
+
+#define FLASH_FLAG_BANK1_BSY                 FLASH_FLAG_BSY       /*!< FLASH BANK1 Busy flag*/
+#define FLASH_FLAG_BANK1_EOP                 FLASH_FLAG_EOP       /*!< FLASH BANK1 End of Operation flag */
+#define FLASH_FLAG_BANK1_PGERR               FLASH_FLAG_PGERR     /*!< FLASH BANK1 Program error flag */
+#define FLASH_FLAG_BANK1_WRPRTERR            FLASH_FLAG_WRPRTERR  /*!< FLASH BANK1 Write protected error flag */
+ 
+#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000))
+#define IS_FLASH_GET_FLAG(FLAG)  (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \
+                                  ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \
+								  ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \
+                                  ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \
+                                  ((FLAG) == FLASH_FLAG_OPTERR))
+#endif
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup FLASH_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup FLASH_Exported_Functions
+  * @{
+  */
+
+/*------------ Functions used for all STM32F10x devices -----*/
+void FLASH_SetLatency(uint32_t FLASH_Latency);
+void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess);
+void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer);
+void FLASH_Unlock(void);
+void FLASH_Lock(void);
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
+FLASH_Status FLASH_EraseAllPages(void);
+FLASH_Status FLASH_EraseOptionBytes(void);
+FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
+FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
+FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
+FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
+FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);
+uint32_t FLASH_GetUserOptionByte(void);
+uint32_t FLASH_GetWriteProtectionOptionByte(void);
+FlagStatus FLASH_GetReadOutProtectionStatus(void);
+FlagStatus FLASH_GetPrefetchBufferStatus(void);
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
+void FLASH_ClearFlag(uint32_t FLASH_FLAG);
+FLASH_Status FLASH_GetStatus(void);
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
+
+/*------------ New function used for all STM32F10x devices -----*/
+void FLASH_UnlockBank1(void);
+void FLASH_LockBank1(void);
+FLASH_Status FLASH_EraseAllBank1Pages(void);
+FLASH_Status FLASH_GetBank1Status(void);
+FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout);
+
+#ifdef STM32F10X_XL
+/*---- New Functions used only with STM32F10x_XL density devices -----*/
+void FLASH_UnlockBank2(void);
+void FLASH_LockBank2(void);
+FLASH_Status FLASH_EraseAllBank2Pages(void);
+FLASH_Status FLASH_GetBank2Status(void);
+FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout);
+FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_FLASH_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_gpio.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,385 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_gpio.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the GPIO 
+  *          firmware library.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_GPIO_H
+#define __STM32F10x_GPIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup GPIO
+  * @{
+  */
+
+/** @defgroup GPIO_Exported_Types
+  * @{
+  */
+
+#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
+                                    ((PERIPH) == GPIOB) || \
+                                    ((PERIPH) == GPIOC) || \
+                                    ((PERIPH) == GPIOD) || \
+                                    ((PERIPH) == GPIOE) || \
+                                    ((PERIPH) == GPIOF) || \
+                                    ((PERIPH) == GPIOG))
+                                     
+/** 
+  * @brief  Output Maximum frequency selection  
+  */
+
+typedef enum
+{ 
+  GPIO_Speed_10MHz = 1,
+  GPIO_Speed_2MHz, 
+  GPIO_Speed_50MHz
+}GPIOSpeed_TypeDef;
+#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \
+                              ((SPEED) == GPIO_Speed_50MHz))
+
+/** 
+  * @brief  Configuration Mode enumeration  
+  */
+
+typedef enum
+{ GPIO_Mode_AIN = 0x0,
+  GPIO_Mode_IN_FLOATING = 0x04,
+  GPIO_Mode_IPD = 0x28,
+  GPIO_Mode_IPU = 0x48,
+  GPIO_Mode_Out_OD = 0x14,
+  GPIO_Mode_Out_PP = 0x10,
+  GPIO_Mode_AF_OD = 0x1C,
+  GPIO_Mode_AF_PP = 0x18
+}GPIOMode_TypeDef;
+
+#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \
+                            ((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \
+                            ((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \
+                            ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
+
+/** 
+  * @brief  GPIO Init structure definition  
+  */
+
+typedef struct
+{
+  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
+                                      This parameter can be any value of @ref GPIO_pins_define */
+
+  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
+                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */
+
+  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
+                                      This parameter can be a value of @ref GPIOMode_TypeDef */
+}GPIO_InitTypeDef;
+
+
+/** 
+  * @brief  Bit_SET and Bit_RESET enumeration  
+  */
+
+typedef enum
+{ Bit_RESET = 0,
+  Bit_SET
+}BitAction;
+
+#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET))
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Exported_Constants
+  * @{
+  */
+
+/** @defgroup GPIO_pins_define 
+  * @{
+  */
+
+#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
+#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
+#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
+#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
+#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
+#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
+#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
+#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
+#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
+#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
+#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
+#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
+#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
+#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
+#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
+#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
+#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */
+
+#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
+
+#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
+                              ((PIN) == GPIO_Pin_1) || \
+                              ((PIN) == GPIO_Pin_2) || \
+                              ((PIN) == GPIO_Pin_3) || \
+                              ((PIN) == GPIO_Pin_4) || \
+                              ((PIN) == GPIO_Pin_5) || \
+                              ((PIN) == GPIO_Pin_6) || \
+                              ((PIN) == GPIO_Pin_7) || \
+                              ((PIN) == GPIO_Pin_8) || \
+                              ((PIN) == GPIO_Pin_9) || \
+                              ((PIN) == GPIO_Pin_10) || \
+                              ((PIN) == GPIO_Pin_11) || \
+                              ((PIN) == GPIO_Pin_12) || \
+                              ((PIN) == GPIO_Pin_13) || \
+                              ((PIN) == GPIO_Pin_14) || \
+                              ((PIN) == GPIO_Pin_15))
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Remap_define 
+  * @{
+  */
+
+#define GPIO_Remap_SPI1             ((uint32_t)0x00000001)  /*!< SPI1 Alternate Function mapping */
+#define GPIO_Remap_I2C1             ((uint32_t)0x00000002)  /*!< I2C1 Alternate Function mapping */
+#define GPIO_Remap_USART1           ((uint32_t)0x00000004)  /*!< USART1 Alternate Function mapping */
+#define GPIO_Remap_USART2           ((uint32_t)0x00000008)  /*!< USART2 Alternate Function mapping */
+#define GPIO_PartialRemap_USART3    ((uint32_t)0x00140010)  /*!< USART3 Partial Alternate Function mapping */
+#define GPIO_FullRemap_USART3       ((uint32_t)0x00140030)  /*!< USART3 Full Alternate Function mapping */
+#define GPIO_PartialRemap_TIM1      ((uint32_t)0x00160040)  /*!< TIM1 Partial Alternate Function mapping */
+#define GPIO_FullRemap_TIM1         ((uint32_t)0x001600C0)  /*!< TIM1 Full Alternate Function mapping */
+#define GPIO_PartialRemap1_TIM2     ((uint32_t)0x00180100)  /*!< TIM2 Partial1 Alternate Function mapping */
+#define GPIO_PartialRemap2_TIM2     ((uint32_t)0x00180200)  /*!< TIM2 Partial2 Alternate Function mapping */
+#define GPIO_FullRemap_TIM2         ((uint32_t)0x00180300)  /*!< TIM2 Full Alternate Function mapping */
+#define GPIO_PartialRemap_TIM3      ((uint32_t)0x001A0800)  /*!< TIM3 Partial Alternate Function mapping */
+#define GPIO_FullRemap_TIM3         ((uint32_t)0x001A0C00)  /*!< TIM3 Full Alternate Function mapping */
+#define GPIO_Remap_TIM4             ((uint32_t)0x00001000)  /*!< TIM4 Alternate Function mapping */
+#define GPIO_Remap1_CAN1            ((uint32_t)0x001D4000)  /*!< CAN1 Alternate Function mapping */
+#define GPIO_Remap2_CAN1            ((uint32_t)0x001D6000)  /*!< CAN1 Alternate Function mapping */
+#define GPIO_Remap_PD01             ((uint32_t)0x00008000)  /*!< PD01 Alternate Function mapping */
+#define GPIO_Remap_TIM5CH4_LSI      ((uint32_t)0x00200001)  /*!< LSI connected to TIM5 Channel4 input capture for calibration */
+#define GPIO_Remap_ADC1_ETRGINJ     ((uint32_t)0x00200002)  /*!< ADC1 External Trigger Injected Conversion remapping */
+#define GPIO_Remap_ADC1_ETRGREG     ((uint32_t)0x00200004)  /*!< ADC1 External Trigger Regular Conversion remapping */
+#define GPIO_Remap_ADC2_ETRGINJ     ((uint32_t)0x00200008)  /*!< ADC2 External Trigger Injected Conversion remapping */
+#define GPIO_Remap_ADC2_ETRGREG     ((uint32_t)0x00200010)  /*!< ADC2 External Trigger Regular Conversion remapping */
+#define GPIO_Remap_ETH              ((uint32_t)0x00200020)  /*!< Ethernet remapping (only for Connectivity line devices) */
+#define GPIO_Remap_CAN2             ((uint32_t)0x00200040)  /*!< CAN2 remapping (only for Connectivity line devices) */
+#define GPIO_Remap_SWJ_NoJTRST      ((uint32_t)0x00300100)  /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */
+#define GPIO_Remap_SWJ_JTAGDisable  ((uint32_t)0x00300200)  /*!< JTAG-DP Disabled and SW-DP Enabled */
+#define GPIO_Remap_SWJ_Disable      ((uint32_t)0x00300400)  /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */
+#define GPIO_Remap_SPI3             ((uint32_t)0x00201100)  /*!< SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices) */
+#define GPIO_Remap_TIM2ITR1_PTP_SOF ((uint32_t)0x00202000)  /*!< Ethernet PTP output or USB OTG SOF (Start of Frame) connected
+                                                                 to TIM2 Internal Trigger 1 for calibration
+                                                                 (only for Connectivity line devices) */
+#define GPIO_Remap_PTP_PPS          ((uint32_t)0x00204000)  /*!< Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices) */
+
+#define GPIO_Remap_TIM15            ((uint32_t)0x80000001)  /*!< TIM15 Alternate Function mapping (only for Value line devices) */
+#define GPIO_Remap_TIM16            ((uint32_t)0x80000002)  /*!< TIM16 Alternate Function mapping (only for Value line devices) */
+#define GPIO_Remap_TIM17            ((uint32_t)0x80000004)  /*!< TIM17 Alternate Function mapping (only for Value line devices) */
+#define GPIO_Remap_CEC              ((uint32_t)0x80000008)  /*!< CEC Alternate Function mapping (only for Value line devices) */
+#define GPIO_Remap_TIM1_DMA         ((uint32_t)0x80000010)  /*!< TIM1 DMA requests mapping (only for Value line devices) */
+
+#define GPIO_Remap_TIM9             ((uint32_t)0x80000020)  /*!< TIM9 Alternate Function mapping (only for XL-density devices) */
+#define GPIO_Remap_TIM10            ((uint32_t)0x80000040)  /*!< TIM10 Alternate Function mapping (only for XL-density devices) */
+#define GPIO_Remap_TIM11            ((uint32_t)0x80000080)  /*!< TIM11 Alternate Function mapping (only for XL-density devices) */
+#define GPIO_Remap_TIM13            ((uint32_t)0x80000100)  /*!< TIM13 Alternate Function mapping (only for High density Value line and XL-density devices) */
+#define GPIO_Remap_TIM14            ((uint32_t)0x80000200)  /*!< TIM14 Alternate Function mapping (only for High density Value line and XL-density devices) */
+#define GPIO_Remap_FSMC_NADV        ((uint32_t)0x80000400)  /*!< FSMC_NADV Alternate Function mapping (only for High density Value line and XL-density devices) */
+
+#define GPIO_Remap_TIM67_DAC_DMA    ((uint32_t)0x80000800)  /*!< TIM6/TIM7 and DAC DMA requests remapping (only for High density Value line devices) */
+#define GPIO_Remap_TIM12            ((uint32_t)0x80001000)  /*!< TIM12 Alternate Function mapping (only for High density Value line devices) */
+#define GPIO_Remap_MISC             ((uint32_t)0x80002000)  /*!< Miscellaneous Remap (DMA2 Channel5 Position and DAC Trigger remapping, 
+                                                                 only for High density Value line devices) */                                                       
+
+#define IS_GPIO_REMAP(REMAP) (((REMAP) == GPIO_Remap_SPI1) || ((REMAP) == GPIO_Remap_I2C1) || \
+                              ((REMAP) == GPIO_Remap_USART1) || ((REMAP) == GPIO_Remap_USART2) || \
+                              ((REMAP) == GPIO_PartialRemap_USART3) || ((REMAP) == GPIO_FullRemap_USART3) || \
+                              ((REMAP) == GPIO_PartialRemap_TIM1) || ((REMAP) == GPIO_FullRemap_TIM1) || \
+                              ((REMAP) == GPIO_PartialRemap1_TIM2) || ((REMAP) == GPIO_PartialRemap2_TIM2) || \
+                              ((REMAP) == GPIO_FullRemap_TIM2) || ((REMAP) == GPIO_PartialRemap_TIM3) || \
+                              ((REMAP) == GPIO_FullRemap_TIM3) || ((REMAP) == GPIO_Remap_TIM4) || \
+                              ((REMAP) == GPIO_Remap1_CAN1) || ((REMAP) == GPIO_Remap2_CAN1) || \
+                              ((REMAP) == GPIO_Remap_PD01) || ((REMAP) == GPIO_Remap_TIM5CH4_LSI) || \
+                              ((REMAP) == GPIO_Remap_ADC1_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC1_ETRGREG) || \
+                              ((REMAP) == GPIO_Remap_ADC2_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC2_ETRGREG) || \
+                              ((REMAP) == GPIO_Remap_ETH) ||((REMAP) == GPIO_Remap_CAN2) || \
+                              ((REMAP) == GPIO_Remap_SWJ_NoJTRST) || ((REMAP) == GPIO_Remap_SWJ_JTAGDisable) || \
+                              ((REMAP) == GPIO_Remap_SWJ_Disable)|| ((REMAP) == GPIO_Remap_SPI3) || \
+                              ((REMAP) == GPIO_Remap_TIM2ITR1_PTP_SOF) || ((REMAP) == GPIO_Remap_PTP_PPS) || \
+                              ((REMAP) == GPIO_Remap_TIM15) || ((REMAP) == GPIO_Remap_TIM16) || \
+                              ((REMAP) == GPIO_Remap_TIM17) || ((REMAP) == GPIO_Remap_CEC) || \
+                              ((REMAP) == GPIO_Remap_TIM1_DMA) || ((REMAP) == GPIO_Remap_TIM9) || \
+                              ((REMAP) == GPIO_Remap_TIM10) || ((REMAP) == GPIO_Remap_TIM11) || \
+                              ((REMAP) == GPIO_Remap_TIM13) || ((REMAP) == GPIO_Remap_TIM14) || \
+                              ((REMAP) == GPIO_Remap_FSMC_NADV) || ((REMAP) == GPIO_Remap_TIM67_DAC_DMA) || \
+                              ((REMAP) == GPIO_Remap_TIM12) || ((REMAP) == GPIO_Remap_MISC))
+                              
+/**
+  * @}
+  */ 
+
+/** @defgroup GPIO_Port_Sources 
+  * @{
+  */
+
+#define GPIO_PortSourceGPIOA       ((uint8_t)0x00)
+#define GPIO_PortSourceGPIOB       ((uint8_t)0x01)
+#define GPIO_PortSourceGPIOC       ((uint8_t)0x02)
+#define GPIO_PortSourceGPIOD       ((uint8_t)0x03)
+#define GPIO_PortSourceGPIOE       ((uint8_t)0x04)
+#define GPIO_PortSourceGPIOF       ((uint8_t)0x05)
+#define GPIO_PortSourceGPIOG       ((uint8_t)0x06)
+#define IS_GPIO_EVENTOUT_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \
+                                                  ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \
+                                                  ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \
+                                                  ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \
+                                                  ((PORTSOURCE) == GPIO_PortSourceGPIOE))
+
+#define IS_GPIO_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOE) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOF) || \
+                                              ((PORTSOURCE) == GPIO_PortSourceGPIOG))
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Pin_sources 
+  * @{
+  */
+
+#define GPIO_PinSource0            ((uint8_t)0x00)
+#define GPIO_PinSource1            ((uint8_t)0x01)
+#define GPIO_PinSource2            ((uint8_t)0x02)
+#define GPIO_PinSource3            ((uint8_t)0x03)
+#define GPIO_PinSource4            ((uint8_t)0x04)
+#define GPIO_PinSource5            ((uint8_t)0x05)
+#define GPIO_PinSource6            ((uint8_t)0x06)
+#define GPIO_PinSource7            ((uint8_t)0x07)
+#define GPIO_PinSource8            ((uint8_t)0x08)
+#define GPIO_PinSource9            ((uint8_t)0x09)
+#define GPIO_PinSource10           ((uint8_t)0x0A)
+#define GPIO_PinSource11           ((uint8_t)0x0B)
+#define GPIO_PinSource12           ((uint8_t)0x0C)
+#define GPIO_PinSource13           ((uint8_t)0x0D)
+#define GPIO_PinSource14           ((uint8_t)0x0E)
+#define GPIO_PinSource15           ((uint8_t)0x0F)
+
+#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \
+                                       ((PINSOURCE) == GPIO_PinSource1) || \
+                                       ((PINSOURCE) == GPIO_PinSource2) || \
+                                       ((PINSOURCE) == GPIO_PinSource3) || \
+                                       ((PINSOURCE) == GPIO_PinSource4) || \
+                                       ((PINSOURCE) == GPIO_PinSource5) || \
+                                       ((PINSOURCE) == GPIO_PinSource6) || \
+                                       ((PINSOURCE) == GPIO_PinSource7) || \
+                                       ((PINSOURCE) == GPIO_PinSource8) || \
+                                       ((PINSOURCE) == GPIO_PinSource9) || \
+                                       ((PINSOURCE) == GPIO_PinSource10) || \
+                                       ((PINSOURCE) == GPIO_PinSource11) || \
+                                       ((PINSOURCE) == GPIO_PinSource12) || \
+                                       ((PINSOURCE) == GPIO_PinSource13) || \
+                                       ((PINSOURCE) == GPIO_PinSource14) || \
+                                       ((PINSOURCE) == GPIO_PinSource15))
+
+/**
+  * @}
+  */
+
+/** @defgroup Ethernet_Media_Interface 
+  * @{
+  */ 
+#define GPIO_ETH_MediaInterface_MII    ((u32)0x00000000) 
+#define GPIO_ETH_MediaInterface_RMII   ((u32)0x00000001)                                       
+
+#define IS_GPIO_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == GPIO_ETH_MediaInterface_MII) || \
+                                                ((INTERFACE) == GPIO_ETH_MediaInterface_RMII))
+
+/**
+  * @}
+  */                                                
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Exported_Functions
+  * @{
+  */
+
+void GPIO_DeInit(GPIO_TypeDef* GPIOx);
+void GPIO_AFIODeInit(void);
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
+void GPIO_EventOutputCmd(FunctionalState NewState);
+void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
+void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
+void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_GPIO_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_rcc.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,727 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_rcc.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the RCC firmware 
+  *          library.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_RCC_H
+#define __STM32F10x_RCC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup RCC
+  * @{
+  */
+
+/** @defgroup RCC_Exported_Types
+  * @{
+  */
+
+typedef struct
+{
+  uint32_t SYSCLK_Frequency;  /*!< returns SYSCLK clock frequency expressed in Hz */
+  uint32_t HCLK_Frequency;    /*!< returns HCLK clock frequency expressed in Hz */
+  uint32_t PCLK1_Frequency;   /*!< returns PCLK1 clock frequency expressed in Hz */
+  uint32_t PCLK2_Frequency;   /*!< returns PCLK2 clock frequency expressed in Hz */
+  uint32_t ADCCLK_Frequency;  /*!< returns ADCCLK clock frequency expressed in Hz */
+}RCC_ClocksTypeDef;
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Exported_Constants
+  * @{
+  */
+
+/** @defgroup HSE_configuration 
+  * @{
+  */
+
+#define RCC_HSE_OFF                      ((uint32_t)0x00000000)
+#define RCC_HSE_ON                       ((uint32_t)0x00010000)
+#define RCC_HSE_Bypass                   ((uint32_t)0x00040000)
+#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \
+                         ((HSE) == RCC_HSE_Bypass))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup PLL_entry_clock_source 
+  * @{
+  */
+
+#define RCC_PLLSource_HSI_Div2           ((uint32_t)0x00000000)
+
+#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_CL)
+ #define RCC_PLLSource_HSE_Div1           ((uint32_t)0x00010000)
+ #define RCC_PLLSource_HSE_Div2           ((uint32_t)0x00030000)
+ #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \
+                                   ((SOURCE) == RCC_PLLSource_HSE_Div1) || \
+                                   ((SOURCE) == RCC_PLLSource_HSE_Div2))
+#else
+ #define RCC_PLLSource_PREDIV1            ((uint32_t)0x00010000)
+ #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \
+                                   ((SOURCE) == RCC_PLLSource_PREDIV1))
+#endif /* STM32F10X_CL */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup PLL_multiplication_factor 
+  * @{
+  */
+#ifndef STM32F10X_CL
+ #define RCC_PLLMul_2                    ((uint32_t)0x00000000)
+ #define RCC_PLLMul_3                    ((uint32_t)0x00040000)
+ #define RCC_PLLMul_4                    ((uint32_t)0x00080000)
+ #define RCC_PLLMul_5                    ((uint32_t)0x000C0000)
+ #define RCC_PLLMul_6                    ((uint32_t)0x00100000)
+ #define RCC_PLLMul_7                    ((uint32_t)0x00140000)
+ #define RCC_PLLMul_8                    ((uint32_t)0x00180000)
+ #define RCC_PLLMul_9                    ((uint32_t)0x001C0000)
+ #define RCC_PLLMul_10                   ((uint32_t)0x00200000)
+ #define RCC_PLLMul_11                   ((uint32_t)0x00240000)
+ #define RCC_PLLMul_12                   ((uint32_t)0x00280000)
+ #define RCC_PLLMul_13                   ((uint32_t)0x002C0000)
+ #define RCC_PLLMul_14                   ((uint32_t)0x00300000)
+ #define RCC_PLLMul_15                   ((uint32_t)0x00340000)
+ #define RCC_PLLMul_16                   ((uint32_t)0x00380000)
+ #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_2) || ((MUL) == RCC_PLLMul_3)   || \
+                              ((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5)   || \
+                              ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7)   || \
+                              ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9)   || \
+                              ((MUL) == RCC_PLLMul_10) || ((MUL) == RCC_PLLMul_11) || \
+                              ((MUL) == RCC_PLLMul_12) || ((MUL) == RCC_PLLMul_13) || \
+                              ((MUL) == RCC_PLLMul_14) || ((MUL) == RCC_PLLMul_15) || \
+                              ((MUL) == RCC_PLLMul_16))
+
+#else
+ #define RCC_PLLMul_4                    ((uint32_t)0x00080000)
+ #define RCC_PLLMul_5                    ((uint32_t)0x000C0000)
+ #define RCC_PLLMul_6                    ((uint32_t)0x00100000)
+ #define RCC_PLLMul_7                    ((uint32_t)0x00140000)
+ #define RCC_PLLMul_8                    ((uint32_t)0x00180000)
+ #define RCC_PLLMul_9                    ((uint32_t)0x001C0000)
+ #define RCC_PLLMul_6_5                  ((uint32_t)0x00340000)
+
+ #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5) || \
+                              ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7) || \
+                              ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9) || \
+                              ((MUL) == RCC_PLLMul_6_5))
+#endif /* STM32F10X_CL */                              
+/**
+  * @}
+  */
+
+/** @defgroup PREDIV1_division_factor
+  * @{
+  */
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL)
+ #define  RCC_PREDIV1_Div1               ((uint32_t)0x00000000)
+ #define  RCC_PREDIV1_Div2               ((uint32_t)0x00000001)
+ #define  RCC_PREDIV1_Div3               ((uint32_t)0x00000002)
+ #define  RCC_PREDIV1_Div4               ((uint32_t)0x00000003)
+ #define  RCC_PREDIV1_Div5               ((uint32_t)0x00000004)
+ #define  RCC_PREDIV1_Div6               ((uint32_t)0x00000005)
+ #define  RCC_PREDIV1_Div7               ((uint32_t)0x00000006)
+ #define  RCC_PREDIV1_Div8               ((uint32_t)0x00000007)
+ #define  RCC_PREDIV1_Div9               ((uint32_t)0x00000008)
+ #define  RCC_PREDIV1_Div10              ((uint32_t)0x00000009)
+ #define  RCC_PREDIV1_Div11              ((uint32_t)0x0000000A)
+ #define  RCC_PREDIV1_Div12              ((uint32_t)0x0000000B)
+ #define  RCC_PREDIV1_Div13              ((uint32_t)0x0000000C)
+ #define  RCC_PREDIV1_Div14              ((uint32_t)0x0000000D)
+ #define  RCC_PREDIV1_Div15              ((uint32_t)0x0000000E)
+ #define  RCC_PREDIV1_Div16              ((uint32_t)0x0000000F)
+
+ #define IS_RCC_PREDIV1(PREDIV1) (((PREDIV1) == RCC_PREDIV1_Div1) || ((PREDIV1) == RCC_PREDIV1_Div2) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div3) || ((PREDIV1) == RCC_PREDIV1_Div4) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div5) || ((PREDIV1) == RCC_PREDIV1_Div6) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div7) || ((PREDIV1) == RCC_PREDIV1_Div8) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div9) || ((PREDIV1) == RCC_PREDIV1_Div10) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div11) || ((PREDIV1) == RCC_PREDIV1_Div12) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div13) || ((PREDIV1) == RCC_PREDIV1_Div14) || \
+                                  ((PREDIV1) == RCC_PREDIV1_Div15) || ((PREDIV1) == RCC_PREDIV1_Div16))
+#endif
+/**
+  * @}
+  */
+
+
+/** @defgroup PREDIV1_clock_source
+  * @{
+  */
+#ifdef STM32F10X_CL
+/* PREDIV1 clock source (for STM32 connectivity line devices) */
+ #define  RCC_PREDIV1_Source_HSE         ((uint32_t)0x00000000) 
+ #define  RCC_PREDIV1_Source_PLL2        ((uint32_t)0x00010000) 
+
+ #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE) || \
+                                        ((SOURCE) == RCC_PREDIV1_Source_PLL2)) 
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+/* PREDIV1 clock source (for STM32 Value line devices) */
+ #define  RCC_PREDIV1_Source_HSE         ((uint32_t)0x00000000) 
+
+ #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE)) 
+#endif
+/**
+  * @}
+  */
+
+#ifdef STM32F10X_CL
+/** @defgroup PREDIV2_division_factor
+  * @{
+  */
+  
+ #define  RCC_PREDIV2_Div1               ((uint32_t)0x00000000)
+ #define  RCC_PREDIV2_Div2               ((uint32_t)0x00000010)
+ #define  RCC_PREDIV2_Div3               ((uint32_t)0x00000020)
+ #define  RCC_PREDIV2_Div4               ((uint32_t)0x00000030)
+ #define  RCC_PREDIV2_Div5               ((uint32_t)0x00000040)
+ #define  RCC_PREDIV2_Div6               ((uint32_t)0x00000050)
+ #define  RCC_PREDIV2_Div7               ((uint32_t)0x00000060)
+ #define  RCC_PREDIV2_Div8               ((uint32_t)0x00000070)
+ #define  RCC_PREDIV2_Div9               ((uint32_t)0x00000080)
+ #define  RCC_PREDIV2_Div10              ((uint32_t)0x00000090)
+ #define  RCC_PREDIV2_Div11              ((uint32_t)0x000000A0)
+ #define  RCC_PREDIV2_Div12              ((uint32_t)0x000000B0)
+ #define  RCC_PREDIV2_Div13              ((uint32_t)0x000000C0)
+ #define  RCC_PREDIV2_Div14              ((uint32_t)0x000000D0)
+ #define  RCC_PREDIV2_Div15              ((uint32_t)0x000000E0)
+ #define  RCC_PREDIV2_Div16              ((uint32_t)0x000000F0)
+
+ #define IS_RCC_PREDIV2(PREDIV2) (((PREDIV2) == RCC_PREDIV2_Div1) || ((PREDIV2) == RCC_PREDIV2_Div2) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div3) || ((PREDIV2) == RCC_PREDIV2_Div4) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div5) || ((PREDIV2) == RCC_PREDIV2_Div6) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div7) || ((PREDIV2) == RCC_PREDIV2_Div8) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div9) || ((PREDIV2) == RCC_PREDIV2_Div10) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div11) || ((PREDIV2) == RCC_PREDIV2_Div12) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div13) || ((PREDIV2) == RCC_PREDIV2_Div14) || \
+                                  ((PREDIV2) == RCC_PREDIV2_Div15) || ((PREDIV2) == RCC_PREDIV2_Div16))
+/**
+  * @}
+  */
+
+
+/** @defgroup PLL2_multiplication_factor
+  * @{
+  */
+  
+ #define  RCC_PLL2Mul_8                  ((uint32_t)0x00000600)
+ #define  RCC_PLL2Mul_9                  ((uint32_t)0x00000700)
+ #define  RCC_PLL2Mul_10                 ((uint32_t)0x00000800)
+ #define  RCC_PLL2Mul_11                 ((uint32_t)0x00000900)
+ #define  RCC_PLL2Mul_12                 ((uint32_t)0x00000A00)
+ #define  RCC_PLL2Mul_13                 ((uint32_t)0x00000B00)
+ #define  RCC_PLL2Mul_14                 ((uint32_t)0x00000C00)
+ #define  RCC_PLL2Mul_16                 ((uint32_t)0x00000E00)
+ #define  RCC_PLL2Mul_20                 ((uint32_t)0x00000F00)
+
+ #define IS_RCC_PLL2_MUL(MUL) (((MUL) == RCC_PLL2Mul_8) || ((MUL) == RCC_PLL2Mul_9)  || \
+                               ((MUL) == RCC_PLL2Mul_10) || ((MUL) == RCC_PLL2Mul_11) || \
+                               ((MUL) == RCC_PLL2Mul_12) || ((MUL) == RCC_PLL2Mul_13) || \
+                               ((MUL) == RCC_PLL2Mul_14) || ((MUL) == RCC_PLL2Mul_16) || \
+                               ((MUL) == RCC_PLL2Mul_20))
+/**
+  * @}
+  */
+
+
+/** @defgroup PLL3_multiplication_factor
+  * @{
+  */
+
+ #define  RCC_PLL3Mul_8                  ((uint32_t)0x00006000)
+ #define  RCC_PLL3Mul_9                  ((uint32_t)0x00007000)
+ #define  RCC_PLL3Mul_10                 ((uint32_t)0x00008000)
+ #define  RCC_PLL3Mul_11                 ((uint32_t)0x00009000)
+ #define  RCC_PLL3Mul_12                 ((uint32_t)0x0000A000)
+ #define  RCC_PLL3Mul_13                 ((uint32_t)0x0000B000)
+ #define  RCC_PLL3Mul_14                 ((uint32_t)0x0000C000)
+ #define  RCC_PLL3Mul_16                 ((uint32_t)0x0000E000)
+ #define  RCC_PLL3Mul_20                 ((uint32_t)0x0000F000)
+
+ #define IS_RCC_PLL3_MUL(MUL) (((MUL) == RCC_PLL3Mul_8) || ((MUL) == RCC_PLL3Mul_9)  || \
+                               ((MUL) == RCC_PLL3Mul_10) || ((MUL) == RCC_PLL3Mul_11) || \
+                               ((MUL) == RCC_PLL3Mul_12) || ((MUL) == RCC_PLL3Mul_13) || \
+                               ((MUL) == RCC_PLL3Mul_14) || ((MUL) == RCC_PLL3Mul_16) || \
+                               ((MUL) == RCC_PLL3Mul_20))
+/**
+  * @}
+  */
+
+#endif /* STM32F10X_CL */
+
+
+/** @defgroup System_clock_source 
+  * @{
+  */
+
+#define RCC_SYSCLKSource_HSI             ((uint32_t)0x00000000)
+#define RCC_SYSCLKSource_HSE             ((uint32_t)0x00000001)
+#define RCC_SYSCLKSource_PLLCLK          ((uint32_t)0x00000002)
+#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \
+                                      ((SOURCE) == RCC_SYSCLKSource_HSE) || \
+                                      ((SOURCE) == RCC_SYSCLKSource_PLLCLK))
+/**
+  * @}
+  */
+
+/** @defgroup AHB_clock_source 
+  * @{
+  */
+
+#define RCC_SYSCLK_Div1                  ((uint32_t)0x00000000)
+#define RCC_SYSCLK_Div2                  ((uint32_t)0x00000080)
+#define RCC_SYSCLK_Div4                  ((uint32_t)0x00000090)
+#define RCC_SYSCLK_Div8                  ((uint32_t)0x000000A0)
+#define RCC_SYSCLK_Div16                 ((uint32_t)0x000000B0)
+#define RCC_SYSCLK_Div64                 ((uint32_t)0x000000C0)
+#define RCC_SYSCLK_Div128                ((uint32_t)0x000000D0)
+#define RCC_SYSCLK_Div256                ((uint32_t)0x000000E0)
+#define RCC_SYSCLK_Div512                ((uint32_t)0x000000F0)
+#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \
+                           ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \
+                           ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \
+                           ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \
+                           ((HCLK) == RCC_SYSCLK_Div512))
+/**
+  * @}
+  */ 
+
+/** @defgroup APB1_APB2_clock_source 
+  * @{
+  */
+
+#define RCC_HCLK_Div1                    ((uint32_t)0x00000000)
+#define RCC_HCLK_Div2                    ((uint32_t)0x00000400)
+#define RCC_HCLK_Div4                    ((uint32_t)0x00000500)
+#define RCC_HCLK_Div8                    ((uint32_t)0x00000600)
+#define RCC_HCLK_Div16                   ((uint32_t)0x00000700)
+#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \
+                           ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \
+                           ((PCLK) == RCC_HCLK_Div16))
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Interrupt_source 
+  * @{
+  */
+
+#define RCC_IT_LSIRDY                    ((uint8_t)0x01)
+#define RCC_IT_LSERDY                    ((uint8_t)0x02)
+#define RCC_IT_HSIRDY                    ((uint8_t)0x04)
+#define RCC_IT_HSERDY                    ((uint8_t)0x08)
+#define RCC_IT_PLLRDY                    ((uint8_t)0x10)
+#define RCC_IT_CSS                       ((uint8_t)0x80)
+
+#ifndef STM32F10X_CL
+ #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xE0) == 0x00) && ((IT) != 0x00))
+ #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \
+                            ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \
+                            ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS))
+ #define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x60) == 0x00) && ((IT) != 0x00))
+#else
+ #define RCC_IT_PLL2RDY                  ((uint8_t)0x20)
+ #define RCC_IT_PLL3RDY                  ((uint8_t)0x40)
+ #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00))
+ #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \
+                            ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \
+                            ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \
+                            ((IT) == RCC_IT_PLL2RDY) || ((IT) == RCC_IT_PLL3RDY))
+ #define IS_RCC_CLEAR_IT(IT) ((IT) != 0x00)
+#endif /* STM32F10X_CL */ 
+
+
+/**
+  * @}
+  */
+
+#ifndef STM32F10X_CL
+/** @defgroup USB_Device_clock_source 
+  * @{
+  */
+
+ #define RCC_USBCLKSource_PLLCLK_1Div5   ((uint8_t)0x00)
+ #define RCC_USBCLKSource_PLLCLK_Div1    ((uint8_t)0x01)
+
+ #define IS_RCC_USBCLK_SOURCE(SOURCE) (((SOURCE) == RCC_USBCLKSource_PLLCLK_1Div5) || \
+                                      ((SOURCE) == RCC_USBCLKSource_PLLCLK_Div1))
+/**
+  * @}
+  */
+#else
+/** @defgroup USB_OTG_FS_clock_source 
+  * @{
+  */
+ #define RCC_OTGFSCLKSource_PLLVCO_Div3    ((uint8_t)0x00)
+ #define RCC_OTGFSCLKSource_PLLVCO_Div2    ((uint8_t)0x01)
+
+ #define IS_RCC_OTGFSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div3) || \
+                                         ((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div2))
+/**
+  * @}
+  */
+#endif /* STM32F10X_CL */ 
+
+
+#ifdef STM32F10X_CL
+/** @defgroup I2S2_clock_source 
+  * @{
+  */
+ #define RCC_I2S2CLKSource_SYSCLK        ((uint8_t)0x00)
+ #define RCC_I2S2CLKSource_PLL3_VCO      ((uint8_t)0x01)
+
+ #define IS_RCC_I2S2CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_SYSCLK) || \
+                                        ((SOURCE) == RCC_I2S2CLKSource_PLL3_VCO))
+/**
+  * @}
+  */
+
+/** @defgroup I2S3_clock_source 
+  * @{
+  */
+ #define RCC_I2S3CLKSource_SYSCLK        ((uint8_t)0x00)
+ #define RCC_I2S3CLKSource_PLL3_VCO      ((uint8_t)0x01)
+
+ #define IS_RCC_I2S3CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S3CLKSource_SYSCLK) || \
+                                        ((SOURCE) == RCC_I2S3CLKSource_PLL3_VCO))    
+/**
+  * @}
+  */
+#endif /* STM32F10X_CL */  
+  
+
+/** @defgroup ADC_clock_source 
+  * @{
+  */
+
+#define RCC_PCLK2_Div2                   ((uint32_t)0x00000000)
+#define RCC_PCLK2_Div4                   ((uint32_t)0x00004000)
+#define RCC_PCLK2_Div6                   ((uint32_t)0x00008000)
+#define RCC_PCLK2_Div8                   ((uint32_t)0x0000C000)
+#define IS_RCC_ADCCLK(ADCCLK) (((ADCCLK) == RCC_PCLK2_Div2) || ((ADCCLK) == RCC_PCLK2_Div4) || \
+                               ((ADCCLK) == RCC_PCLK2_Div6) || ((ADCCLK) == RCC_PCLK2_Div8))
+/**
+  * @}
+  */
+
+/** @defgroup LSE_configuration 
+  * @{
+  */
+
+#define RCC_LSE_OFF                      ((uint8_t)0x00)
+#define RCC_LSE_ON                       ((uint8_t)0x01)
+#define RCC_LSE_Bypass                   ((uint8_t)0x04)
+#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \
+                         ((LSE) == RCC_LSE_Bypass))
+/**
+  * @}
+  */
+
+/** @defgroup RTC_clock_source 
+  * @{
+  */
+
+#define RCC_RTCCLKSource_LSE             ((uint32_t)0x00000100)
+#define RCC_RTCCLKSource_LSI             ((uint32_t)0x00000200)
+#define RCC_RTCCLKSource_HSE_Div128      ((uint32_t)0x00000300)
+#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \
+                                      ((SOURCE) == RCC_RTCCLKSource_LSI) || \
+                                      ((SOURCE) == RCC_RTCCLKSource_HSE_Div128))
+/**
+  * @}
+  */
+
+/** @defgroup AHB_peripheral 
+  * @{
+  */
+
+#define RCC_AHBPeriph_DMA1               ((uint32_t)0x00000001)
+#define RCC_AHBPeriph_DMA2               ((uint32_t)0x00000002)
+#define RCC_AHBPeriph_SRAM               ((uint32_t)0x00000004)
+#define RCC_AHBPeriph_FLITF              ((uint32_t)0x00000010)
+#define RCC_AHBPeriph_CRC                ((uint32_t)0x00000040)
+
+#ifndef STM32F10X_CL
+ #define RCC_AHBPeriph_FSMC              ((uint32_t)0x00000100)
+ #define RCC_AHBPeriph_SDIO              ((uint32_t)0x00000400)
+ #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFAA8) == 0x00) && ((PERIPH) != 0x00))
+#else
+ #define RCC_AHBPeriph_OTG_FS            ((uint32_t)0x00001000)
+ #define RCC_AHBPeriph_ETH_MAC           ((uint32_t)0x00004000)
+ #define RCC_AHBPeriph_ETH_MAC_Tx        ((uint32_t)0x00008000)
+ #define RCC_AHBPeriph_ETH_MAC_Rx        ((uint32_t)0x00010000)
+
+ #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFE2FA8) == 0x00) && ((PERIPH) != 0x00))
+ #define IS_RCC_AHB_PERIPH_RESET(PERIPH) ((((PERIPH) & 0xFFFFAFFF) == 0x00) && ((PERIPH) != 0x00))
+#endif /* STM32F10X_CL */
+/**
+  * @}
+  */
+
+/** @defgroup APB2_peripheral 
+  * @{
+  */
+
+#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)
+#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
+#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
+#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
+#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
+#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)
+#define RCC_APB2Periph_GPIOF             ((uint32_t)0x00000080)
+#define RCC_APB2Periph_GPIOG             ((uint32_t)0x00000100)
+#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)
+#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000400)
+#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000800)
+#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)
+#define RCC_APB2Periph_TIM8              ((uint32_t)0x00002000)
+#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)
+#define RCC_APB2Periph_ADC3              ((uint32_t)0x00008000)
+#define RCC_APB2Periph_TIM15             ((uint32_t)0x00010000)
+#define RCC_APB2Periph_TIM16             ((uint32_t)0x00020000)
+#define RCC_APB2Periph_TIM17             ((uint32_t)0x00040000)
+#define RCC_APB2Periph_TIM9              ((uint32_t)0x00080000)
+#define RCC_APB2Periph_TIM10             ((uint32_t)0x00100000)
+#define RCC_APB2Periph_TIM11             ((uint32_t)0x00200000)
+
+#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))
+/**
+  * @}
+  */ 
+
+/** @defgroup APB1_peripheral 
+  * @{
+  */
+
+#define RCC_APB1Periph_TIM2              ((uint32_t)0x00000001)
+#define RCC_APB1Periph_TIM3              ((uint32_t)0x00000002)
+#define RCC_APB1Periph_TIM4              ((uint32_t)0x00000004)
+#define RCC_APB1Periph_TIM5              ((uint32_t)0x00000008)
+#define RCC_APB1Periph_TIM6              ((uint32_t)0x00000010)
+#define RCC_APB1Periph_TIM7              ((uint32_t)0x00000020)
+#define RCC_APB1Periph_TIM12             ((uint32_t)0x00000040)
+#define RCC_APB1Periph_TIM13             ((uint32_t)0x00000080)
+#define RCC_APB1Periph_TIM14             ((uint32_t)0x00000100)
+#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)
+#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)
+#define RCC_APB1Periph_SPI3              ((uint32_t)0x00008000)
+#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
+#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)
+#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)
+#define RCC_APB1Periph_UART5             ((uint32_t)0x00100000)
+#define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)
+#define RCC_APB1Periph_I2C2              ((uint32_t)0x00400000)
+#define RCC_APB1Periph_USB               ((uint32_t)0x00800000)
+#define RCC_APB1Periph_CAN1              ((uint32_t)0x02000000)
+#define RCC_APB1Periph_CAN2              ((uint32_t)0x04000000)
+#define RCC_APB1Periph_BKP               ((uint32_t)0x08000000)
+#define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)
+#define RCC_APB1Periph_DAC               ((uint32_t)0x20000000)
+#define RCC_APB1Periph_CEC               ((uint32_t)0x40000000)
+ 
+#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x81013600) == 0x00) && ((PERIPH) != 0x00))
+
+/**
+  * @}
+  */
+
+/** @defgroup Clock_source_to_output_on_MCO_pin 
+  * @{
+  */
+
+#define RCC_MCO_NoClock                  ((uint8_t)0x00)
+#define RCC_MCO_SYSCLK                   ((uint8_t)0x04)
+#define RCC_MCO_HSI                      ((uint8_t)0x05)
+#define RCC_MCO_HSE                      ((uint8_t)0x06)
+#define RCC_MCO_PLLCLK_Div2              ((uint8_t)0x07)
+
+#ifndef STM32F10X_CL
+ #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \
+                          ((MCO) == RCC_MCO_SYSCLK)  || ((MCO) == RCC_MCO_HSE) || \
+                          ((MCO) == RCC_MCO_PLLCLK_Div2))
+#else
+ #define RCC_MCO_PLL2CLK                 ((uint8_t)0x08)
+ #define RCC_MCO_PLL3CLK_Div2            ((uint8_t)0x09)
+ #define RCC_MCO_XT1                     ((uint8_t)0x0A)
+ #define RCC_MCO_PLL3CLK                 ((uint8_t)0x0B)
+
+ #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \
+                          ((MCO) == RCC_MCO_SYSCLK)  || ((MCO) == RCC_MCO_HSE) || \
+                          ((MCO) == RCC_MCO_PLLCLK_Div2) || ((MCO) == RCC_MCO_PLL2CLK) || \
+                          ((MCO) == RCC_MCO_PLL3CLK_Div2) || ((MCO) == RCC_MCO_XT1) || \
+                          ((MCO) == RCC_MCO_PLL3CLK))
+#endif /* STM32F10X_CL */ 
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Flag 
+  * @{
+  */
+
+#define RCC_FLAG_HSIRDY                  ((uint8_t)0x21)
+#define RCC_FLAG_HSERDY                  ((uint8_t)0x31)
+#define RCC_FLAG_PLLRDY                  ((uint8_t)0x39)
+#define RCC_FLAG_LSERDY                  ((uint8_t)0x41)
+#define RCC_FLAG_LSIRDY                  ((uint8_t)0x61)
+#define RCC_FLAG_PINRST                  ((uint8_t)0x7A)
+#define RCC_FLAG_PORRST                  ((uint8_t)0x7B)
+#define RCC_FLAG_SFTRST                  ((uint8_t)0x7C)
+#define RCC_FLAG_IWDGRST                 ((uint8_t)0x7D)
+#define RCC_FLAG_WWDGRST                 ((uint8_t)0x7E)
+#define RCC_FLAG_LPWRRST                 ((uint8_t)0x7F)
+
+#ifndef STM32F10X_CL
+ #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \
+                            ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \
+                            ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \
+                            ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \
+                            ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \
+                            ((FLAG) == RCC_FLAG_LPWRRST))
+#else
+ #define RCC_FLAG_PLL2RDY                ((uint8_t)0x3B) 
+ #define RCC_FLAG_PLL3RDY                ((uint8_t)0x3D) 
+ #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \
+                            ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \
+                            ((FLAG) == RCC_FLAG_PLL2RDY) || ((FLAG) == RCC_FLAG_PLL3RDY) || \
+                            ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \
+                            ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \
+                            ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \
+                            ((FLAG) == RCC_FLAG_LPWRRST))
+#endif /* STM32F10X_CL */ 
+
+#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F)
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Exported_Functions
+  * @{
+  */
+
+void RCC_DeInit(void);
+void RCC_HSEConfig(uint32_t RCC_HSE);
+ErrorStatus RCC_WaitForHSEStartUp(void);
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);
+void RCC_HSICmd(FunctionalState NewState);
+void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
+void RCC_PLLCmd(FunctionalState NewState);
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL)
+ void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div);
+#endif
+
+#ifdef  STM32F10X_CL
+ void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div);
+ void RCC_PLL2Config(uint32_t RCC_PLL2Mul);
+ void RCC_PLL2Cmd(FunctionalState NewState);
+ void RCC_PLL3Config(uint32_t RCC_PLL3Mul);
+ void RCC_PLL3Cmd(FunctionalState NewState);
+#endif /* STM32F10X_CL */ 
+
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
+uint8_t RCC_GetSYSCLKSource(void);
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
+void RCC_PCLK1Config(uint32_t RCC_HCLK);
+void RCC_PCLK2Config(uint32_t RCC_HCLK);
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);
+
+#ifndef STM32F10X_CL
+ void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource);
+#else
+ void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource);
+#endif /* STM32F10X_CL */ 
+
+void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
+
+#ifdef STM32F10X_CL
+ void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource);                                  
+ void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource);
+#endif /* STM32F10X_CL */ 
+
+void RCC_LSEConfig(uint8_t RCC_LSE);
+void RCC_LSICmd(FunctionalState NewState);
+void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
+void RCC_RTCCLKCmd(FunctionalState NewState);
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
+void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+
+#ifdef STM32F10X_CL
+void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
+#endif /* STM32F10X_CL */ 
+
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+void RCC_BackupResetCmd(FunctionalState NewState);
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState);
+void RCC_MCOConfig(uint8_t RCC_MCO);
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
+void RCC_ClearFlag(void);
+ITStatus RCC_GetITStatus(uint8_t RCC_IT);
+void RCC_ClearITPendingBit(uint8_t RCC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_RCC_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_tim.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1137 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_tim.h
+  * @author  MCD Application Team
+  * @version V3.4.0
+  * @date    10/15/2010
+  * @brief   This file contains all the functions prototypes for the TIM firmware 
+  *          library.
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_TIM_H
+#define __STM32F10x_TIM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup TIM
+  * @{
+  */ 
+
+/** @defgroup TIM_Exported_Types
+  * @{
+  */ 
+
+/** 
+  * @brief  TIM Time Base Init structure definition
+  * @note   This sturcture is used with all TIMx except for TIM6 and TIM7.    
+  */
+
+typedef struct
+{
+  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
+                                       This parameter can be a number between 0x0000 and 0xFFFF */
+
+  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
+                                       This parameter can be a value of @ref TIM_Counter_Mode */
+
+  uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
+                                       Auto-Reload Register at the next update event.
+                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 
+
+  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
+                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */
+
+  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
+                                       reaches zero, an update event is generated and counting restarts
+                                       from the RCR value (N).
+                                       This means in PWM mode that (N+1) corresponds to:
+                                          - the number of PWM periods in edge-aligned mode
+                                          - the number of half PWM period in center-aligned mode
+                                       This parameter must be a number between 0x00 and 0xFF. 
+                                       @note This parameter is valid only for TIM1 and TIM8. */
+} TIM_TimeBaseInitTypeDef;       
+
+/** 
+  * @brief  TIM Output Compare Init structure definition  
+  */
+
+typedef struct
+{
+  uint16_t TIM_OCMode;        /*!< Specifies the TIM mode.
+                                   This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
+
+  uint16_t TIM_OutputState;   /*!< Specifies the TIM Output Compare state.
+                                   This parameter can be a value of @ref TIM_Output_Compare_state */
+
+  uint16_t TIM_OutputNState;  /*!< Specifies the TIM complementary Output Compare state.
+                                   This parameter can be a value of @ref TIM_Output_Compare_N_state
+                                   @note This parameter is valid only for TIM1 and TIM8. */
+
+  uint16_t TIM_Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register. 
+                                   This parameter can be a number between 0x0000 and 0xFFFF */
+
+  uint16_t TIM_OCPolarity;    /*!< Specifies the output polarity.
+                                   This parameter can be a value of @ref TIM_Output_Compare_Polarity */
+
+  uint16_t TIM_OCNPolarity;   /*!< Specifies the complementary output polarity.
+                                   This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
+                                   @note This parameter is valid only for TIM1 and TIM8. */
+
+  uint16_t TIM_OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
+                                   This parameter can be a value of @ref TIM_Output_Compare_Idle_State
+                                   @note This parameter is valid only for TIM1 and TIM8. */
+
+  uint16_t TIM_OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
+                                   This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
+                                   @note This parameter is valid only for TIM1 and TIM8. */
+} TIM_OCInitTypeDef;
+
+/** 
+  * @brief  TIM Input Capture Init structure definition  
+  */
+
+typedef struct
+{
+
+  uint16_t TIM_Channel;      /*!< Specifies the TIM channel.
+                                  This parameter can be a value of @ref TIM_Channel */
+
+  uint16_t TIM_ICPolarity;   /*!< Specifies the active edge of the input signal.
+                                  This parameter can be a value of @ref TIM_Input_Capture_Polarity */
+
+  uint16_t TIM_ICSelection;  /*!< Specifies the input.
+                                  This parameter can be a value of @ref TIM_Input_Capture_Selection */
+
+  uint16_t TIM_ICPrescaler;  /*!< Specifies the Input Capture Prescaler.
+                                  This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
+
+  uint16_t TIM_ICFilter;     /*!< Specifies the input capture filter.
+                                  This parameter can be a number between 0x0 and 0xF */
+} TIM_ICInitTypeDef;
+
+/** 
+  * @brief  BDTR structure definition 
+  * @note   This sturcture is used only with TIM1 and TIM8.    
+  */
+
+typedef struct
+{
+
+  uint16_t TIM_OSSRState;        /*!< Specifies the Off-State selection used in Run mode.
+                                      This parameter can be a value of @ref OSSR_Off_State_Selection_for_Run_mode_state */
+
+  uint16_t TIM_OSSIState;        /*!< Specifies the Off-State used in Idle state.
+                                      This parameter can be a value of @ref OSSI_Off_State_Selection_for_Idle_mode_state */
+
+  uint16_t TIM_LOCKLevel;        /*!< Specifies the LOCK level parameters.
+                                      This parameter can be a value of @ref Lock_level */ 
+
+  uint16_t TIM_DeadTime;         /*!< Specifies the delay time between the switching-off and the
+                                      switching-on of the outputs.
+                                      This parameter can be a number between 0x00 and 0xFF  */
+
+  uint16_t TIM_Break;            /*!< Specifies whether the TIM Break input is enabled or not. 
+                                      This parameter can be a value of @ref Break_Input_enable_disable */
+
+  uint16_t TIM_BreakPolarity;    /*!< Specifies the TIM Break Input pin polarity.
+                                      This parameter can be a value of @ref Break_Polarity */
+
+  uint16_t TIM_AutomaticOutput;  /*!< Specifies whether the TIM Automatic Output feature is enabled or not. 
+                                      This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
+} TIM_BDTRInitTypeDef;
+
+/** @defgroup TIM_Exported_constants 
+  * @{
+  */
+
+#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+                                   ((PERIPH) == TIM2) || \
+                                   ((PERIPH) == TIM3) || \
+                                   ((PERIPH) == TIM4) || \
+                                   ((PERIPH) == TIM5) || \
+                                   ((PERIPH) == TIM6) || \
+                                   ((PERIPH) == TIM7) || \
+                                   ((PERIPH) == TIM8) || \
+                                   ((PERIPH) == TIM9) || \
+                                   ((PERIPH) == TIM10)|| \
+                                   ((PERIPH) == TIM11)|| \
+                                   ((PERIPH) == TIM12)|| \
+                                   ((PERIPH) == TIM13)|| \
+                                   ((PERIPH) == TIM14)|| \
+                                   ((PERIPH) == TIM15)|| \
+                                   ((PERIPH) == TIM16)|| \
+                                   ((PERIPH) == TIM17))
+
+/* LIST1: TIM 1 and 8 */
+#define IS_TIM_LIST1_PERIPH(PERIPH)  (((PERIPH) == TIM1) || \
+                                      ((PERIPH) == TIM8))
+
+/* LIST2: TIM 1, 8, 15 16 and 17 */
+#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+                                     ((PERIPH) == TIM8) || \
+                                     ((PERIPH) == TIM15)|| \
+                                     ((PERIPH) == TIM16)|| \
+                                     ((PERIPH) == TIM17)) 
+
+/* LIST3: TIM 1, 2, 3, 4, 5 and 8 */
+#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+                                     ((PERIPH) == TIM2) || \
+                                     ((PERIPH) == TIM3) || \
+                                     ((PERIPH) == TIM4) || \
+                                     ((PERIPH) == TIM5) || \
+                                     ((PERIPH) == TIM8)) 
+									                                 
+/* LIST4: TIM 1, 2, 3, 4, 5, 8, 15, 16 and 17 */
+#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+                                     ((PERIPH) == TIM2) || \
+                                     ((PERIPH) == TIM3) || \
+                                     ((PERIPH) == TIM4) || \
+                                     ((PERIPH) == TIM5) || \
+                                     ((PERIPH) == TIM8) || \
+                                     ((PERIPH) == TIM15)|| \
+                                     ((PERIPH) == TIM16)|| \
+                                     ((PERIPH) == TIM17))
+
+/* LIST5: TIM 1, 2, 3, 4, 5, 8 and 15 */                                            
+#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+                                     ((PERIPH) == TIM2) || \
+                                     ((PERIPH) == TIM3) || \
+                                     ((PERIPH) == TIM4) || \
+                                     ((PERIPH) == TIM5) || \
+                                     ((PERIPH) == TIM8) || \
+                                     ((PERIPH) == TIM15)) 
+
+/* LIST6: TIM 1, 2, 3, 4, 5, 8, 9, 12 and 15 */
+#define IS_TIM_LIST6_PERIPH(PERIPH)  (((PERIPH) == TIM1) || \
+                                      ((PERIPH) == TIM2) || \
+                                      ((PERIPH) == TIM3) || \
+                                      ((PERIPH) == TIM4) || \
+                                      ((PERIPH) == TIM5) || \
+                                      ((PERIPH) == TIM8) || \
+                                      ((PERIPH) == TIM9) || \
+									  ((PERIPH) == TIM12)|| \
+                                      ((PERIPH) == TIM15))
+
+/* LIST7: TIM 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 and 15 */
+#define IS_TIM_LIST7_PERIPH(PERIPH)  (((PERIPH) == TIM1) || \
+                                      ((PERIPH) == TIM2) || \
+                                      ((PERIPH) == TIM3) || \
+                                      ((PERIPH) == TIM4) || \
+                                      ((PERIPH) == TIM5) || \
+                                      ((PERIPH) == TIM6) || \
+                                      ((PERIPH) == TIM7) || \
+                                      ((PERIPH) == TIM8) || \
+                                      ((PERIPH) == TIM9) || \
+                                      ((PERIPH) == TIM12)|| \
+                                      ((PERIPH) == TIM15))                                    
+
+/* LIST8: TIM 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16 and 17 */                                        
+#define IS_TIM_LIST8_PERIPH(PERIPH)  (((PERIPH) == TIM1) || \
+                                      ((PERIPH) == TIM2) || \
+                                      ((PERIPH) == TIM3) || \
+                                      ((PERIPH) == TIM4) || \
+                                      ((PERIPH) == TIM5) || \
+                                      ((PERIPH) == TIM8) || \
+                                      ((PERIPH) == TIM9) || \
+                                      ((PERIPH) == TIM10)|| \
+                                      ((PERIPH) == TIM11)|| \
+                                      ((PERIPH) == TIM12)|| \
+                                      ((PERIPH) == TIM13)|| \
+                                      ((PERIPH) == TIM14)|| \
+                                      ((PERIPH) == TIM15)|| \
+                                      ((PERIPH) == TIM16)|| \
+                                      ((PERIPH) == TIM17))
+
+/* LIST9: TIM 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, and 17 */
+#define IS_TIM_LIST9_PERIPH(PERIPH)  (((PERIPH) == TIM1) || \
+                                      ((PERIPH) == TIM2) || \
+                                      ((PERIPH) == TIM3) || \
+                                      ((PERIPH) == TIM4) || \
+                                      ((PERIPH) == TIM5) || \
+                                      ((PERIPH) == TIM6) || \
+                                      ((PERIPH) == TIM7) || \
+                                      ((PERIPH) == TIM8) || \
+                                      ((PERIPH) == TIM15)|| \
+                                      ((PERIPH) == TIM16)|| \
+                                      ((PERIPH) == TIM17))  
+                                                                                                                                                                                                                          
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Output_Compare_and_PWM_modes 
+  * @{
+  */
+
+#define TIM_OCMode_Timing                  ((uint16_t)0x0000)
+#define TIM_OCMode_Active                  ((uint16_t)0x0010)
+#define TIM_OCMode_Inactive                ((uint16_t)0x0020)
+#define TIM_OCMode_Toggle                  ((uint16_t)0x0030)
+#define TIM_OCMode_PWM1                    ((uint16_t)0x0060)
+#define TIM_OCMode_PWM2                    ((uint16_t)0x0070)
+#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \
+                              ((MODE) == TIM_OCMode_Active) || \
+                              ((MODE) == TIM_OCMode_Inactive) || \
+                              ((MODE) == TIM_OCMode_Toggle)|| \
+                              ((MODE) == TIM_OCMode_PWM1) || \
+                              ((MODE) == TIM_OCMode_PWM2))
+#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \
+                          ((MODE) == TIM_OCMode_Active) || \
+                          ((MODE) == TIM_OCMode_Inactive) || \
+                          ((MODE) == TIM_OCMode_Toggle)|| \
+                          ((MODE) == TIM_OCMode_PWM1) || \
+                          ((MODE) == TIM_OCMode_PWM2) ||	\
+                          ((MODE) == TIM_ForcedAction_Active) || \
+                          ((MODE) == TIM_ForcedAction_InActive))
+/**
+  * @}
+  */
+
+/** @defgroup TIM_One_Pulse_Mode 
+  * @{
+  */
+
+#define TIM_OPMode_Single                  ((uint16_t)0x0008)
+#define TIM_OPMode_Repetitive              ((uint16_t)0x0000)
+#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \
+                               ((MODE) == TIM_OPMode_Repetitive))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Channel 
+  * @{
+  */
+
+#define TIM_Channel_1                      ((uint16_t)0x0000)
+#define TIM_Channel_2                      ((uint16_t)0x0004)
+#define TIM_Channel_3                      ((uint16_t)0x0008)
+#define TIM_Channel_4                      ((uint16_t)0x000C)
+#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+                                 ((CHANNEL) == TIM_Channel_2) || \
+                                 ((CHANNEL) == TIM_Channel_3) || \
+                                 ((CHANNEL) == TIM_Channel_4))
+#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+                                      ((CHANNEL) == TIM_Channel_2))
+#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+                                               ((CHANNEL) == TIM_Channel_2) || \
+                                               ((CHANNEL) == TIM_Channel_3))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Clock_Division_CKD 
+  * @{
+  */
+
+#define TIM_CKD_DIV1                       ((uint16_t)0x0000)
+#define TIM_CKD_DIV2                       ((uint16_t)0x0100)
+#define TIM_CKD_DIV4                       ((uint16_t)0x0200)
+#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
+                             ((DIV) == TIM_CKD_DIV2) || \
+                             ((DIV) == TIM_CKD_DIV4))
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Counter_Mode 
+  * @{
+  */
+
+#define TIM_CounterMode_Up                 ((uint16_t)0x0000)
+#define TIM_CounterMode_Down               ((uint16_t)0x0010)
+#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)
+#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)
+#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)
+#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) ||  \
+                                   ((MODE) == TIM_CounterMode_Down) || \
+                                   ((MODE) == TIM_CounterMode_CenterAligned1) || \
+                                   ((MODE) == TIM_CounterMode_CenterAligned2) || \
+                                   ((MODE) == TIM_CounterMode_CenterAligned3))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Output_Compare_Polarity 
+  * @{
+  */
+
+#define TIM_OCPolarity_High                ((uint16_t)0x0000)
+#define TIM_OCPolarity_Low                 ((uint16_t)0x0002)
+#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \
+                                      ((POLARITY) == TIM_OCPolarity_Low))
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Output_Compare_N_Polarity 
+  * @{
+  */
+  
+#define TIM_OCNPolarity_High               ((uint16_t)0x0000)
+#define TIM_OCNPolarity_Low                ((uint16_t)0x0008)
+#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \
+                                       ((POLARITY) == TIM_OCNPolarity_Low))
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Output_Compare_state 
+  * @{
+  */
+
+#define TIM_OutputState_Disable            ((uint16_t)0x0000)
+#define TIM_OutputState_Enable             ((uint16_t)0x0001)
+#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \
+                                    ((STATE) == TIM_OutputState_Enable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Output_Compare_N_state 
+  * @{
+  */
+
+#define TIM_OutputNState_Disable           ((uint16_t)0x0000)
+#define TIM_OutputNState_Enable            ((uint16_t)0x0004)
+#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \
+                                     ((STATE) == TIM_OutputNState_Enable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Capture_Compare_state 
+  * @{
+  */
+
+#define TIM_CCx_Enable                      ((uint16_t)0x0001)
+#define TIM_CCx_Disable                     ((uint16_t)0x0000)
+#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \
+                         ((CCX) == TIM_CCx_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Capture_Compare_N_state 
+  * @{
+  */
+
+#define TIM_CCxN_Enable                     ((uint16_t)0x0004)
+#define TIM_CCxN_Disable                    ((uint16_t)0x0000)
+#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \
+                           ((CCXN) == TIM_CCxN_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup Break_Input_enable_disable 
+  * @{
+  */
+
+#define TIM_Break_Enable                   ((uint16_t)0x1000)
+#define TIM_Break_Disable                  ((uint16_t)0x0000)
+#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \
+                                   ((STATE) == TIM_Break_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup Break_Polarity 
+  * @{
+  */
+
+#define TIM_BreakPolarity_Low              ((uint16_t)0x0000)
+#define TIM_BreakPolarity_High             ((uint16_t)0x2000)
+#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \
+                                         ((POLARITY) == TIM_BreakPolarity_High))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_AOE_Bit_Set_Reset 
+  * @{
+  */
+
+#define TIM_AutomaticOutput_Enable         ((uint16_t)0x4000)
+#define TIM_AutomaticOutput_Disable        ((uint16_t)0x0000)
+#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \
+                                              ((STATE) == TIM_AutomaticOutput_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup Lock_level 
+  * @{
+  */
+
+#define TIM_LOCKLevel_OFF                  ((uint16_t)0x0000)
+#define TIM_LOCKLevel_1                    ((uint16_t)0x0100)
+#define TIM_LOCKLevel_2                    ((uint16_t)0x0200)
+#define TIM_LOCKLevel_3                    ((uint16_t)0x0300)
+#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \
+                                  ((LEVEL) == TIM_LOCKLevel_1) || \
+                                  ((LEVEL) == TIM_LOCKLevel_2) || \
+                                  ((LEVEL) == TIM_LOCKLevel_3))
+/**
+  * @}
+  */ 
+
+/** @defgroup OSSI_Off_State_Selection_for_Idle_mode_state 
+  * @{
+  */
+
+#define TIM_OSSIState_Enable               ((uint16_t)0x0400)
+#define TIM_OSSIState_Disable              ((uint16_t)0x0000)
+#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \
+                                  ((STATE) == TIM_OSSIState_Disable))
+/**
+  * @}
+  */
+
+/** @defgroup OSSR_Off_State_Selection_for_Run_mode_state 
+  * @{
+  */
+
+#define TIM_OSSRState_Enable               ((uint16_t)0x0800)
+#define TIM_OSSRState_Disable              ((uint16_t)0x0000)
+#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \
+                                  ((STATE) == TIM_OSSRState_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Output_Compare_Idle_State 
+  * @{
+  */
+
+#define TIM_OCIdleState_Set                ((uint16_t)0x0100)
+#define TIM_OCIdleState_Reset              ((uint16_t)0x0000)
+#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \
+                                    ((STATE) == TIM_OCIdleState_Reset))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Output_Compare_N_Idle_State 
+  * @{
+  */
+
+#define TIM_OCNIdleState_Set               ((uint16_t)0x0200)
+#define TIM_OCNIdleState_Reset             ((uint16_t)0x0000)
+#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \
+                                     ((STATE) == TIM_OCNIdleState_Reset))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Input_Capture_Polarity 
+  * @{
+  */
+
+#define  TIM_ICPolarity_Rising             ((uint16_t)0x0000)
+#define  TIM_ICPolarity_Falling            ((uint16_t)0x0002)
+#define  TIM_ICPolarity_BothEdge           ((uint16_t)0x000A)
+#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
+                                      ((POLARITY) == TIM_ICPolarity_Falling))
+#define IS_TIM_IC_POLARITY_LITE(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
+                                           ((POLARITY) == TIM_ICPolarity_Falling)|| \
+                                           ((POLARITY) == TIM_ICPolarity_BothEdge))                                      
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Input_Capture_Selection 
+  * @{
+  */
+
+#define TIM_ICSelection_DirectTI           ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be 
+                                                                   connected to IC1, IC2, IC3 or IC4, respectively */
+#define TIM_ICSelection_IndirectTI         ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be
+                                                                   connected to IC2, IC1, IC4 or IC3, respectively. */
+#define TIM_ICSelection_TRC                ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */
+#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \
+                                        ((SELECTION) == TIM_ICSelection_IndirectTI) || \
+                                        ((SELECTION) == TIM_ICSelection_TRC))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Input_Capture_Prescaler 
+  * @{
+  */
+
+#define TIM_ICPSC_DIV1                     ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */
+#define TIM_ICPSC_DIV2                     ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */
+#define TIM_ICPSC_DIV4                     ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */
+#define TIM_ICPSC_DIV8                     ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */
+#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \
+                                        ((PRESCALER) == TIM_ICPSC_DIV2) || \
+                                        ((PRESCALER) == TIM_ICPSC_DIV4) || \
+                                        ((PRESCALER) == TIM_ICPSC_DIV8))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_interrupt_sources 
+  * @{
+  */
+
+#define TIM_IT_Update                      ((uint16_t)0x0001)
+#define TIM_IT_CC1                         ((uint16_t)0x0002)
+#define TIM_IT_CC2                         ((uint16_t)0x0004)
+#define TIM_IT_CC3                         ((uint16_t)0x0008)
+#define TIM_IT_CC4                         ((uint16_t)0x0010)
+#define TIM_IT_COM                         ((uint16_t)0x0020)
+#define TIM_IT_Trigger                     ((uint16_t)0x0040)
+#define TIM_IT_Break                       ((uint16_t)0x0080)
+#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000))
+
+#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \
+                           ((IT) == TIM_IT_CC1) || \
+                           ((IT) == TIM_IT_CC2) || \
+                           ((IT) == TIM_IT_CC3) || \
+                           ((IT) == TIM_IT_CC4) || \
+                           ((IT) == TIM_IT_COM) || \
+                           ((IT) == TIM_IT_Trigger) || \
+                           ((IT) == TIM_IT_Break))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_DMA_Base_address 
+  * @{
+  */
+
+#define TIM_DMABase_CR1                    ((uint16_t)0x0000)
+#define TIM_DMABase_CR2                    ((uint16_t)0x0001)
+#define TIM_DMABase_SMCR                   ((uint16_t)0x0002)
+#define TIM_DMABase_DIER                   ((uint16_t)0x0003)
+#define TIM_DMABase_SR                     ((uint16_t)0x0004)
+#define TIM_DMABase_EGR                    ((uint16_t)0x0005)
+#define TIM_DMABase_CCMR1                  ((uint16_t)0x0006)
+#define TIM_DMABase_CCMR2                  ((uint16_t)0x0007)
+#define TIM_DMABase_CCER                   ((uint16_t)0x0008)
+#define TIM_DMABase_CNT                    ((uint16_t)0x0009)
+#define TIM_DMABase_PSC                    ((uint16_t)0x000A)
+#define TIM_DMABase_ARR                    ((uint16_t)0x000B)
+#define TIM_DMABase_RCR                    ((uint16_t)0x000C)
+#define TIM_DMABase_CCR1                   ((uint16_t)0x000D)
+#define TIM_DMABase_CCR2                   ((uint16_t)0x000E)
+#define TIM_DMABase_CCR3                   ((uint16_t)0x000F)
+#define TIM_DMABase_CCR4                   ((uint16_t)0x0010)
+#define TIM_DMABase_BDTR                   ((uint16_t)0x0011)
+#define TIM_DMABase_DCR                    ((uint16_t)0x0012)
+#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \
+                               ((BASE) == TIM_DMABase_CR2) || \
+                               ((BASE) == TIM_DMABase_SMCR) || \
+                               ((BASE) == TIM_DMABase_DIER) || \
+                               ((BASE) == TIM_DMABase_SR) || \
+                               ((BASE) == TIM_DMABase_EGR) || \
+                               ((BASE) == TIM_DMABase_CCMR1) || \
+                               ((BASE) == TIM_DMABase_CCMR2) || \
+                               ((BASE) == TIM_DMABase_CCER) || \
+                               ((BASE) == TIM_DMABase_CNT) || \
+                               ((BASE) == TIM_DMABase_PSC) || \
+                               ((BASE) == TIM_DMABase_ARR) || \
+                               ((BASE) == TIM_DMABase_RCR) || \
+                               ((BASE) == TIM_DMABase_CCR1) || \
+                               ((BASE) == TIM_DMABase_CCR2) || \
+                               ((BASE) == TIM_DMABase_CCR3) || \
+                               ((BASE) == TIM_DMABase_CCR4) || \
+                               ((BASE) == TIM_DMABase_BDTR) || \
+                               ((BASE) == TIM_DMABase_DCR))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_DMA_Burst_Length 
+  * @{
+  */
+
+#define TIM_DMABurstLength_1Byte           ((uint16_t)0x0000)
+#define TIM_DMABurstLength_2Bytes          ((uint16_t)0x0100)
+#define TIM_DMABurstLength_3Bytes          ((uint16_t)0x0200)
+#define TIM_DMABurstLength_4Bytes          ((uint16_t)0x0300)
+#define TIM_DMABurstLength_5Bytes          ((uint16_t)0x0400)
+#define TIM_DMABurstLength_6Bytes          ((uint16_t)0x0500)
+#define TIM_DMABurstLength_7Bytes          ((uint16_t)0x0600)
+#define TIM_DMABurstLength_8Bytes          ((uint16_t)0x0700)
+#define TIM_DMABurstLength_9Bytes          ((uint16_t)0x0800)
+#define TIM_DMABurstLength_10Bytes         ((uint16_t)0x0900)
+#define TIM_DMABurstLength_11Bytes         ((uint16_t)0x0A00)
+#define TIM_DMABurstLength_12Bytes         ((uint16_t)0x0B00)
+#define TIM_DMABurstLength_13Bytes         ((uint16_t)0x0C00)
+#define TIM_DMABurstLength_14Bytes         ((uint16_t)0x0D00)
+#define TIM_DMABurstLength_15Bytes         ((uint16_t)0x0E00)
+#define TIM_DMABurstLength_16Bytes         ((uint16_t)0x0F00)
+#define TIM_DMABurstLength_17Bytes         ((uint16_t)0x1000)
+#define TIM_DMABurstLength_18Bytes         ((uint16_t)0x1100)
+#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Byte) || \
+                                   ((LENGTH) == TIM_DMABurstLength_2Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_3Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_4Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_5Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_6Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_7Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_8Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_9Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_10Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_11Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_12Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_13Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_14Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_15Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_16Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_17Bytes) || \
+                                   ((LENGTH) == TIM_DMABurstLength_18Bytes))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_DMA_sources 
+  * @{
+  */
+
+#define TIM_DMA_Update                     ((uint16_t)0x0100)
+#define TIM_DMA_CC1                        ((uint16_t)0x0200)
+#define TIM_DMA_CC2                        ((uint16_t)0x0400)
+#define TIM_DMA_CC3                        ((uint16_t)0x0800)
+#define TIM_DMA_CC4                        ((uint16_t)0x1000)
+#define TIM_DMA_COM                        ((uint16_t)0x2000)
+#define TIM_DMA_Trigger                    ((uint16_t)0x4000)
+#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_External_Trigger_Prescaler 
+  * @{
+  */
+
+#define TIM_ExtTRGPSC_OFF                  ((uint16_t)0x0000)
+#define TIM_ExtTRGPSC_DIV2                 ((uint16_t)0x1000)
+#define TIM_ExtTRGPSC_DIV4                 ((uint16_t)0x2000)
+#define TIM_ExtTRGPSC_DIV8                 ((uint16_t)0x3000)
+#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \
+                                         ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \
+                                         ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \
+                                         ((PRESCALER) == TIM_ExtTRGPSC_DIV8))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Internal_Trigger_Selection 
+  * @{
+  */
+
+#define TIM_TS_ITR0                        ((uint16_t)0x0000)
+#define TIM_TS_ITR1                        ((uint16_t)0x0010)
+#define TIM_TS_ITR2                        ((uint16_t)0x0020)
+#define TIM_TS_ITR3                        ((uint16_t)0x0030)
+#define TIM_TS_TI1F_ED                     ((uint16_t)0x0040)
+#define TIM_TS_TI1FP1                      ((uint16_t)0x0050)
+#define TIM_TS_TI2FP2                      ((uint16_t)0x0060)
+#define TIM_TS_ETRF                        ((uint16_t)0x0070)
+#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+                                             ((SELECTION) == TIM_TS_ITR1) || \
+                                             ((SELECTION) == TIM_TS_ITR2) || \
+                                             ((SELECTION) == TIM_TS_ITR3) || \
+                                             ((SELECTION) == TIM_TS_TI1F_ED) || \
+                                             ((SELECTION) == TIM_TS_TI1FP1) || \
+                                             ((SELECTION) == TIM_TS_TI2FP2) || \
+                                             ((SELECTION) == TIM_TS_ETRF))
+#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+                                                      ((SELECTION) == TIM_TS_ITR1) || \
+                                                      ((SELECTION) == TIM_TS_ITR2) || \
+                                                      ((SELECTION) == TIM_TS_ITR3))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_TIx_External_Clock_Source 
+  * @{
+  */
+
+#define TIM_TIxExternalCLK1Source_TI1      ((uint16_t)0x0050)
+#define TIM_TIxExternalCLK1Source_TI2      ((uint16_t)0x0060)
+#define TIM_TIxExternalCLK1Source_TI1ED    ((uint16_t)0x0040)
+#define IS_TIM_TIXCLK_SOURCE(SOURCE) (((SOURCE) == TIM_TIxExternalCLK1Source_TI1) || \
+                                      ((SOURCE) == TIM_TIxExternalCLK1Source_TI2) || \
+                                      ((SOURCE) == TIM_TIxExternalCLK1Source_TI1ED))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_External_Trigger_Polarity 
+  * @{
+  */ 
+#define TIM_ExtTRGPolarity_Inverted        ((uint16_t)0x8000)
+#define TIM_ExtTRGPolarity_NonInverted     ((uint16_t)0x0000)
+#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \
+                                       ((POLARITY) == TIM_ExtTRGPolarity_NonInverted))
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Prescaler_Reload_Mode 
+  * @{
+  */
+
+#define TIM_PSCReloadMode_Update           ((uint16_t)0x0000)
+#define TIM_PSCReloadMode_Immediate        ((uint16_t)0x0001)
+#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \
+                                         ((RELOAD) == TIM_PSCReloadMode_Immediate))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Forced_Action 
+  * @{
+  */
+
+#define TIM_ForcedAction_Active            ((uint16_t)0x0050)
+#define TIM_ForcedAction_InActive          ((uint16_t)0x0040)
+#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \
+                                      ((ACTION) == TIM_ForcedAction_InActive))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Encoder_Mode 
+  * @{
+  */
+
+#define TIM_EncoderMode_TI1                ((uint16_t)0x0001)
+#define TIM_EncoderMode_TI2                ((uint16_t)0x0002)
+#define TIM_EncoderMode_TI12               ((uint16_t)0x0003)
+#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \
+                                   ((MODE) == TIM_EncoderMode_TI2) || \
+                                   ((MODE) == TIM_EncoderMode_TI12))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup TIM_Event_Source 
+  * @{
+  */
+
+#define TIM_EventSource_Update             ((uint16_t)0x0001)
+#define TIM_EventSource_CC1                ((uint16_t)0x0002)
+#define TIM_EventSource_CC2                ((uint16_t)0x0004)
+#define TIM_EventSource_CC3                ((uint16_t)0x0008)
+#define TIM_EventSource_CC4                ((uint16_t)0x0010)
+#define TIM_EventSource_COM                ((uint16_t)0x0020)
+#define TIM_EventSource_Trigger            ((uint16_t)0x0040)
+#define TIM_EventSource_Break              ((uint16_t)0x0080)
+#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Update_Source 
+  * @{
+  */
+
+#define TIM_UpdateSource_Global            ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow
+                                                                   or the setting of UG bit, or an update generation
+                                                                   through the slave mode controller. */
+#define TIM_UpdateSource_Regular           ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */
+#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \
+                                      ((SOURCE) == TIM_UpdateSource_Regular))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Ouput_Compare_Preload_State 
+  * @{
+  */
+
+#define TIM_OCPreload_Enable               ((uint16_t)0x0008)
+#define TIM_OCPreload_Disable              ((uint16_t)0x0000)
+#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \
+                                       ((STATE) == TIM_OCPreload_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Ouput_Compare_Fast_State 
+  * @{
+  */
+
+#define TIM_OCFast_Enable                  ((uint16_t)0x0004)
+#define TIM_OCFast_Disable                 ((uint16_t)0x0000)
+#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \
+                                    ((STATE) == TIM_OCFast_Disable))
+                                     
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Ouput_Compare_Clear_State 
+  * @{
+  */
+
+#define TIM_OCClear_Enable                 ((uint16_t)0x0080)
+#define TIM_OCClear_Disable                ((uint16_t)0x0000)
+#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \
+                                     ((STATE) == TIM_OCClear_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Trigger_Output_Source 
+  * @{
+  */
+
+#define TIM_TRGOSource_Reset               ((uint16_t)0x0000)
+#define TIM_TRGOSource_Enable              ((uint16_t)0x0010)
+#define TIM_TRGOSource_Update              ((uint16_t)0x0020)
+#define TIM_TRGOSource_OC1                 ((uint16_t)0x0030)
+#define TIM_TRGOSource_OC1Ref              ((uint16_t)0x0040)
+#define TIM_TRGOSource_OC2Ref              ((uint16_t)0x0050)
+#define TIM_TRGOSource_OC3Ref              ((uint16_t)0x0060)
+#define TIM_TRGOSource_OC4Ref              ((uint16_t)0x0070)
+#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \
+                                    ((SOURCE) == TIM_TRGOSource_Enable) || \
+                                    ((SOURCE) == TIM_TRGOSource_Update) || \
+                                    ((SOURCE) == TIM_TRGOSource_OC1) || \
+                                    ((SOURCE) == TIM_TRGOSource_OC1Ref) || \
+                                    ((SOURCE) == TIM_TRGOSource_OC2Ref) || \
+                                    ((SOURCE) == TIM_TRGOSource_OC3Ref) || \
+                                    ((SOURCE) == TIM_TRGOSource_OC4Ref))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Slave_Mode 
+  * @{
+  */
+
+#define TIM_SlaveMode_Reset                ((uint16_t)0x0004)
+#define TIM_SlaveMode_Gated                ((uint16_t)0x0005)
+#define TIM_SlaveMode_Trigger              ((uint16_t)0x0006)
+#define TIM_SlaveMode_External1            ((uint16_t)0x0007)
+#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \
+                                 ((MODE) == TIM_SlaveMode_Gated) || \
+                                 ((MODE) == TIM_SlaveMode_Trigger) || \
+                                 ((MODE) == TIM_SlaveMode_External1))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Master_Slave_Mode 
+  * @{
+  */
+
+#define TIM_MasterSlaveMode_Enable         ((uint16_t)0x0080)
+#define TIM_MasterSlaveMode_Disable        ((uint16_t)0x0000)
+#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \
+                                 ((STATE) == TIM_MasterSlaveMode_Disable))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Flags 
+  * @{
+  */
+
+#define TIM_FLAG_Update                    ((uint16_t)0x0001)
+#define TIM_FLAG_CC1                       ((uint16_t)0x0002)
+#define TIM_FLAG_CC2                       ((uint16_t)0x0004)
+#define TIM_FLAG_CC3                       ((uint16_t)0x0008)
+#define TIM_FLAG_CC4                       ((uint16_t)0x0010)
+#define TIM_FLAG_COM                       ((uint16_t)0x0020)
+#define TIM_FLAG_Trigger                   ((uint16_t)0x0040)
+#define TIM_FLAG_Break                     ((uint16_t)0x0080)
+#define TIM_FLAG_CC1OF                     ((uint16_t)0x0200)
+#define TIM_FLAG_CC2OF                     ((uint16_t)0x0400)
+#define TIM_FLAG_CC3OF                     ((uint16_t)0x0800)
+#define TIM_FLAG_CC4OF                     ((uint16_t)0x1000)
+#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \
+                               ((FLAG) == TIM_FLAG_CC1) || \
+                               ((FLAG) == TIM_FLAG_CC2) || \
+                               ((FLAG) == TIM_FLAG_CC3) || \
+                               ((FLAG) == TIM_FLAG_CC4) || \
+                               ((FLAG) == TIM_FLAG_COM) || \
+                               ((FLAG) == TIM_FLAG_Trigger) || \
+                               ((FLAG) == TIM_FLAG_Break) || \
+                               ((FLAG) == TIM_FLAG_CC1OF) || \
+                               ((FLAG) == TIM_FLAG_CC2OF) || \
+                               ((FLAG) == TIM_FLAG_CC3OF) || \
+                               ((FLAG) == TIM_FLAG_CC4OF))
+                               
+                               
+#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE100) == 0x0000) && ((TIM_FLAG) != 0x0000))
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Input_Capture_Filer_Value 
+  * @{
+  */
+
+#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) 
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_External_Trigger_Filter 
+  * @{
+  */
+
+#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF)
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup TIM_Exported_Functions
+  * @{
+  */
+
+void TIM_DeInit(TIM_TypeDef* TIMx);
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
+void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
+void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+                                uint16_t TIM_ICPolarity, uint16_t ICFilter);
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+                             uint16_t ExtTRGFilter);
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
+                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+                   uint16_t ExtTRGFilter);
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
+uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
+uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
+uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
+uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
+uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F10x_TIM_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/inc/stm32f10x_usart.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,412 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_usart.h
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file contains all the functions prototypes for the USART 
+  *          firmware library.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_USART_H
+#define __STM32F10x_USART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @addtogroup USART
+  * @{
+  */ 
+
+/** @defgroup USART_Exported_Types
+  * @{
+  */ 
+
+/** 
+  * @brief  USART Init Structure definition  
+  */ 
+  
+typedef struct
+{
+  uint32_t USART_BaudRate;            /*!< This member configures the USART communication baud rate.
+                                           The baud rate is computed using the following formula:
+                                            - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
+                                            - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
+
+  uint16_t USART_WordLength;          /*!< Specifies the number of data bits transmitted or received in a frame.
+                                           This parameter can be a value of @ref USART_Word_Length */
+
+  uint16_t USART_StopBits;            /*!< Specifies the number of stop bits transmitted.
+                                           This parameter can be a value of @ref USART_Stop_Bits */
+
+  uint16_t USART_Parity;              /*!< Specifies the parity mode.
+                                           This parameter can be a value of @ref USART_Parity
+                                           @note When parity is enabled, the computed parity is inserted
+                                                 at the MSB position of the transmitted data (9th bit when
+                                                 the word length is set to 9 data bits; 8th bit when the
+                                                 word length is set to 8 data bits). */
+ 
+  uint16_t USART_Mode;                /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.
+                                           This parameter can be a value of @ref USART_Mode */
+
+  uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
+                                           or disabled.
+                                           This parameter can be a value of @ref USART_Hardware_Flow_Control */
+} USART_InitTypeDef;
+
+/** 
+  * @brief  USART Clock Init Structure definition  
+  */ 
+  
+typedef struct
+{
+
+  uint16_t USART_Clock;   /*!< Specifies whether the USART clock is enabled or disabled.
+                               This parameter can be a value of @ref USART_Clock */
+
+  uint16_t USART_CPOL;    /*!< Specifies the steady state value of the serial clock.
+                               This parameter can be a value of @ref USART_Clock_Polarity */
+
+  uint16_t USART_CPHA;    /*!< Specifies the clock transition on which the bit capture is made.
+                               This parameter can be a value of @ref USART_Clock_Phase */
+
+  uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+                               data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+                               This parameter can be a value of @ref USART_Last_Bit */
+} USART_ClockInitTypeDef;
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Exported_Constants
+  * @{
+  */ 
+  
+#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
+                                     ((PERIPH) == USART2) || \
+                                     ((PERIPH) == USART3) || \
+                                     ((PERIPH) == UART4) || \
+                                     ((PERIPH) == UART5))
+
+#define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \
+                                     ((PERIPH) == USART2) || \
+                                     ((PERIPH) == USART3))
+
+#define IS_USART_1234_PERIPH(PERIPH) (((PERIPH) == USART1) || \
+                                      ((PERIPH) == USART2) || \
+                                      ((PERIPH) == USART3) || \
+                                      ((PERIPH) == UART4))
+/** @defgroup USART_Word_Length 
+  * @{
+  */ 
+  
+#define USART_WordLength_8b                  ((uint16_t)0x0000)
+#define USART_WordLength_9b                  ((uint16_t)0x1000)
+                                    
+#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \
+                                      ((LENGTH) == USART_WordLength_9b))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Stop_Bits 
+  * @{
+  */ 
+  
+#define USART_StopBits_1                     ((uint16_t)0x0000)
+#define USART_StopBits_0_5                   ((uint16_t)0x1000)
+#define USART_StopBits_2                     ((uint16_t)0x2000)
+#define USART_StopBits_1_5                   ((uint16_t)0x3000)
+#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \
+                                     ((STOPBITS) == USART_StopBits_0_5) || \
+                                     ((STOPBITS) == USART_StopBits_2) || \
+                                     ((STOPBITS) == USART_StopBits_1_5))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Parity 
+  * @{
+  */ 
+  
+#define USART_Parity_No                      ((uint16_t)0x0000)
+#define USART_Parity_Even                    ((uint16_t)0x0400)
+#define USART_Parity_Odd                     ((uint16_t)0x0600) 
+#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \
+                                 ((PARITY) == USART_Parity_Even) || \
+                                 ((PARITY) == USART_Parity_Odd))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Mode 
+  * @{
+  */ 
+  
+#define USART_Mode_Rx                        ((uint16_t)0x0004)
+#define USART_Mode_Tx                        ((uint16_t)0x0008)
+#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Hardware_Flow_Control 
+  * @{
+  */ 
+#define USART_HardwareFlowControl_None       ((uint16_t)0x0000)
+#define USART_HardwareFlowControl_RTS        ((uint16_t)0x0100)
+#define USART_HardwareFlowControl_CTS        ((uint16_t)0x0200)
+#define USART_HardwareFlowControl_RTS_CTS    ((uint16_t)0x0300)
+#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\
+                              (((CONTROL) == USART_HardwareFlowControl_None) || \
+                               ((CONTROL) == USART_HardwareFlowControl_RTS) || \
+                               ((CONTROL) == USART_HardwareFlowControl_CTS) || \
+                               ((CONTROL) == USART_HardwareFlowControl_RTS_CTS))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Clock 
+  * @{
+  */ 
+#define USART_Clock_Disable                  ((uint16_t)0x0000)
+#define USART_Clock_Enable                   ((uint16_t)0x0800)
+#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \
+                               ((CLOCK) == USART_Clock_Enable))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Clock_Polarity 
+  * @{
+  */
+  
+#define USART_CPOL_Low                       ((uint16_t)0x0000)
+#define USART_CPOL_High                      ((uint16_t)0x0400)
+#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Clock_Phase
+  * @{
+  */
+
+#define USART_CPHA_1Edge                     ((uint16_t)0x0000)
+#define USART_CPHA_2Edge                     ((uint16_t)0x0200)
+#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge))
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Last_Bit
+  * @{
+  */
+
+#define USART_LastBit_Disable                ((uint16_t)0x0000)
+#define USART_LastBit_Enable                 ((uint16_t)0x0100)
+#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \
+                                   ((LASTBIT) == USART_LastBit_Enable))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Interrupt_definition 
+  * @{
+  */
+  
+#define USART_IT_PE                          ((uint16_t)0x0028)
+#define USART_IT_TXE                         ((uint16_t)0x0727)
+#define USART_IT_TC                          ((uint16_t)0x0626)
+#define USART_IT_RXNE                        ((uint16_t)0x0525)
+#define USART_IT_IDLE                        ((uint16_t)0x0424)
+#define USART_IT_LBD                         ((uint16_t)0x0846)
+#define USART_IT_CTS                         ((uint16_t)0x096A)
+#define USART_IT_ERR                         ((uint16_t)0x0060)
+#define USART_IT_ORE                         ((uint16_t)0x0360)
+#define USART_IT_NE                          ((uint16_t)0x0260)
+#define USART_IT_FE                          ((uint16_t)0x0160)
+#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+                               ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+                               ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+                               ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))
+#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+                            ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+                            ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+                            ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \
+                            ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE))
+#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+                               ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS))
+/**
+  * @}
+  */
+
+/** @defgroup USART_DMA_Requests 
+  * @{
+  */
+
+#define USART_DMAReq_Tx                      ((uint16_t)0x0080)
+#define USART_DMAReq_Rx                      ((uint16_t)0x0040)
+#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00))
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_WakeUp_methods
+  * @{
+  */
+
+#define USART_WakeUp_IdleLine                ((uint16_t)0x0000)
+#define USART_WakeUp_AddressMark             ((uint16_t)0x0800)
+#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \
+                                 ((WAKEUP) == USART_WakeUp_AddressMark))
+/**
+  * @}
+  */
+
+/** @defgroup USART_LIN_Break_Detection_Length 
+  * @{
+  */
+  
+#define USART_LINBreakDetectLength_10b      ((uint16_t)0x0000)
+#define USART_LINBreakDetectLength_11b      ((uint16_t)0x0020)
+#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \
+                               (((LENGTH) == USART_LINBreakDetectLength_10b) || \
+                                ((LENGTH) == USART_LINBreakDetectLength_11b))
+/**
+  * @}
+  */
+
+/** @defgroup USART_IrDA_Low_Power 
+  * @{
+  */
+
+#define USART_IrDAMode_LowPower              ((uint16_t)0x0004)
+#define USART_IrDAMode_Normal                ((uint16_t)0x0000)
+#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \
+                                  ((MODE) == USART_IrDAMode_Normal))
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Flags 
+  * @{
+  */
+
+#define USART_FLAG_CTS                       ((uint16_t)0x0200)
+#define USART_FLAG_LBD                       ((uint16_t)0x0100)
+#define USART_FLAG_TXE                       ((uint16_t)0x0080)
+#define USART_FLAG_TC                        ((uint16_t)0x0040)
+#define USART_FLAG_RXNE                      ((uint16_t)0x0020)
+#define USART_FLAG_IDLE                      ((uint16_t)0x0010)
+#define USART_FLAG_ORE                       ((uint16_t)0x0008)
+#define USART_FLAG_NE                        ((uint16_t)0x0004)
+#define USART_FLAG_FE                        ((uint16_t)0x0002)
+#define USART_FLAG_PE                        ((uint16_t)0x0001)
+#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \
+                             ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \
+                             ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \
+                             ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \
+                             ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE))
+                              
+#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00))
+#define IS_USART_PERIPH_FLAG(PERIPH, USART_FLAG) ((((*(uint32_t*)&(PERIPH)) != UART4_BASE) &&\
+                                                  ((*(uint32_t*)&(PERIPH)) != UART5_BASE)) \
+                                                  || ((USART_FLAG) != USART_FLAG_CTS)) 
+#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x0044AA21))
+#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF)
+#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF)
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Exported_Macros
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup USART_Exported_Functions
+  * @{
+  */
+
+void USART_DeInit(USART_TypeDef* USARTx);
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
+void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
+void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);
+void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
+void USART_SendBreak(USART_TypeDef* USARTx);
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_USART_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/misc.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,225 @@
+/**
+  ******************************************************************************
+  * @file    misc.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the miscellaneous firmware functions (add-on
+  *          to CMSIS functions).
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "misc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup MISC 
+  * @brief MISC driver modules
+  * @{
+  */
+
+/** @defgroup MISC_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup MISC_Private_Defines
+  * @{
+  */
+
+#define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup MISC_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Configures the priority grouping: pre-emption priority and subpriority.
+  * @param  NVIC_PriorityGroup: specifies the priority grouping bits length. 
+  *   This parameter can be one of the following values:
+  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
+  *                                4 bits for subpriority
+  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
+  *                                3 bits for subpriority
+  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
+  *                                2 bits for subpriority
+  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
+  *                                1 bits for subpriority
+  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
+  *                                0 bits for subpriority
+  * @retval None
+  */
+void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
+{
+  /* Check the parameters */
+  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
+  
+  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
+  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
+}
+
+/**
+  * @brief  Initializes the NVIC peripheral according to the specified
+  *         parameters in the NVIC_InitStruct.
+  * @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
+  *         the configuration information for the specified NVIC peripheral.
+  * @retval None
+  */
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
+{
+  uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
+  
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
+  assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  
+  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
+    
+  if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
+  {
+    /* Compute the Corresponding IRQ Priority --------------------------------*/    
+    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
+    tmppre = (0x4 - tmppriority);
+    tmpsub = tmpsub >> tmppriority;
+
+    tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
+    tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
+    tmppriority = tmppriority << 0x04;
+        
+    NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
+    
+    /* Enable the Selected IRQ Channels --------------------------------------*/
+    NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
+      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+  }
+  else
+  {
+    /* Disable the Selected IRQ Channels -------------------------------------*/
+    NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
+      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+  }
+}
+
+/**
+  * @brief  Sets the vector table location and Offset.
+  * @param  NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory.
+  *   This parameter can be one of the following values:
+  *     @arg NVIC_VectTab_RAM
+  *     @arg NVIC_VectTab_FLASH
+  * @param  Offset: Vector Table base offset field. This value must be a multiple 
+  *         of 0x200.
+  * @retval None
+  */
+void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
+{ 
+  /* Check the parameters */
+  assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
+  assert_param(IS_NVIC_OFFSET(Offset));  
+   
+  SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
+}
+
+/**
+  * @brief  Selects the condition for the system to enter low power mode.
+  * @param  LowPowerMode: Specifies the new mode for the system to enter low power mode.
+  *   This parameter can be one of the following values:
+  *     @arg NVIC_LP_SEVONPEND
+  *     @arg NVIC_LP_SLEEPDEEP
+  *     @arg NVIC_LP_SLEEPONEXIT
+  * @param  NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_NVIC_LP(LowPowerMode));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));  
+  
+  if (NewState != DISABLE)
+  {
+    SCB->SCR |= LowPowerMode;
+  }
+  else
+  {
+    SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
+  }
+}
+
+/**
+  * @brief  Configures the SysTick clock source.
+  * @param  SysTick_CLKSource: specifies the SysTick clock source.
+  *   This parameter can be one of the following values:
+  *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
+  *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
+  * @retval None
+  */
+void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
+  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
+  {
+    SysTick->CTRL |= SysTick_CLKSource_HCLK;
+  }
+  else
+  {
+    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_exti.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,269 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_exti.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the EXTI firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_exti.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup EXTI 
+  * @brief EXTI driver modules
+  * @{
+  */
+
+/** @defgroup EXTI_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Private_Defines
+  * @{
+  */
+
+#define EXTI_LINENONE    ((uint32_t)0x00000)  /* No interrupt selected */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup EXTI_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Deinitializes the EXTI peripheral registers to their default reset values.
+  * @param  None
+  * @retval None
+  */
+void EXTI_DeInit(void)
+{
+  EXTI->IMR = 0x00000000;
+  EXTI->EMR = 0x00000000;
+  EXTI->RTSR = 0x00000000; 
+  EXTI->FTSR = 0x00000000; 
+  EXTI->PR = 0x000FFFFF;
+}
+
+/**
+  * @brief  Initializes the EXTI peripheral according to the specified
+  *         parameters in the EXTI_InitStruct.
+  * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
+  *         that contains the configuration information for the EXTI peripheral.
+  * @retval None
+  */
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+  uint32_t tmp = 0;
+
+  /* Check the parameters */
+  assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
+  assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
+  assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));  
+  assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
+
+  tmp = (uint32_t)EXTI_BASE;
+     
+  if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
+  {
+    /* Clear EXTI line configuration */
+    EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
+    EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
+    
+    tmp += EXTI_InitStruct->EXTI_Mode;
+
+    *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+
+    /* Clear Rising Falling edge configuration */
+    EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
+    EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
+    
+    /* Select the trigger for the selected external interrupts */
+    if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
+    {
+      /* Rising Falling edge */
+      EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
+      EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
+    }
+    else
+    {
+      tmp = (uint32_t)EXTI_BASE;
+      tmp += EXTI_InitStruct->EXTI_Trigger;
+
+      *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+    }
+  }
+  else
+  {
+    tmp += EXTI_InitStruct->EXTI_Mode;
+
+    /* Disable the selected external lines */
+    *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
+  }
+}
+
+/**
+  * @brief  Fills each EXTI_InitStruct member with its reset value.
+  * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will
+  *         be initialized.
+  * @retval None
+  */
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+  EXTI_InitStruct->EXTI_Line = EXTI_LINENONE;
+  EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;
+  EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;
+  EXTI_InitStruct->EXTI_LineCmd = DISABLE;
+}
+
+/**
+  * @brief  Generates a Software interrupt.
+  * @param  EXTI_Line: specifies the EXTI lines to be enabled or disabled.
+  *   This parameter can be any combination of EXTI_Linex where x can be (0..19).
+  * @retval None
+  */
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
+{
+  /* Check the parameters */
+  assert_param(IS_EXTI_LINE(EXTI_Line));
+  
+  EXTI->SWIER |= EXTI_Line;
+}
+
+/**
+  * @brief  Checks whether the specified EXTI line flag is set or not.
+  * @param  EXTI_Line: specifies the EXTI line flag to check.
+  *   This parameter can be:
+  *     @arg EXTI_Linex: External interrupt line x where x(0..19)
+  * @retval The new state of EXTI_Line (SET or RESET).
+  */
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
+{
+  FlagStatus bitstatus = RESET;
+  /* Check the parameters */
+  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+  
+  if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the EXTI's line pending flags.
+  * @param  EXTI_Line: specifies the EXTI lines flags to clear.
+  *   This parameter can be any combination of EXTI_Linex where x can be (0..19).
+  * @retval None
+  */
+void EXTI_ClearFlag(uint32_t EXTI_Line)
+{
+  /* Check the parameters */
+  assert_param(IS_EXTI_LINE(EXTI_Line));
+  
+  EXTI->PR = EXTI_Line;
+}
+
+/**
+  * @brief  Checks whether the specified EXTI line is asserted or not.
+  * @param  EXTI_Line: specifies the EXTI line to check.
+  *   This parameter can be:
+  *     @arg EXTI_Linex: External interrupt line x where x(0..19)
+  * @retval The new state of EXTI_Line (SET or RESET).
+  */
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
+{
+  ITStatus bitstatus = RESET;
+  uint32_t enablestatus = 0;
+  /* Check the parameters */
+  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+  
+  enablestatus =  EXTI->IMR & EXTI_Line;
+  if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the EXTI's line pending bits.
+  * @param  EXTI_Line: specifies the EXTI lines to clear.
+  *   This parameter can be any combination of EXTI_Linex where x can be (0..19).
+  * @retval None
+  */
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
+{
+  /* Check the parameters */
+  assert_param(IS_EXTI_LINE(EXTI_Line));
+  
+  EXTI->PR = EXTI_Line;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_flash.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1684 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_flash.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the FLASH firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_flash.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup FLASH 
+  * @brief FLASH driver modules
+  * @{
+  */ 
+
+/** @defgroup FLASH_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup FLASH_Private_Defines
+  * @{
+  */ 
+
+/* Flash Access Control Register bits */
+#define ACR_LATENCY_Mask         ((uint32_t)0x00000038)
+#define ACR_HLFCYA_Mask          ((uint32_t)0xFFFFFFF7)
+#define ACR_PRFTBE_Mask          ((uint32_t)0xFFFFFFEF)
+
+/* Flash Access Control Register bits */
+#define ACR_PRFTBS_Mask          ((uint32_t)0x00000020) 
+
+/* Flash Control Register bits */
+#define CR_PG_Set                ((uint32_t)0x00000001)
+#define CR_PG_Reset              ((uint32_t)0x00001FFE) 
+#define CR_PER_Set               ((uint32_t)0x00000002)
+#define CR_PER_Reset             ((uint32_t)0x00001FFD)
+#define CR_MER_Set               ((uint32_t)0x00000004)
+#define CR_MER_Reset             ((uint32_t)0x00001FFB)
+#define CR_OPTPG_Set             ((uint32_t)0x00000010)
+#define CR_OPTPG_Reset           ((uint32_t)0x00001FEF)
+#define CR_OPTER_Set             ((uint32_t)0x00000020)
+#define CR_OPTER_Reset           ((uint32_t)0x00001FDF)
+#define CR_STRT_Set              ((uint32_t)0x00000040)
+#define CR_LOCK_Set              ((uint32_t)0x00000080)
+
+/* FLASH Mask */
+#define RDPRT_Mask               ((uint32_t)0x00000002)
+#define WRP0_Mask                ((uint32_t)0x000000FF)
+#define WRP1_Mask                ((uint32_t)0x0000FF00)
+#define WRP2_Mask                ((uint32_t)0x00FF0000)
+#define WRP3_Mask                ((uint32_t)0xFF000000)
+#define OB_USER_BFB2             ((uint16_t)0x0008)
+
+/* FLASH Keys */
+#define RDP_Key                  ((uint16_t)0x00A5)
+#define FLASH_KEY1               ((uint32_t)0x45670123)
+#define FLASH_KEY2               ((uint32_t)0xCDEF89AB)
+
+/* FLASH BANK address */
+#define FLASH_BANK1_END_ADDRESS   ((uint32_t)0x807FFFF)
+
+/* Delay definition */   
+#define EraseTimeout          ((uint32_t)0x000B0000)
+#define ProgramTimeout        ((uint32_t)0x00002000)
+/**
+  * @}
+  */ 
+
+/** @defgroup FLASH_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup FLASH_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup FLASH_Private_FunctionPrototypes
+  * @{
+  */
+  
+/**
+  * @}
+  */
+
+/** @defgroup FLASH_Private_Functions
+  * @{
+  */
+
+/**
+@code  
+ 
+ This driver provides functions to configure and program the Flash memory of all STM32F10x devices,
+ including the latest STM32F10x_XL density devices. 
+
+ STM32F10x_XL devices feature up to 1 Mbyte with dual bank architecture for read-while-write (RWW) capability:
+    - bank1: fixed size of 512 Kbytes (256 pages of 2Kbytes each)
+    - bank2: up to 512 Kbytes (up to 256 pages of 2Kbytes each)
+ While other STM32F10x devices features only one bank with memory up to 512 Kbytes.
+
+ In version V3.3.0, some functions were updated and new ones were added to support
+ STM32F10x_XL devices. Thus some functions manages all devices, while other are 
+ dedicated for XL devices only.
+ 
+ The table below presents the list of available functions depending on the used STM32F10x devices.  
+      
+   ***************************************************
+   * Legacy functions used for all STM32F10x devices *
+   ***************************************************
+   +----------------------------------------------------------------------------------------------------------------------------------+
+   |       Functions prototypes         |STM32F10x_XL|Other STM32F10x|    Comments                                                    |
+   |                                    |   devices  |  devices      |                                                                |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_SetLatency                    |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_HalfCycleAccessCmd            |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_PrefetchBufferCmd             |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_Unlock                        |    Yes     |      Yes      | - For STM32F10X_XL devices: unlock Bank1 and Bank2.            |
+   |                                    |            |               | - For other devices: unlock Bank1 and it is equivalent         |
+   |                                    |            |               |   to FLASH_UnlockBank1 function.                               |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_Lock                          |    Yes     |      Yes      | - For STM32F10X_XL devices: lock Bank1 and Bank2.              |
+   |                                    |            |               | - For other devices: lock Bank1 and it is equivalent           |
+   |                                    |            |               |   to FLASH_LockBank1 function.                                 |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ErasePage                     |    Yes     |      Yes      | - For STM32F10x_XL devices: erase a page in Bank1 and Bank2    |
+   |                                    |            |               | - For other devices: erase a page in Bank1                     |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_EraseAllPages                 |    Yes     |      Yes      | - For STM32F10x_XL devices: erase all pages in Bank1 and Bank2 |
+   |                                    |            |               | - For other devices: erase all pages in Bank1                  |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_EraseOptionBytes              |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ProgramWord                   |    Yes     |      Yes      | Updated to program up to 1MByte (depending on the used device) |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ProgramHalfWord               |    Yes     |      Yes      | Updated to program up to 1MByte (depending on the used device) |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ProgramOptionByteData         |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_EnableWriteProtection         |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ReadOutProtection             |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_UserOptionByteConfig          |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetUserOptionByte             |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetWriteProtectionOptionByte  |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetReadOutProtectionStatus    |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetPrefetchBufferStatus       |    Yes     |      Yes      | No change                                                      |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ITConfig                      |    Yes     |      Yes      | - For STM32F10x_XL devices: enable Bank1 and Bank2's interrupts|
+   |                                    |            |               | - For other devices: enable Bank1's interrupts                 |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetFlagStatus                 |    Yes     |      Yes      | - For STM32F10x_XL devices: return Bank1 and Bank2's flag status|
+   |                                    |            |               | - For other devices: return Bank1's flag status                |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_ClearFlag                     |    Yes     |      Yes      | - For STM32F10x_XL devices: clear Bank1 and Bank2's flag       |
+   |                                    |            |               | - For other devices: clear Bank1's flag                        |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_GetStatus                     |    Yes     |      Yes      | - Return the status of Bank1 (for all devices)                 |
+   |                                    |            |               |   equivalent to FLASH_GetBank1Status function                  |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_WaitForLastOperation          |    Yes     |      Yes      | - Wait for Bank1 last operation (for all devices)              |
+   |                                    |            |               |   equivalent to: FLASH_WaitForLastBank1Operation function      |
+   +----------------------------------------------------------------------------------------------------------------------------------+
+
+   ************************************************************************************************************************
+   * New functions used for all STM32F10x devices to manage Bank1:                                                        *
+   *   - These functions are mainly useful for STM32F10x_XL density devices, to have separate control for Bank1 and bank2 *
+   *   - For other devices, these functions are optional (covered by functions listed above)                              *
+   ************************************************************************************************************************
+   +----------------------------------------------------------------------------------------------------------------------------------+
+   |       Functions prototypes         |STM32F10x_XL|Other STM32F10x|    Comments                                                    |
+   |                                    |   devices  |  devices      |                                                                |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_UnlockBank1                  |    Yes     |      Yes      | - Unlock Bank1                                                 |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_LockBank1                     |    Yes     |      Yes      | - Lock Bank1                                                   |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_EraseAllBank1Pages           |    Yes     |      Yes      | - Erase all pages in Bank1                                     |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_GetBank1Status               |    Yes     |      Yes      | - Return the status of Bank1                                   |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_WaitForLastBank1Operation    |    Yes     |      Yes      | - Wait for Bank1 last operation                                |
+   +----------------------------------------------------------------------------------------------------------------------------------+
+
+   *****************************************************************************
+   * New Functions used only with STM32F10x_XL density devices to manage Bank2 *
+   *****************************************************************************
+   +----------------------------------------------------------------------------------------------------------------------------------+
+   |       Functions prototypes         |STM32F10x_XL|Other STM32F10x|    Comments                                                    |
+   |                                    |   devices  |  devices      |                                                                |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_UnlockBank2                  |    Yes     |      No       | - Unlock Bank2                                                 |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   |FLASH_LockBank2                     |    Yes     |      No       | - Lock Bank2                                                   |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_EraseAllBank2Pages           |    Yes     |      No       | - Erase all pages in Bank2                                     |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_GetBank2Status               |    Yes     |      No       | - Return the status of Bank2                                   |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_WaitForLastBank2Operation    |    Yes     |      No       | - Wait for Bank2 last operation                                |
+   |----------------------------------------------------------------------------------------------------------------------------------|
+   | FLASH_BootConfig                   |    Yes     |      No       | - Configure to boot from Bank1 or Bank2                        |
+   +----------------------------------------------------------------------------------------------------------------------------------+
+@endcode
+*/
+
+
+/**
+  * @brief  Sets the code latency value.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  FLASH_Latency: specifies the FLASH Latency value.
+  *   This parameter can be one of the following values:
+  *     @arg FLASH_Latency_0: FLASH Zero Latency cycle
+  *     @arg FLASH_Latency_1: FLASH One Latency cycle
+  *     @arg FLASH_Latency_2: FLASH Two Latency cycles
+  * @retval None
+  */
+void FLASH_SetLatency(uint32_t FLASH_Latency)
+{
+  uint32_t tmpreg = 0;
+  
+  /* Check the parameters */
+  assert_param(IS_FLASH_LATENCY(FLASH_Latency));
+  
+  /* Read the ACR register */
+  tmpreg = FLASH->ACR;  
+  
+  /* Sets the Latency value */
+  tmpreg &= ACR_LATENCY_Mask;
+  tmpreg |= FLASH_Latency;
+  
+  /* Write the ACR register */
+  FLASH->ACR = tmpreg;
+}
+
+/**
+  * @brief  Enables or disables the Half cycle flash access.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode.
+  *   This parameter can be one of the following values:
+  *     @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable
+  *     @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable
+  * @retval None
+  */
+void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)
+{
+  /* Check the parameters */
+  assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess));
+  
+  /* Enable or disable the Half cycle access */
+  FLASH->ACR &= ACR_HLFCYA_Mask;
+  FLASH->ACR |= FLASH_HalfCycleAccess;
+}
+
+/**
+  * @brief  Enables or disables the Prefetch Buffer.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  FLASH_PrefetchBuffer: specifies the Prefetch buffer status.
+  *   This parameter can be one of the following values:
+  *     @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable
+  *     @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable
+  * @retval None
+  */
+void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)
+{
+  /* Check the parameters */
+  assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer));
+  
+  /* Enable or disable the Prefetch Buffer */
+  FLASH->ACR &= ACR_PRFTBE_Mask;
+  FLASH->ACR |= FLASH_PrefetchBuffer;
+}
+
+/**
+  * @brief  Unlocks the FLASH Program Erase Controller.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices this function unlocks Bank1 and Bank2.
+  *         - For all other devices it unlocks Bank1 and it is equivalent 
+  *           to FLASH_UnlockBank1 function.. 
+  * @param  None
+  * @retval None
+  */
+void FLASH_Unlock(void)
+{
+  /* Authorize the FPEC of Bank1 Access */
+  FLASH->KEYR = FLASH_KEY1;
+  FLASH->KEYR = FLASH_KEY2;
+
+#ifdef STM32F10X_XL
+  /* Authorize the FPEC of Bank2 Access */
+  FLASH->KEYR2 = FLASH_KEY1;
+  FLASH->KEYR2 = FLASH_KEY2;
+#endif /* STM32F10X_XL */
+}
+/**
+  * @brief  Unlocks the FLASH Bank1 Program Erase Controller.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices this function unlocks Bank1.
+  *         - For all other devices it unlocks Bank1 and it is 
+  *           equivalent to FLASH_Unlock function.
+  * @param  None
+  * @retval None
+  */
+void FLASH_UnlockBank1(void)
+{
+  /* Authorize the FPEC of Bank1 Access */
+  FLASH->KEYR = FLASH_KEY1;
+  FLASH->KEYR = FLASH_KEY2;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Unlocks the FLASH Bank2 Program Erase Controller.
+  * @note   This function can be used only for STM32F10X_XL density devices.
+  * @param  None
+  * @retval None
+  */
+void FLASH_UnlockBank2(void)
+{
+  /* Authorize the FPEC of Bank2 Access */
+  FLASH->KEYR2 = FLASH_KEY1;
+  FLASH->KEYR2 = FLASH_KEY2;
+
+}
+#endif /* STM32F10X_XL */
+
+/**
+  * @brief  Locks the FLASH Program Erase Controller.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices this function Locks Bank1 and Bank2.
+  *         - For all other devices it Locks Bank1 and it is equivalent 
+  *           to FLASH_LockBank1 function.
+  * @param  None
+  * @retval None
+  */
+void FLASH_Lock(void)
+{
+  /* Set the Lock Bit to lock the FPEC and the CR of  Bank1 */
+  FLASH->CR |= CR_LOCK_Set;
+
+#ifdef STM32F10X_XL
+  /* Set the Lock Bit to lock the FPEC and the CR of  Bank2 */
+  FLASH->CR2 |= CR_LOCK_Set;
+#endif /* STM32F10X_XL */
+}
+
+/**
+  * @brief  Locks the FLASH Bank1 Program Erase Controller.
+  * @note   this function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices this function Locks Bank1.
+  *         - For all other devices it Locks Bank1 and it is equivalent 
+  *           to FLASH_Lock function.
+  * @param  None
+  * @retval None
+  */
+void FLASH_LockBank1(void)
+{
+  /* Set the Lock Bit to lock the FPEC and the CR of  Bank1 */
+  FLASH->CR |= CR_LOCK_Set;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Locks the FLASH Bank2 Program Erase Controller.
+  * @note   This function can be used only for STM32F10X_XL density devices.
+  * @param  None
+  * @retval None
+  */
+void FLASH_LockBank2(void)
+{
+  /* Set the Lock Bit to lock the FPEC and the CR of  Bank2 */
+  FLASH->CR2 |= CR_LOCK_Set;
+}
+#endif /* STM32F10X_XL */
+
+/**
+  * @brief  Erases a specified FLASH page.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  Page_Address: The page address to be erased.
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Check the parameters */
+  assert_param(IS_FLASH_ADDRESS(Page_Address));
+
+#ifdef STM32F10X_XL
+  if(Page_Address < FLASH_BANK1_END_ADDRESS)  
+  {
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+    if(status == FLASH_COMPLETE)
+    { 
+      /* if the previous operation is completed, proceed to erase the page */
+      FLASH->CR|= CR_PER_Set;
+      FLASH->AR = Page_Address; 
+      FLASH->CR|= CR_STRT_Set;
+    
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+
+      /* Disable the PER Bit */
+      FLASH->CR &= CR_PER_Reset;
+    }
+  }
+  else
+  {
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+    if(status == FLASH_COMPLETE)
+    { 
+      /* if the previous operation is completed, proceed to erase the page */
+      FLASH->CR2|= CR_PER_Set;
+      FLASH->AR2 = Page_Address; 
+      FLASH->CR2|= CR_STRT_Set;
+    
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+      
+      /* Disable the PER Bit */
+      FLASH->CR2 &= CR_PER_Reset;
+    }
+  }
+#else
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(EraseTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  { 
+    /* if the previous operation is completed, proceed to erase the page */
+    FLASH->CR|= CR_PER_Set;
+    FLASH->AR = Page_Address; 
+    FLASH->CR|= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(EraseTimeout);
+    
+    /* Disable the PER Bit */
+    FLASH->CR &= CR_PER_Reset;
+  }
+#endif /* STM32F10X_XL */
+
+  /* Return the Erase Status */
+  return status;
+}
+
+/**
+  * @brief  Erases all FLASH pages.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_EraseAllPages(void)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+
+#ifdef STM32F10X_XL
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to erase all pages */
+     FLASH->CR |= CR_MER_Set;
+     FLASH->CR |= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+    
+    /* Disable the MER Bit */
+    FLASH->CR &= CR_MER_Reset;
+  }    
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to erase all pages */
+     FLASH->CR2 |= CR_MER_Set;
+     FLASH->CR2 |= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+    
+    /* Disable the MER Bit */
+    FLASH->CR2 &= CR_MER_Reset;
+  }
+#else
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(EraseTimeout);
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to erase all pages */
+     FLASH->CR |= CR_MER_Set;
+     FLASH->CR |= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(EraseTimeout);
+
+    /* Disable the MER Bit */
+    FLASH->CR &= CR_MER_Reset;
+  }
+#endif /* STM32F10X_XL */
+
+  /* Return the Erase Status */
+  return status;
+}
+
+/**
+  * @brief  Erases all Bank1 FLASH pages.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices this function erases all Bank1 pages.
+  *         - For all other devices it erases all Bank1 pages and it is equivalent 
+  *           to FLASH_EraseAllPages function.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_EraseAllBank1Pages(void)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to erase all pages */
+     FLASH->CR |= CR_MER_Set;
+     FLASH->CR |= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank1Operation(EraseTimeout);
+    
+    /* Disable the MER Bit */
+    FLASH->CR &= CR_MER_Reset;
+  }    
+  /* Return the Erase Status */
+  return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Erases all Bank2 FLASH pages.
+  * @note   This function can be used only for STM32F10x_XL density devices.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_EraseAllBank2Pages(void)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to erase all pages */
+     FLASH->CR2 |= CR_MER_Set;
+     FLASH->CR2 |= CR_STRT_Set;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank2Operation(EraseTimeout);
+
+    /* Disable the MER Bit */
+    FLASH->CR2 &= CR_MER_Reset;
+  }    
+  /* Return the Erase Status */
+  return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+  * @brief  Erases the FLASH option bytes.
+  * @note   This functions erases all option bytes except the Read protection (RDP). 
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_EraseOptionBytes(void)
+{
+  uint16_t rdptmp = RDP_Key;
+
+  FLASH_Status status = FLASH_COMPLETE;
+
+  /* Get the actual read protection Option Byte value */ 
+  if(FLASH_GetReadOutProtectionStatus() != RESET)
+  {
+    rdptmp = 0x00;  
+  }
+
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(EraseTimeout);
+  if(status == FLASH_COMPLETE)
+  {
+    /* Authorize the small information block programming */
+    FLASH->OPTKEYR = FLASH_KEY1;
+    FLASH->OPTKEYR = FLASH_KEY2;
+    
+    /* if the previous operation is completed, proceed to erase the option bytes */
+    FLASH->CR |= CR_OPTER_Set;
+    FLASH->CR |= CR_STRT_Set;
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(EraseTimeout);
+    
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the erase operation is completed, disable the OPTER Bit */
+      FLASH->CR &= CR_OPTER_Reset;
+       
+      /* Enable the Option Bytes Programming operation */
+      FLASH->CR |= CR_OPTPG_Set;
+      /* Restore the last read protection Option Byte value */
+      OB->RDP = (uint16_t)rdptmp; 
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+ 
+      if(status != FLASH_TIMEOUT)
+      {
+        /* if the program operation is completed, disable the OPTPG Bit */
+        FLASH->CR &= CR_OPTPG_Reset;
+      }
+    }
+    else
+    {
+      if (status != FLASH_TIMEOUT)
+      {
+        /* Disable the OPTPG Bit */
+        FLASH->CR &= CR_OPTPG_Reset;
+      }
+    }  
+  }
+  /* Return the erase status */
+  return status;
+}
+
+/**
+  * @brief  Programs a word at a specified address.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  Address: specifies the address to be programmed.
+  * @param  Data: specifies the data to be programmed.
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. 
+  */
+FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  __IO uint32_t tmp = 0;
+
+  /* Check the parameters */
+  assert_param(IS_FLASH_ADDRESS(Address));
+
+#ifdef STM32F10X_XL
+  if(Address < FLASH_BANK1_END_ADDRESS - 2)
+  { 
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank1Operation(ProgramTimeout); 
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new first 
+        half word */
+      FLASH->CR |= CR_PG_Set;
+  
+      *(__IO uint16_t*)Address = (uint16_t)Data;
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+ 
+      if(status == FLASH_COMPLETE)
+      {
+        /* if the previous operation is completed, proceed to program the new second 
+        half word */
+        tmp = Address + 2;
+
+        *(__IO uint16_t*) tmp = Data >> 16;
+    
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation(ProgramTimeout);
+        
+        /* Disable the PG Bit */
+        FLASH->CR &= CR_PG_Reset;
+      }
+      else
+      {
+        /* Disable the PG Bit */
+        FLASH->CR &= CR_PG_Reset;
+       }
+    }
+  }
+  else if(Address == (FLASH_BANK1_END_ADDRESS - 1))
+  {
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new first 
+        half word */
+      FLASH->CR |= CR_PG_Set;
+  
+      *(__IO uint16_t*)Address = (uint16_t)Data;
+
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+      
+	  /* Disable the PG Bit */
+      FLASH->CR &= CR_PG_Reset;
+    }
+    else
+    {
+      /* Disable the PG Bit */
+      FLASH->CR &= CR_PG_Reset;
+    }
+
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new second 
+      half word */
+      FLASH->CR2 |= CR_PG_Set;
+      tmp = Address + 2;
+
+      *(__IO uint16_t*) tmp = Data >> 16;
+    
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+        
+      /* Disable the PG Bit */
+      FLASH->CR2 &= CR_PG_Reset;
+    }
+    else
+    {
+      /* Disable the PG Bit */
+      FLASH->CR2 &= CR_PG_Reset;
+    }
+  }
+  else
+  {
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new first 
+        half word */
+      FLASH->CR2 |= CR_PG_Set;
+  
+      *(__IO uint16_t*)Address = (uint16_t)Data;
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+ 
+      if(status == FLASH_COMPLETE)
+      {
+        /* if the previous operation is completed, proceed to program the new second 
+        half word */
+        tmp = Address + 2;
+
+        *(__IO uint16_t*) tmp = Data >> 16;
+    
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+        
+        /* Disable the PG Bit */
+        FLASH->CR2 &= CR_PG_Reset;
+      }
+      else
+      {
+        /* Disable the PG Bit */
+        FLASH->CR2 &= CR_PG_Reset;
+      }
+    }
+  }
+#else
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to program the new first 
+    half word */
+    FLASH->CR |= CR_PG_Set;
+  
+    *(__IO uint16_t*)Address = (uint16_t)Data;
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(ProgramTimeout);
+ 
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new second 
+      half word */
+      tmp = Address + 2;
+
+      *(__IO uint16_t*) tmp = Data >> 16;
+    
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+        
+      /* Disable the PG Bit */
+      FLASH->CR &= CR_PG_Reset;
+    }
+    else
+    {
+      /* Disable the PG Bit */
+      FLASH->CR &= CR_PG_Reset;
+    }
+  }         
+#endif /* STM32F10X_XL */
+   
+  /* Return the Program Status */
+  return status;
+}
+
+/**
+  * @brief  Programs a half word at a specified address.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  Address: specifies the address to be programmed.
+  * @param  Data: specifies the data to be programmed.
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. 
+  */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Check the parameters */
+  assert_param(IS_FLASH_ADDRESS(Address));
+
+#ifdef STM32F10X_XL
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(Address < FLASH_BANK1_END_ADDRESS)
+  {
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new data */
+      FLASH->CR |= CR_PG_Set;
+  
+      *(__IO uint16_t*)Address = Data;
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank1Operation(ProgramTimeout);
+
+      /* Disable the PG Bit */
+      FLASH->CR &= CR_PG_Reset;
+    }
+  }
+  else
+  {
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the previous operation is completed, proceed to program the new data */
+      FLASH->CR2 |= CR_PG_Set;
+  
+      *(__IO uint16_t*)Address = Data;
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastBank2Operation(ProgramTimeout);
+
+      /* Disable the PG Bit */
+      FLASH->CR2 &= CR_PG_Reset;
+    }
+  }
+#else
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* if the previous operation is completed, proceed to program the new data */
+    FLASH->CR |= CR_PG_Set;
+  
+    *(__IO uint16_t*)Address = Data;
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(ProgramTimeout);
+    
+    /* Disable the PG Bit */
+    FLASH->CR &= CR_PG_Reset;
+  } 
+#endif  /* STM32F10X_XL */
+  
+  /* Return the Program Status */
+  return status;
+}
+
+/**
+  * @brief  Programs a half word at a specified Option Byte Data address.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  Address: specifies the address to be programmed.
+  *   This parameter can be 0x1FFFF804 or 0x1FFFF806. 
+  * @param  Data: specifies the data to be programmed.
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. 
+  */
+FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Check the parameters */
+  assert_param(IS_OB_DATA_ADDRESS(Address));
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+
+  if(status == FLASH_COMPLETE)
+  {
+    /* Authorize the small information block programming */
+    FLASH->OPTKEYR = FLASH_KEY1;
+    FLASH->OPTKEYR = FLASH_KEY2;
+    /* Enables the Option Bytes Programming operation */
+    FLASH->CR |= CR_OPTPG_Set; 
+    *(__IO uint16_t*)Address = Data;
+    
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(ProgramTimeout);
+    if(status != FLASH_TIMEOUT)
+    {
+      /* if the program operation is completed, disable the OPTPG Bit */
+      FLASH->CR &= CR_OPTPG_Reset;
+    }
+  }
+  /* Return the Option Byte Data Program Status */
+  return status;
+}
+
+/**
+  * @brief  Write protects the desired pages
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  FLASH_Pages: specifies the address of the pages to be write protected.
+  *   This parameter can be:
+  *     @arg For @b STM32_Low-density_devices: value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages28to31  
+  *     @arg For @b STM32_Medium-density_devices: value between FLASH_WRProt_Pages0to3
+  *       and FLASH_WRProt_Pages124to127
+  *     @arg For @b STM32_High-density_devices: value between FLASH_WRProt_Pages0to1 and
+  *       FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to255
+  *     @arg For @b STM32_Connectivity_line_devices: value between FLASH_WRProt_Pages0to1 and
+  *       FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to127    
+  *     @arg For @b STM32_XL-density_devices: value between FLASH_WRProt_Pages0to1 and
+  *       FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to511
+  *     @arg FLASH_WRProt_AllPages
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
+{
+  uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
+  
+  FLASH_Status status = FLASH_COMPLETE;
+  
+  /* Check the parameters */
+  assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
+  
+  FLASH_Pages = (uint32_t)(~FLASH_Pages);
+  WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
+  WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
+  WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
+  WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);
+  
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {
+    /* Authorizes the small information block programming */
+    FLASH->OPTKEYR = FLASH_KEY1;
+    FLASH->OPTKEYR = FLASH_KEY2;
+    FLASH->CR |= CR_OPTPG_Set;
+    if(WRP0_Data != 0xFF)
+    {
+      OB->WRP0 = WRP0_Data;
+      
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+    }
+    if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
+    {
+      OB->WRP1 = WRP1_Data;
+      
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+    }
+    if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
+    {
+      OB->WRP2 = WRP2_Data;
+      
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+    }
+    
+    if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF))
+    {
+      OB->WRP3 = WRP3_Data;
+     
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(ProgramTimeout);
+    }
+          
+    if(status != FLASH_TIMEOUT)
+    {
+      /* if the program operation is completed, disable the OPTPG Bit */
+      FLASH->CR &= CR_OPTPG_Reset;
+    }
+  } 
+  /* Return the write protection operation Status */
+  return status;       
+}
+
+/**
+  * @brief  Enables or disables the read out protection.
+  * @note   If the user has already programmed the other option bytes before calling 
+  *   this function, he must re-program them since this function erases all option bytes.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  Newstate: new state of the ReadOut Protection.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
+{
+  FLASH_Status status = FLASH_COMPLETE;
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  status = FLASH_WaitForLastOperation(EraseTimeout);
+  if(status == FLASH_COMPLETE)
+  {
+    /* Authorizes the small information block programming */
+    FLASH->OPTKEYR = FLASH_KEY1;
+    FLASH->OPTKEYR = FLASH_KEY2;
+    FLASH->CR |= CR_OPTER_Set;
+    FLASH->CR |= CR_STRT_Set;
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(EraseTimeout);
+    if(status == FLASH_COMPLETE)
+    {
+      /* if the erase operation is completed, disable the OPTER Bit */
+      FLASH->CR &= CR_OPTER_Reset;
+      /* Enable the Option Bytes Programming operation */
+      FLASH->CR |= CR_OPTPG_Set; 
+      if(NewState != DISABLE)
+      {
+        OB->RDP = 0x00;
+      }
+      else
+      {
+        OB->RDP = RDP_Key;  
+      }
+      /* Wait for last operation to be completed */
+      status = FLASH_WaitForLastOperation(EraseTimeout); 
+    
+      if(status != FLASH_TIMEOUT)
+      {
+        /* if the program operation is completed, disable the OPTPG Bit */
+        FLASH->CR &= CR_OPTPG_Reset;
+      }
+    }
+    else 
+    {
+      if(status != FLASH_TIMEOUT)
+      {
+        /* Disable the OPTER Bit */
+        FLASH->CR &= CR_OPTER_Reset;
+      }
+    }
+  }
+  /* Return the protection operation Status */
+  return status;       
+}
+
+/**
+  * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  OB_IWDG: Selects the IWDG mode
+  *   This parameter can be one of the following values:
+  *     @arg OB_IWDG_SW: Software IWDG selected
+  *     @arg OB_IWDG_HW: Hardware IWDG selected
+  * @param  OB_STOP: Reset event when entering STOP mode.
+  *   This parameter can be one of the following values:
+  *     @arg OB_STOP_NoRST: No reset generated when entering in STOP
+  *     @arg OB_STOP_RST: Reset generated when entering in STOP
+  * @param  OB_STDBY: Reset event when entering Standby mode.
+  *   This parameter can be one of the following values:
+  *     @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY
+  *     @arg OB_STDBY_RST: Reset generated when entering in STANDBY
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, 
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)
+{
+  FLASH_Status status = FLASH_COMPLETE; 
+
+  /* Check the parameters */
+  assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
+  assert_param(IS_OB_STOP_SOURCE(OB_STOP));
+  assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
+
+  /* Authorize the small information block programming */
+  FLASH->OPTKEYR = FLASH_KEY1;
+  FLASH->OPTKEYR = FLASH_KEY2;
+  
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {  
+    /* Enable the Option Bytes Programming operation */
+    FLASH->CR |= CR_OPTPG_Set; 
+           
+    OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8))); 
+  
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(ProgramTimeout);
+    if(status != FLASH_TIMEOUT)
+    {
+      /* if the program operation is completed, disable the OPTPG Bit */
+      FLASH->CR &= CR_OPTPG_Reset;
+    }
+  }    
+  /* Return the Option Byte program Status */
+  return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Configures to boot from Bank1 or Bank2.  
+  * @note   This function can be used only for STM32F10x_XL density devices.
+  * @param  FLASH_BOOT: select the FLASH Bank to boot from.
+  *   This parameter can be one of the following values:
+  *     @arg FLASH_BOOT_Bank1: At startup, if boot pins are set in boot from user Flash
+  *        position and this parameter is selected the device will boot from Bank1(Default).
+  *     @arg FLASH_BOOT_Bank2: At startup, if boot pins are set in boot from user Flash
+  *        position and this parameter is selected the device will boot from Bank2 or Bank1,
+  *        depending on the activation of the bank. The active banks are checked in
+  *        the following order: Bank2, followed by Bank1.
+  *        The active bank is recognized by the value programmed at the base address
+  *        of the respective bank (corresponding to the initial stack pointer value
+  *        in the interrupt vector table).
+  *        For more information, please refer to AN2606 from www.st.com.    
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, 
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT)
+{ 
+  FLASH_Status status = FLASH_COMPLETE; 
+  assert_param(IS_FLASH_BOOT(FLASH_BOOT));
+  /* Authorize the small information block programming */
+  FLASH->OPTKEYR = FLASH_KEY1;
+  FLASH->OPTKEYR = FLASH_KEY2;
+  
+  /* Wait for last operation to be completed */
+  status = FLASH_WaitForLastOperation(ProgramTimeout);
+  
+  if(status == FLASH_COMPLETE)
+  {  
+    /* Enable the Option Bytes Programming operation */
+    FLASH->CR |= CR_OPTPG_Set; 
+
+    if(FLASH_BOOT == FLASH_BOOT_Bank1)
+    {
+      OB->USER |= OB_USER_BFB2;
+    }
+    else
+    {
+      OB->USER &= (uint16_t)(~(uint16_t)(OB_USER_BFB2));
+    }
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(ProgramTimeout);
+    if(status != FLASH_TIMEOUT)
+    {
+      /* if the program operation is completed, disable the OPTPG Bit */
+      FLASH->CR &= CR_OPTPG_Reset;
+    }
+  }    
+  /* Return the Option Byte program Status */
+  return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+  * @brief  Returns the FLASH User Option Bytes values.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
+  *         and RST_STDBY(Bit2).
+  */
+uint32_t FLASH_GetUserOptionByte(void)
+{
+  /* Return the User Option Byte */
+  return (uint32_t)(FLASH->OBR >> 2);
+}
+
+/**
+  * @brief  Returns the FLASH Write Protection Option Bytes Register value.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval The FLASH Write Protection  Option Bytes Register value
+  */
+uint32_t FLASH_GetWriteProtectionOptionByte(void)
+{
+  /* Return the Flash write protection Register value */
+  return (uint32_t)(FLASH->WRPR);
+}
+
+/**
+  * @brief  Checks whether the FLASH Read Out Protection Status is set or not.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval FLASH ReadOut Protection Status(SET or RESET)
+  */
+FlagStatus FLASH_GetReadOutProtectionStatus(void)
+{
+  FlagStatus readoutstatus = RESET;
+  if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
+  {
+    readoutstatus = SET;
+  }
+  else
+  {
+    readoutstatus = RESET;
+  }
+  return readoutstatus;
+}
+
+/**
+  * @brief  Checks whether the FLASH Prefetch Buffer status is set or not.
+  * @note   This function can be used for all STM32F10x devices.
+  * @param  None
+  * @retval FLASH Prefetch Buffer Status (SET or RESET).
+  */
+FlagStatus FLASH_GetPrefetchBufferStatus(void)
+{
+  FlagStatus bitstatus = RESET;
+  
+  if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */
+  return bitstatus; 
+}
+
+/**
+  * @brief  Enables or disables the specified FLASH interrupts.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices, enables or disables the specified FLASH interrupts
+              for Bank1 and Bank2.
+  *         - For other devices it enables or disables the specified FLASH interrupts for Bank1.
+  * @param  FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled.
+  *   This parameter can be any combination of the following values:
+  *     @arg FLASH_IT_ERROR: FLASH Error Interrupt
+  *     @arg FLASH_IT_EOP: FLASH end of operation Interrupt
+  * @param  NewState: new state of the specified Flash interrupts.
+  *   This parameter can be: ENABLE or DISABLE.      
+  * @retval None 
+  */
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
+{
+#ifdef STM32F10X_XL
+  /* Check the parameters */
+  assert_param(IS_FLASH_IT(FLASH_IT)); 
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  if((FLASH_IT & 0x80000000) != 0x0)
+  {
+    if(NewState != DISABLE)
+    {
+      /* Enable the interrupt sources */
+      FLASH->CR2 |= (FLASH_IT & 0x7FFFFFFF);
+    }
+    else
+    {
+      /* Disable the interrupt sources */
+      FLASH->CR2 &= ~(uint32_t)(FLASH_IT & 0x7FFFFFFF);
+    }
+  }
+  else
+  {
+    if(NewState != DISABLE)
+    {
+      /* Enable the interrupt sources */
+      FLASH->CR |= FLASH_IT;
+    }
+    else
+    {
+      /* Disable the interrupt sources */
+      FLASH->CR &= ~(uint32_t)FLASH_IT;
+    }
+  }
+#else
+  /* Check the parameters */
+  assert_param(IS_FLASH_IT(FLASH_IT)); 
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  if(NewState != DISABLE)
+  {
+    /* Enable the interrupt sources */
+    FLASH->CR |= FLASH_IT;
+  }
+  else
+  {
+    /* Disable the interrupt sources */
+    FLASH->CR &= ~(uint32_t)FLASH_IT;
+  }
+#endif /* STM32F10X_XL */
+}
+
+/**
+  * @brief  Checks whether the specified FLASH flag is set or not.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices, this function checks whether the specified 
+  *           Bank1 or Bank2 flag is set or not.
+  *         - For other devices, it checks whether the specified Bank1 flag is 
+  *           set or not.
+  * @param  FLASH_FLAG: specifies the FLASH flag to check.
+  *   This parameter can be one of the following values:
+  *     @arg FLASH_FLAG_BSY: FLASH Busy flag           
+  *     @arg FLASH_FLAG_PGERR: FLASH Program error flag       
+  *     @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag      
+  *     @arg FLASH_FLAG_EOP: FLASH End of Operation flag           
+  *     @arg FLASH_FLAG_OPTERR:  FLASH Option Byte error flag     
+  * @retval The new state of FLASH_FLAG (SET or RESET).
+  */
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
+{
+  FlagStatus bitstatus = RESET;
+
+#ifdef STM32F10X_XL
+  /* Check the parameters */
+  assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;
+  if(FLASH_FLAG == FLASH_FLAG_OPTERR) 
+  {
+    if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
+    {
+      bitstatus = SET;
+    }
+    else
+    {
+      bitstatus = RESET;
+    }
+  }
+  else
+  {
+    if((FLASH_FLAG & 0x80000000) != 0x0)
+    {
+      if((FLASH->SR2 & FLASH_FLAG) != (uint32_t)RESET)
+      {
+        bitstatus = SET;
+      }
+      else
+      {
+        bitstatus = RESET;
+      }
+    }
+    else
+    {
+      if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+      {
+        bitstatus = SET;
+      }
+      else
+      {
+        bitstatus = RESET;
+      }
+    }
+  }
+#else
+  /* Check the parameters */
+  assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;
+  if(FLASH_FLAG == FLASH_FLAG_OPTERR) 
+  {
+    if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
+    {
+      bitstatus = SET;
+    }
+    else
+    {
+      bitstatus = RESET;
+    }
+  }
+  else
+  {
+   if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+    {
+      bitstatus = SET;
+    }
+    else
+    {
+      bitstatus = RESET;
+    }
+  }
+#endif /* STM32F10X_XL */
+
+  /* Return the new state of FLASH_FLAG (SET or RESET) */
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the FLASH's pending flags.
+  * @note   This function can be used for all STM32F10x devices.
+  *         - For STM32F10X_XL devices, this function clears Bank1 or Bank2’s pending flags
+  *         - For other devices, it clears Bank1’s pending flags.
+  * @param  FLASH_FLAG: specifies the FLASH flags to clear.
+  *   This parameter can be any combination of the following values:         
+  *     @arg FLASH_FLAG_PGERR: FLASH Program error flag       
+  *     @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag      
+  *     @arg FLASH_FLAG_EOP: FLASH End of Operation flag           
+  * @retval None
+  */
+void FLASH_ClearFlag(uint32_t FLASH_FLAG)
+{
+#ifdef STM32F10X_XL
+  /* Check the parameters */
+  assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
+
+  if((FLASH_FLAG & 0x80000000) != 0x0)
+  {
+    /* Clear the flags */
+    FLASH->SR2 = FLASH_FLAG;
+  }
+  else
+  {
+    /* Clear the flags */
+    FLASH->SR = FLASH_FLAG;
+  }  
+
+#else
+  /* Check the parameters */
+  assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
+  
+  /* Clear the flags */
+  FLASH->SR = FLASH_FLAG;
+#endif /* STM32F10X_XL */
+}
+
+/**
+  * @brief  Returns the FLASH Status.
+  * @note   This function can be used for all STM32F10x devices, it is equivalent
+  *         to FLASH_GetBank1Status function.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP or FLASH_COMPLETE
+  */
+FLASH_Status FLASH_GetStatus(void)
+{
+  FLASH_Status flashstatus = FLASH_COMPLETE;
+  
+  if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) 
+  {
+    flashstatus = FLASH_BUSY;
+  }
+  else 
+  {  
+    if((FLASH->SR & FLASH_FLAG_PGERR) != 0)
+    { 
+      flashstatus = FLASH_ERROR_PG;
+    }
+    else 
+    {
+      if((FLASH->SR & FLASH_FLAG_WRPRTERR) != 0 )
+      {
+        flashstatus = FLASH_ERROR_WRP;
+      }
+      else
+      {
+        flashstatus = FLASH_COMPLETE;
+      }
+    }
+  }
+  /* Return the Flash Status */
+  return flashstatus;
+}
+
+/**
+  * @brief  Returns the FLASH Bank1 Status.
+  * @note   This function can be used for all STM32F10x devices, it is equivalent
+  *         to FLASH_GetStatus function.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP or FLASH_COMPLETE
+  */
+FLASH_Status FLASH_GetBank1Status(void)
+{
+  FLASH_Status flashstatus = FLASH_COMPLETE;
+  
+  if((FLASH->SR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY) 
+  {
+    flashstatus = FLASH_BUSY;
+  }
+  else 
+  {  
+    if((FLASH->SR & FLASH_FLAG_BANK1_PGERR) != 0)
+    { 
+      flashstatus = FLASH_ERROR_PG;
+    }
+    else 
+    {
+      if((FLASH->SR & FLASH_FLAG_BANK1_WRPRTERR) != 0 )
+      {
+        flashstatus = FLASH_ERROR_WRP;
+      }
+      else
+      {
+        flashstatus = FLASH_COMPLETE;
+      }
+    }
+  }
+  /* Return the Flash Status */
+  return flashstatus;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Returns the FLASH Bank2 Status.
+  * @note   This function can be used for STM32F10x_XL density devices.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *        FLASH_ERROR_WRP or FLASH_COMPLETE
+  */
+FLASH_Status FLASH_GetBank2Status(void)
+{
+  FLASH_Status flashstatus = FLASH_COMPLETE;
+  
+  if((FLASH->SR2 & (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) 
+  {
+    flashstatus = FLASH_BUSY;
+  }
+  else 
+  {  
+    if((FLASH->SR2 & (FLASH_FLAG_BANK2_PGERR & 0x7FFFFFFF)) != 0)
+    { 
+      flashstatus = FLASH_ERROR_PG;
+    }
+    else 
+    {
+      if((FLASH->SR2 & (FLASH_FLAG_BANK2_WRPRTERR & 0x7FFFFFFF)) != 0 )
+      {
+        flashstatus = FLASH_ERROR_WRP;
+      }
+      else
+      {
+        flashstatus = FLASH_COMPLETE;
+      }
+    }
+  }
+  /* Return the Flash Status */
+  return flashstatus;
+}
+#endif /* STM32F10X_XL */
+/**
+  * @brief  Waits for a Flash operation to complete or a TIMEOUT to occur.
+  * @note   This function can be used for all STM32F10x devices, 
+  *         it is equivalent to FLASH_WaitForLastBank1Operation.
+  *         - For STM32F10X_XL devices this function waits for a Bank1 Flash operation
+  *           to complete or a TIMEOUT to occur.
+  *         - For all other devices it waits for a Flash operation to complete 
+  *           or a TIMEOUT to occur.
+  * @param  Timeout: FLASH programming Timeout
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
+{ 
+  FLASH_Status status = FLASH_COMPLETE;
+   
+  /* Check for the Flash Status */
+  status = FLASH_GetBank1Status();
+  /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+  while((status == FLASH_BUSY) && (Timeout != 0x00))
+  {
+    status = FLASH_GetBank1Status();
+    Timeout--;
+  }
+  if(Timeout == 0x00 )
+  {
+    status = FLASH_TIMEOUT;
+  }
+  /* Return the operation status */
+  return status;
+}
+
+/**
+  * @brief  Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur.
+  * @note   This function can be used for all STM32F10x devices, 
+  *         it is equivalent to FLASH_WaitForLastOperation.
+  * @param  Timeout: FLASH programming Timeout
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout)
+{ 
+  FLASH_Status status = FLASH_COMPLETE;
+   
+  /* Check for the Flash Status */
+  status = FLASH_GetBank1Status();
+  /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+  while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00))
+  {
+    status = FLASH_GetBank1Status();
+    Timeout--;
+  }
+  if(Timeout == 0x00 )
+  {
+    status = FLASH_TIMEOUT;
+  }
+  /* Return the operation status */
+  return status;
+}
+
+#ifdef STM32F10X_XL
+/**
+  * @brief  Waits for a Flash operation on Bank2 to complete or a TIMEOUT to occur.
+  * @note   This function can be used only for STM32F10x_XL density devices.
+  * @param  Timeout: FLASH programming Timeout
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout)
+{ 
+  FLASH_Status status = FLASH_COMPLETE;
+   
+  /* Check for the Flash Status */
+  status = FLASH_GetBank2Status();
+  /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+  while((status == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) && (Timeout != 0x00))
+  {
+    status = FLASH_GetBank2Status();
+    Timeout--;
+  }
+  if(Timeout == 0x00 )
+  {
+    status = FLASH_TIMEOUT;
+  }
+  /* Return the operation status */
+  return status;
+}
+#endif /* STM32F10X_XL */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_gpio.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,650 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_gpio.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the GPIO firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_gpio.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup GPIO 
+  * @brief GPIO driver modules
+  * @{
+  */ 
+
+/** @defgroup GPIO_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Private_Defines
+  * @{
+  */
+
+/* ------------ RCC registers bit address in the alias region ----------------*/
+#define AFIO_OFFSET                 (AFIO_BASE - PERIPH_BASE)
+
+/* --- EVENTCR Register -----*/
+
+/* Alias word address of EVOE bit */
+#define EVCR_OFFSET                 (AFIO_OFFSET + 0x00)
+#define EVOE_BitNumber              ((uint8_t)0x07)
+#define EVCR_EVOE_BB                (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4))
+
+
+/* ---  MAPR Register ---*/ 
+/* Alias word address of MII_RMII_SEL bit */ 
+#define MAPR_OFFSET                 (AFIO_OFFSET + 0x04) 
+#define MII_RMII_SEL_BitNumber      ((u8)0x17) 
+#define MAPR_MII_RMII_SEL_BB        (PERIPH_BB_BASE + (MAPR_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4))
+
+
+#define EVCR_PORTPINCONFIG_MASK     ((uint16_t)0xFF80)
+#define LSB_MASK                    ((uint16_t)0xFFFF)
+#define DBGAFR_POSITION_MASK        ((uint32_t)0x000F0000)
+#define DBGAFR_SWJCFG_MASK          ((uint32_t)0xF0FFFFFF)
+#define DBGAFR_LOCATION_MASK        ((uint32_t)0x00200000)
+#define DBGAFR_NUMBITS_MASK         ((uint32_t)0x00100000)
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Deinitializes the GPIOx peripheral registers to their default reset values.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @retval None
+  */
+void GPIO_DeInit(GPIO_TypeDef* GPIOx)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  
+  if (GPIOx == GPIOA)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);
+  }
+  else if (GPIOx == GPIOB)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);
+  }
+  else if (GPIOx == GPIOC)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE);
+  }
+  else if (GPIOx == GPIOD)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE);
+  }    
+  else if (GPIOx == GPIOE)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE);
+  } 
+  else if (GPIOx == GPIOF)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, DISABLE);
+  }
+  else
+  {
+    if (GPIOx == GPIOG)
+    {
+      RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, ENABLE);
+      RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, DISABLE);
+    }
+  }
+}
+
+/**
+  * @brief  Deinitializes the Alternate Functions (remap, event control
+  *   and EXTI configuration) registers to their default reset values.
+  * @param  None
+  * @retval None
+  */
+void GPIO_AFIODeInit(void)
+{
+  RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE);
+  RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE);
+}
+
+/**
+  * @brief  Initializes the GPIOx peripheral according to the specified
+  *         parameters in the GPIO_InitStruct.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
+  *         contains the configuration information for the specified GPIO peripheral.
+  * @retval None
+  */
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
+{
+  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
+  uint32_t tmpreg = 0x00, pinmask = 0x00;
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
+  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  
+  
+/*---------------------------- GPIO Mode Configuration -----------------------*/
+  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
+  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
+  { 
+    /* Check the parameters */
+    assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
+    /* Output mode */
+    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
+  }
+/*---------------------------- GPIO CRL Configuration ------------------------*/
+  /* Configure the eight low port pins */
+  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
+  {
+    tmpreg = GPIOx->CRL;
+    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
+    {
+      pos = ((uint32_t)0x01) << pinpos;
+      /* Get the port pins position */
+      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
+      if (currentpin == pos)
+      {
+        pos = pinpos << 2;
+        /* Clear the corresponding low control register bits */
+        pinmask = ((uint32_t)0x0F) << pos;
+        tmpreg &= ~pinmask;
+        /* Write the mode configuration in the corresponding bits */
+        tmpreg |= (currentmode << pos);
+        /* Reset the corresponding ODR bit */
+        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
+        {
+          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
+        }
+        else
+        {
+          /* Set the corresponding ODR bit */
+          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
+          {
+            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
+          }
+        }
+      }
+    }
+    GPIOx->CRL = tmpreg;
+  }
+/*---------------------------- GPIO CRH Configuration ------------------------*/
+  /* Configure the eight high port pins */
+  if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
+  {
+    tmpreg = GPIOx->CRH;
+    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
+    {
+      pos = (((uint32_t)0x01) << (pinpos + 0x08));
+      /* Get the port pins position */
+      currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
+      if (currentpin == pos)
+      {
+        pos = pinpos << 2;
+        /* Clear the corresponding high control register bits */
+        pinmask = ((uint32_t)0x0F) << pos;
+        tmpreg &= ~pinmask;
+        /* Write the mode configuration in the corresponding bits */
+        tmpreg |= (currentmode << pos);
+        /* Reset the corresponding ODR bit */
+        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
+        {
+          GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
+        }
+        /* Set the corresponding ODR bit */
+        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
+        {
+          GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
+        }
+      }
+    }
+    GPIOx->CRH = tmpreg;
+  }
+}
+
+/**
+  * @brief  Fills each GPIO_InitStruct member with its default value.
+  * @param  GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will
+  *         be initialized.
+  * @retval None
+  */
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
+{
+  /* Reset GPIO init structure parameters values */
+  GPIO_InitStruct->GPIO_Pin  = GPIO_Pin_All;
+  GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
+  GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
+}
+
+/**
+  * @brief  Reads the specified input port pin.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin:  specifies the port bit to read.
+  *   This parameter can be GPIO_Pin_x where x can be (0..15).
+  * @retval The input port pin value.
+  */
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+  uint8_t bitstatus = 0x00;
+  
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 
+  
+  if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
+  {
+    bitstatus = (uint8_t)Bit_SET;
+  }
+  else
+  {
+    bitstatus = (uint8_t)Bit_RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Reads the specified GPIO input data port.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @retval GPIO input data port value.
+  */
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  
+  return ((uint16_t)GPIOx->IDR);
+}
+
+/**
+  * @brief  Reads the specified output data port bit.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin:  specifies the port bit to read.
+  *   This parameter can be GPIO_Pin_x where x can be (0..15).
+  * @retval The output port pin value.
+  */
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+  uint8_t bitstatus = 0x00;
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 
+  
+  if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
+  {
+    bitstatus = (uint8_t)Bit_SET;
+  }
+  else
+  {
+    bitstatus = (uint8_t)Bit_RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Reads the specified GPIO output data port.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @retval GPIO output data port value.
+  */
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+    
+  return ((uint16_t)GPIOx->ODR);
+}
+
+/**
+  * @brief  Sets the selected data port bits.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bits to be written.
+  *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+  * @retval None
+  */
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+  
+  GPIOx->BSRR = GPIO_Pin;
+}
+
+/**
+  * @brief  Clears the selected data port bits.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bits to be written.
+  *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+  * @retval None
+  */
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+  
+  GPIOx->BRR = GPIO_Pin;
+}
+
+/**
+  * @brief  Sets or clears the selected data port bit.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bit to be written.
+  *   This parameter can be one of GPIO_Pin_x where x can be (0..15).
+  * @param  BitVal: specifies the value to be written to the selected bit.
+  *   This parameter can be one of the BitAction enum values:
+  *     @arg Bit_RESET: to clear the port pin
+  *     @arg Bit_SET: to set the port pin
+  * @retval None
+  */
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+  assert_param(IS_GPIO_BIT_ACTION(BitVal)); 
+  
+  if (BitVal != Bit_RESET)
+  {
+    GPIOx->BSRR = GPIO_Pin;
+  }
+  else
+  {
+    GPIOx->BRR = GPIO_Pin;
+  }
+}
+
+/**
+  * @brief  Writes data to the specified GPIO data port.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  PortVal: specifies the value to be written to the port output data register.
+  * @retval None
+  */
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  
+  GPIOx->ODR = PortVal;
+}
+
+/**
+  * @brief  Locks GPIO Pins configuration registers.
+  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bit to be written.
+  *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+  * @retval None
+  */
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+  uint32_t tmp = 0x00010000;
+  
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+  
+  tmp |= GPIO_Pin;
+  /* Set LCKK bit */
+  GPIOx->LCKR = tmp;
+  /* Reset LCKK bit */
+  GPIOx->LCKR =  GPIO_Pin;
+  /* Set LCKK bit */
+  GPIOx->LCKR = tmp;
+  /* Read LCKK bit*/
+  tmp = GPIOx->LCKR;
+  /* Read LCKK bit*/
+  tmp = GPIOx->LCKR;
+}
+
+/**
+  * @brief  Selects the GPIO pin used as Event output.
+  * @param  GPIO_PortSource: selects the GPIO port to be used as source
+  *   for Event output.
+  *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..E).
+  * @param  GPIO_PinSource: specifies the pin for the Event output.
+  *   This parameter can be GPIO_PinSourcex where x can be (0..15).
+  * @retval None
+  */
+void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
+{
+  uint32_t tmpreg = 0x00;
+  /* Check the parameters */
+  assert_param(IS_GPIO_EVENTOUT_PORT_SOURCE(GPIO_PortSource));
+  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
+    
+  tmpreg = AFIO->EVCR;
+  /* Clear the PORT[6:4] and PIN[3:0] bits */
+  tmpreg &= EVCR_PORTPINCONFIG_MASK;
+  tmpreg |= (uint32_t)GPIO_PortSource << 0x04;
+  tmpreg |= GPIO_PinSource;
+  AFIO->EVCR = tmpreg;
+}
+
+/**
+  * @brief  Enables or disables the Event Output.
+  * @param  NewState: new state of the Event output.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void GPIO_EventOutputCmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  *(__IO uint32_t *) EVCR_EVOE_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Changes the mapping of the specified pin.
+  * @param  GPIO_Remap: selects the pin to remap.
+  *   This parameter can be one of the following values:
+  *     @arg GPIO_Remap_SPI1             : SPI1 Alternate Function mapping
+  *     @arg GPIO_Remap_I2C1             : I2C1 Alternate Function mapping
+  *     @arg GPIO_Remap_USART1           : USART1 Alternate Function mapping
+  *     @arg GPIO_Remap_USART2           : USART2 Alternate Function mapping
+  *     @arg GPIO_PartialRemap_USART3    : USART3 Partial Alternate Function mapping
+  *     @arg GPIO_FullRemap_USART3       : USART3 Full Alternate Function mapping
+  *     @arg GPIO_PartialRemap_TIM1      : TIM1 Partial Alternate Function mapping
+  *     @arg GPIO_FullRemap_TIM1         : TIM1 Full Alternate Function mapping
+  *     @arg GPIO_PartialRemap1_TIM2     : TIM2 Partial1 Alternate Function mapping
+  *     @arg GPIO_PartialRemap2_TIM2     : TIM2 Partial2 Alternate Function mapping
+  *     @arg GPIO_FullRemap_TIM2         : TIM2 Full Alternate Function mapping
+  *     @arg GPIO_PartialRemap_TIM3      : TIM3 Partial Alternate Function mapping
+  *     @arg GPIO_FullRemap_TIM3         : TIM3 Full Alternate Function mapping
+  *     @arg GPIO_Remap_TIM4             : TIM4 Alternate Function mapping
+  *     @arg GPIO_Remap1_CAN1            : CAN1 Alternate Function mapping
+  *     @arg GPIO_Remap2_CAN1            : CAN1 Alternate Function mapping
+  *     @arg GPIO_Remap_PD01             : PD01 Alternate Function mapping
+  *     @arg GPIO_Remap_TIM5CH4_LSI      : LSI connected to TIM5 Channel4 input capture for calibration
+  *     @arg GPIO_Remap_ADC1_ETRGINJ     : ADC1 External Trigger Injected Conversion remapping
+  *     @arg GPIO_Remap_ADC1_ETRGREG     : ADC1 External Trigger Regular Conversion remapping
+  *     @arg GPIO_Remap_ADC2_ETRGINJ     : ADC2 External Trigger Injected Conversion remapping
+  *     @arg GPIO_Remap_ADC2_ETRGREG     : ADC2 External Trigger Regular Conversion remapping
+  *     @arg GPIO_Remap_ETH              : Ethernet remapping (only for Connectivity line devices)
+  *     @arg GPIO_Remap_CAN2             : CAN2 remapping (only for Connectivity line devices)
+  *     @arg GPIO_Remap_SWJ_NoJTRST      : Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST
+  *     @arg GPIO_Remap_SWJ_JTAGDisable  : JTAG-DP Disabled and SW-DP Enabled
+  *     @arg GPIO_Remap_SWJ_Disable      : Full SWJ Disabled (JTAG-DP + SW-DP)
+  *     @arg GPIO_Remap_SPI3             : SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices)
+  *                                        When the SPI3/I2S3 is remapped using this function, the SWJ is configured
+  *                                        to Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST.   
+  *     @arg GPIO_Remap_TIM2ITR1_PTP_SOF : Ethernet PTP output or USB OTG SOF (Start of Frame) connected
+  *                                        to TIM2 Internal Trigger 1 for calibration (only for Connectivity line devices)
+  *                                        If the GPIO_Remap_TIM2ITR1_PTP_SOF is enabled the TIM2 ITR1 is connected to 
+  *                                        Ethernet PTP output. When Reset TIM2 ITR1 is connected to USB OTG SOF output.    
+  *     @arg GPIO_Remap_PTP_PPS          : Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices)
+  *     @arg GPIO_Remap_TIM15            : TIM15 Alternate Function mapping (only for Value line devices)
+  *     @arg GPIO_Remap_TIM16            : TIM16 Alternate Function mapping (only for Value line devices)
+  *     @arg GPIO_Remap_TIM17            : TIM17 Alternate Function mapping (only for Value line devices)
+  *     @arg GPIO_Remap_CEC              : CEC Alternate Function mapping (only for Value line devices)
+  *     @arg GPIO_Remap_TIM1_DMA         : TIM1 DMA requests mapping (only for Value line devices)
+  *     @arg GPIO_Remap_TIM9             : TIM9 Alternate Function mapping (only for XL-density devices)
+  *     @arg GPIO_Remap_TIM10            : TIM10 Alternate Function mapping (only for XL-density devices)
+  *     @arg GPIO_Remap_TIM11            : TIM11 Alternate Function mapping (only for XL-density devices)
+  *     @arg GPIO_Remap_TIM13            : TIM13 Alternate Function mapping (only for High density Value line and XL-density devices)
+  *     @arg GPIO_Remap_TIM14            : TIM14 Alternate Function mapping (only for High density Value line and XL-density devices)
+  *     @arg GPIO_Remap_FSMC_NADV        : FSMC_NADV Alternate Function mapping (only for High density Value line and XL-density devices)
+  *     @arg GPIO_Remap_TIM67_DAC_DMA    : TIM6/TIM7 and DAC DMA requests remapping (only for High density Value line devices)
+  *     @arg GPIO_Remap_TIM12            : TIM12 Alternate Function mapping (only for High density Value line devices)
+  *     @arg GPIO_Remap_MISC             : Miscellaneous Remap (DMA2 Channel5 Position and DAC Trigger remapping, 
+  *                                        only for High density Value line devices)     
+  * @param  NewState: new state of the port pin remapping.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
+{
+  uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00;
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_REMAP(GPIO_Remap));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));  
+  
+  if((GPIO_Remap & 0x80000000) == 0x80000000)
+  {
+    tmpreg = AFIO->MAPR2;
+  }
+  else
+  {
+    tmpreg = AFIO->MAPR;
+  }
+
+  tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10;
+  tmp = GPIO_Remap & LSB_MASK;
+
+  if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK))
+  {
+    tmpreg &= DBGAFR_SWJCFG_MASK;
+    AFIO->MAPR &= DBGAFR_SWJCFG_MASK;
+  }
+  else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK)
+  {
+    tmp1 = ((uint32_t)0x03) << tmpmask;
+    tmpreg &= ~tmp1;
+    tmpreg |= ~DBGAFR_SWJCFG_MASK;
+  }
+  else
+  {
+    tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10));
+    tmpreg |= ~DBGAFR_SWJCFG_MASK;
+  }
+
+  if (NewState != DISABLE)
+  {
+    tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10));
+  }
+
+  if((GPIO_Remap & 0x80000000) == 0x80000000)
+  {
+    AFIO->MAPR2 = tmpreg;
+  }
+  else
+  {
+    AFIO->MAPR = tmpreg;
+  }  
+}
+
+/**
+  * @brief  Selects the GPIO pin used as EXTI Line.
+  * @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
+  *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
+  * @param  GPIO_PinSource: specifies the EXTI line to be configured.
+  *   This parameter can be GPIO_PinSourcex where x can be (0..15).
+  * @retval None
+  */
+void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
+{
+  uint32_t tmp = 0x00;
+  /* Check the parameters */
+  assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
+  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
+  
+  tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
+  AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
+  AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
+}
+
+/**
+  * @brief  Selects the Ethernet media interface.
+  * @note   This function applies only to STM32 Connectivity line devices.  
+  * @param  GPIO_ETH_MediaInterface: specifies the Media Interface mode.
+  *   This parameter can be one of the following values:
+  *     @arg GPIO_ETH_MediaInterface_MII: MII mode
+  *     @arg GPIO_ETH_MediaInterface_RMII: RMII mode    
+  * @retval None
+  */
+void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) 
+{ 
+  assert_param(IS_GPIO_ETH_MEDIA_INTERFACE(GPIO_ETH_MediaInterface)); 
+
+  /* Configure MII_RMII selection bit */ 
+  *(__IO uint32_t *) MAPR_MII_RMII_SEL_BB = GPIO_ETH_MediaInterface; 
+}
+  
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_rcc.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1470 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_rcc.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the RCC firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup RCC 
+  * @brief RCC driver modules
+  * @{
+  */ 
+
+/** @defgroup RCC_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Private_Defines
+  * @{
+  */
+
+/* ------------ RCC registers bit address in the alias region ----------- */
+#define RCC_OFFSET                (RCC_BASE - PERIPH_BASE)
+
+/* --- CR Register ---*/
+
+/* Alias word address of HSION bit */
+#define CR_OFFSET                 (RCC_OFFSET + 0x00)
+#define HSION_BitNumber           0x00
+#define CR_HSION_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))
+
+/* Alias word address of PLLON bit */
+#define PLLON_BitNumber           0x18
+#define CR_PLLON_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))
+
+#ifdef STM32F10X_CL
+ /* Alias word address of PLL2ON bit */
+ #define PLL2ON_BitNumber          0x1A
+ #define CR_PLL2ON_BB              (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL2ON_BitNumber * 4))
+
+ /* Alias word address of PLL3ON bit */
+ #define PLL3ON_BitNumber          0x1C
+ #define CR_PLL3ON_BB              (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL3ON_BitNumber * 4))
+#endif /* STM32F10X_CL */ 
+
+/* Alias word address of CSSON bit */
+#define CSSON_BitNumber           0x13
+#define CR_CSSON_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4))
+
+/* --- CFGR Register ---*/
+
+/* Alias word address of USBPRE bit */
+#define CFGR_OFFSET               (RCC_OFFSET + 0x04)
+
+#ifndef STM32F10X_CL
+ #define USBPRE_BitNumber          0x16
+ #define CFGR_USBPRE_BB            (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4))
+#else
+ #define OTGFSPRE_BitNumber        0x16
+ #define CFGR_OTGFSPRE_BB          (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (OTGFSPRE_BitNumber * 4))
+#endif /* STM32F10X_CL */ 
+
+/* --- BDCR Register ---*/
+
+/* Alias word address of RTCEN bit */
+#define BDCR_OFFSET               (RCC_OFFSET + 0x20)
+#define RTCEN_BitNumber           0x0F
+#define BDCR_RTCEN_BB             (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4))
+
+/* Alias word address of BDRST bit */
+#define BDRST_BitNumber           0x10
+#define BDCR_BDRST_BB             (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4))
+
+/* --- CSR Register ---*/
+
+/* Alias word address of LSION bit */
+#define CSR_OFFSET                (RCC_OFFSET + 0x24)
+#define LSION_BitNumber           0x00
+#define CSR_LSION_BB              (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))
+
+#ifdef STM32F10X_CL
+/* --- CFGR2 Register ---*/
+
+ /* Alias word address of I2S2SRC bit */
+ #define CFGR2_OFFSET              (RCC_OFFSET + 0x2C)
+ #define I2S2SRC_BitNumber         0x11
+ #define CFGR2_I2S2SRC_BB          (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S2SRC_BitNumber * 4))
+
+ /* Alias word address of I2S3SRC bit */
+ #define I2S3SRC_BitNumber         0x12
+ #define CFGR2_I2S3SRC_BB          (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S3SRC_BitNumber * 4))
+#endif /* STM32F10X_CL */
+
+/* ---------------------- RCC registers bit mask ------------------------ */
+
+/* CR register bit mask */
+#define CR_HSEBYP_Reset           ((uint32_t)0xFFFBFFFF)
+#define CR_HSEBYP_Set             ((uint32_t)0x00040000)
+#define CR_HSEON_Reset            ((uint32_t)0xFFFEFFFF)
+#define CR_HSEON_Set              ((uint32_t)0x00010000)
+#define CR_HSITRIM_Mask           ((uint32_t)0xFFFFFF07)
+
+/* CFGR register bit mask */
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) 
+ #define CFGR_PLL_Mask            ((uint32_t)0xFFC2FFFF)
+#else
+ #define CFGR_PLL_Mask            ((uint32_t)0xFFC0FFFF)
+#endif /* STM32F10X_CL */ 
+
+#define CFGR_PLLMull_Mask         ((uint32_t)0x003C0000)
+#define CFGR_PLLSRC_Mask          ((uint32_t)0x00010000)
+#define CFGR_PLLXTPRE_Mask        ((uint32_t)0x00020000)
+#define CFGR_SWS_Mask             ((uint32_t)0x0000000C)
+#define CFGR_SW_Mask              ((uint32_t)0xFFFFFFFC)
+#define CFGR_HPRE_Reset_Mask      ((uint32_t)0xFFFFFF0F)
+#define CFGR_HPRE_Set_Mask        ((uint32_t)0x000000F0)
+#define CFGR_PPRE1_Reset_Mask     ((uint32_t)0xFFFFF8FF)
+#define CFGR_PPRE1_Set_Mask       ((uint32_t)0x00000700)
+#define CFGR_PPRE2_Reset_Mask     ((uint32_t)0xFFFFC7FF)
+#define CFGR_PPRE2_Set_Mask       ((uint32_t)0x00003800)
+#define CFGR_ADCPRE_Reset_Mask    ((uint32_t)0xFFFF3FFF)
+#define CFGR_ADCPRE_Set_Mask      ((uint32_t)0x0000C000)
+
+/* CSR register bit mask */
+#define CSR_RMVF_Set              ((uint32_t)0x01000000)
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) 
+/* CFGR2 register bit mask */
+ #define CFGR2_PREDIV1SRC         ((uint32_t)0x00010000)
+ #define CFGR2_PREDIV1            ((uint32_t)0x0000000F)
+#endif
+#ifdef STM32F10X_CL
+ #define CFGR2_PREDIV2            ((uint32_t)0x000000F0)
+ #define CFGR2_PLL2MUL            ((uint32_t)0x00000F00)
+ #define CFGR2_PLL3MUL            ((uint32_t)0x0000F000)
+#endif /* STM32F10X_CL */ 
+
+/* RCC Flag Mask */
+#define FLAG_Mask                 ((uint8_t)0x1F)
+
+/* CIR register byte 2 (Bits[15:8]) base address */
+#define CIR_BYTE2_ADDRESS         ((uint32_t)0x40021009)
+
+/* CIR register byte 3 (Bits[23:16]) base address */
+#define CIR_BYTE3_ADDRESS         ((uint32_t)0x4002100A)
+
+/* CFGR register byte 4 (Bits[31:24]) base address */
+#define CFGR_BYTE4_ADDRESS        ((uint32_t)0x40021007)
+
+/* BDCR register base address */
+#define BDCR_ADDRESS              (PERIPH_BASE + BDCR_OFFSET)
+
+/**
+  * @}
+  */ 
+
+/** @defgroup RCC_Private_Macros
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup RCC_Private_Variables
+  * @{
+  */ 
+
+static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
+static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup RCC_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Resets the RCC clock configuration to the default reset state.
+  * @param  None
+  * @retval None
+  */
+void RCC_DeInit(void)
+{
+  /* Set HSION bit */
+  RCC->CR |= (uint32_t)0x00000001;
+
+  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
+#ifndef STM32F10X_CL
+  RCC->CFGR &= (uint32_t)0xF8FF0000;
+#else
+  RCC->CFGR &= (uint32_t)0xF0FF0000;
+#endif /* STM32F10X_CL */   
+  
+  /* Reset HSEON, CSSON and PLLON bits */
+  RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+  /* Reset HSEBYP bit */
+  RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
+  RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+#ifdef STM32F10X_CL
+  /* Reset PLL2ON and PLL3ON bits */
+  RCC->CR &= (uint32_t)0xEBFFFFFF;
+
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x00FF0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;
+#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+
+  /* Reset CFGR2 register */
+  RCC->CFGR2 = 0x00000000;      
+#else
+  /* Disable all interrupts and clear pending bits  */
+  RCC->CIR = 0x009F0000;
+#endif /* STM32F10X_CL */
+
+}
+
+/**
+  * @brief  Configures the External High Speed oscillator (HSE).
+  * @note   HSE can not be stopped if it is used directly or through the PLL as system clock.
+  * @param  RCC_HSE: specifies the new state of the HSE.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_HSE_OFF: HSE oscillator OFF
+  *     @arg RCC_HSE_ON: HSE oscillator ON
+  *     @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock
+  * @retval None
+  */
+void RCC_HSEConfig(uint32_t RCC_HSE)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_HSE(RCC_HSE));
+  /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/
+  /* Reset HSEON bit */
+  RCC->CR &= CR_HSEON_Reset;
+  /* Reset HSEBYP bit */
+  RCC->CR &= CR_HSEBYP_Reset;
+  /* Configure HSE (RCC_HSE_OFF is already covered by the code section above) */
+  switch(RCC_HSE)
+  {
+    case RCC_HSE_ON:
+      /* Set HSEON bit */
+      RCC->CR |= CR_HSEON_Set;
+      break;
+      
+    case RCC_HSE_Bypass:
+      /* Set HSEBYP and HSEON bits */
+      RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set;
+      break;
+      
+    default:
+      break;
+  }
+}
+
+/**
+  * @brief  Waits for HSE start-up.
+  * @param  None
+  * @retval An ErrorStatus enumuration value:
+  * - SUCCESS: HSE oscillator is stable and ready to use
+  * - ERROR: HSE oscillator not yet ready
+  */
+ErrorStatus RCC_WaitForHSEStartUp(void)
+{
+  __IO uint32_t StartUpCounter = 0;
+  ErrorStatus status = ERROR;
+  FlagStatus HSEStatus = RESET;
+  
+  /* Wait till HSE is ready and if Time out is reached exit */
+  do
+  {
+    HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
+    StartUpCounter++;  
+  } while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET));
+  
+  if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
+  {
+    status = SUCCESS;
+  }
+  else
+  {
+    status = ERROR;
+  }  
+  return (status);
+}
+
+/**
+  * @brief  Adjusts the Internal High Speed oscillator (HSI) calibration value.
+  * @param  HSICalibrationValue: specifies the calibration trimming value.
+  *   This parameter must be a number between 0 and 0x1F.
+  * @retval None
+  */
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue));
+  tmpreg = RCC->CR;
+  /* Clear HSITRIM[4:0] bits */
+  tmpreg &= CR_HSITRIM_Mask;
+  /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */
+  tmpreg |= (uint32_t)HSICalibrationValue << 3;
+  /* Store the new value */
+  RCC->CR = tmpreg;
+}
+
+/**
+  * @brief  Enables or disables the Internal High Speed oscillator (HSI).
+  * @note   HSI can not be stopped if it is used directly or through the PLL as system clock.
+  * @param  NewState: new state of the HSI. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_HSICmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Configures the PLL clock source and multiplication factor.
+  * @note   This function must be used only when the PLL is disabled.
+  * @param  RCC_PLLSource: specifies the PLL entry clock source.
+  *   For @b STM32_Connectivity_line_devices or @b STM32_Value_line_devices, 
+  *   this parameter can be one of the following values:
+  *     @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry
+  *     @arg RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry
+  *   For @b other_STM32_devices, this parameter can be one of the following values:
+  *     @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry
+  *     @arg RCC_PLLSource_HSE_Div1: HSE oscillator clock selected as PLL clock entry
+  *     @arg RCC_PLLSource_HSE_Div2: HSE oscillator clock divided by 2 selected as PLL clock entry 
+  * @param  RCC_PLLMul: specifies the PLL multiplication factor.
+  *   For @b STM32_Connectivity_line_devices, this parameter can be RCC_PLLMul_x where x:{[4,9], 6_5}
+  *   For @b other_STM32_devices, this parameter can be RCC_PLLMul_x where x:[2,16]  
+  * @retval None
+  */
+void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
+{
+  uint32_t tmpreg = 0;
+
+  /* Check the parameters */
+  assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
+  assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
+
+  tmpreg = RCC->CFGR;
+  /* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
+  tmpreg &= CFGR_PLL_Mask;
+  /* Set the PLL configuration bits */
+  tmpreg |= RCC_PLLSource | RCC_PLLMul;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+/**
+  * @brief  Enables or disables the PLL.
+  * @note   The PLL can not be disabled if it is used as system clock.
+  * @param  NewState: new state of the PLL. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_PLLCmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState;
+}
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL)
+/**
+  * @brief  Configures the PREDIV1 division factor.
+  * @note 
+  *   - This function must be used only when the PLL is disabled.
+  *   - This function applies only to STM32 Connectivity line and Value line 
+  *     devices.
+  * @param  RCC_PREDIV1_Source: specifies the PREDIV1 clock source.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_PREDIV1_Source_HSE: HSE selected as PREDIV1 clock
+  *     @arg RCC_PREDIV1_Source_PLL2: PLL2 selected as PREDIV1 clock
+  * @note 
+  *   For @b STM32_Value_line_devices this parameter is always RCC_PREDIV1_Source_HSE  
+  * @param  RCC_PREDIV1_Div: specifies the PREDIV1 clock division factor.
+  *   This parameter can be RCC_PREDIV1_Divx where x:[1,16]
+  * @retval None
+  */
+void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div)
+{
+  uint32_t tmpreg = 0;
+  
+  /* Check the parameters */
+  assert_param(IS_RCC_PREDIV1_SOURCE(RCC_PREDIV1_Source));
+  assert_param(IS_RCC_PREDIV1(RCC_PREDIV1_Div));
+
+  tmpreg = RCC->CFGR2;
+  /* Clear PREDIV1[3:0] and PREDIV1SRC bits */
+  tmpreg &= ~(CFGR2_PREDIV1 | CFGR2_PREDIV1SRC);
+  /* Set the PREDIV1 clock source and division factor */
+  tmpreg |= RCC_PREDIV1_Source | RCC_PREDIV1_Div ;
+  /* Store the new value */
+  RCC->CFGR2 = tmpreg;
+}
+#endif
+
+#ifdef STM32F10X_CL
+/**
+  * @brief  Configures the PREDIV2 division factor.
+  * @note 
+  *   - This function must be used only when both PLL2 and PLL3 are disabled.
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_PREDIV2_Div: specifies the PREDIV2 clock division factor.
+  *   This parameter can be RCC_PREDIV2_Divx where x:[1,16]
+  * @retval None
+  */
+void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div)
+{
+  uint32_t tmpreg = 0;
+
+  /* Check the parameters */
+  assert_param(IS_RCC_PREDIV2(RCC_PREDIV2_Div));
+
+  tmpreg = RCC->CFGR2;
+  /* Clear PREDIV2[3:0] bits */
+  tmpreg &= ~CFGR2_PREDIV2;
+  /* Set the PREDIV2 division factor */
+  tmpreg |= RCC_PREDIV2_Div;
+  /* Store the new value */
+  RCC->CFGR2 = tmpreg;
+}
+
+/**
+  * @brief  Configures the PLL2 multiplication factor.
+  * @note
+  *   - This function must be used only when the PLL2 is disabled.
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_PLL2Mul: specifies the PLL2 multiplication factor.
+  *   This parameter can be RCC_PLL2Mul_x where x:{[8,14], 16, 20}
+  * @retval None
+  */
+void RCC_PLL2Config(uint32_t RCC_PLL2Mul)
+{
+  uint32_t tmpreg = 0;
+
+  /* Check the parameters */
+  assert_param(IS_RCC_PLL2_MUL(RCC_PLL2Mul));
+
+  tmpreg = RCC->CFGR2;
+  /* Clear PLL2Mul[3:0] bits */
+  tmpreg &= ~CFGR2_PLL2MUL;
+  /* Set the PLL2 configuration bits */
+  tmpreg |= RCC_PLL2Mul;
+  /* Store the new value */
+  RCC->CFGR2 = tmpreg;
+}
+
+
+/**
+  * @brief  Enables or disables the PLL2.
+  * @note 
+  *   - The PLL2 can not be disabled if it is used indirectly as system clock
+  *     (i.e. it is used as PLL clock entry that is used as System clock).
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  NewState: new state of the PLL2. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_PLL2Cmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  *(__IO uint32_t *) CR_PLL2ON_BB = (uint32_t)NewState;
+}
+
+
+/**
+  * @brief  Configures the PLL3 multiplication factor.
+  * @note 
+  *   - This function must be used only when the PLL3 is disabled.
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_PLL3Mul: specifies the PLL3 multiplication factor.
+  *   This parameter can be RCC_PLL3Mul_x where x:{[8,14], 16, 20}
+  * @retval None
+  */
+void RCC_PLL3Config(uint32_t RCC_PLL3Mul)
+{
+  uint32_t tmpreg = 0;
+
+  /* Check the parameters */
+  assert_param(IS_RCC_PLL3_MUL(RCC_PLL3Mul));
+
+  tmpreg = RCC->CFGR2;
+  /* Clear PLL3Mul[3:0] bits */
+  tmpreg &= ~CFGR2_PLL3MUL;
+  /* Set the PLL3 configuration bits */
+  tmpreg |= RCC_PLL3Mul;
+  /* Store the new value */
+  RCC->CFGR2 = tmpreg;
+}
+
+
+/**
+  * @brief  Enables or disables the PLL3.
+  * @note   This function applies only to STM32 Connectivity line devices.
+  * @param  NewState: new state of the PLL3. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_PLL3Cmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) CR_PLL3ON_BB = (uint32_t)NewState;
+}
+#endif /* STM32F10X_CL */
+
+/**
+  * @brief  Configures the system clock (SYSCLK).
+  * @param  RCC_SYSCLKSource: specifies the clock source used as system clock.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_SYSCLKSource_HSI: HSI selected as system clock
+  *     @arg RCC_SYSCLKSource_HSE: HSE selected as system clock
+  *     @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock
+  * @retval None
+  */
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));
+  tmpreg = RCC->CFGR;
+  /* Clear SW[1:0] bits */
+  tmpreg &= CFGR_SW_Mask;
+  /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
+  tmpreg |= RCC_SYSCLKSource;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+/**
+  * @brief  Returns the clock source used as system clock.
+  * @param  None
+  * @retval The clock source used as system clock. The returned value can
+  *   be one of the following:
+  *     - 0x00: HSI used as system clock
+  *     - 0x04: HSE used as system clock
+  *     - 0x08: PLL used as system clock
+  */
+uint8_t RCC_GetSYSCLKSource(void)
+{
+  return ((uint8_t)(RCC->CFGR & CFGR_SWS_Mask));
+}
+
+/**
+  * @brief  Configures the AHB clock (HCLK).
+  * @param  RCC_SYSCLK: defines the AHB clock divider. This clock is derived from 
+  *   the system clock (SYSCLK).
+  *   This parameter can be one of the following values:
+  *     @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
+  *     @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
+  *     @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
+  *     @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
+  *     @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
+  *     @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
+  *     @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
+  *     @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
+  *     @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
+  * @retval None
+  */
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_HCLK(RCC_SYSCLK));
+  tmpreg = RCC->CFGR;
+  /* Clear HPRE[3:0] bits */
+  tmpreg &= CFGR_HPRE_Reset_Mask;
+  /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
+  tmpreg |= RCC_SYSCLK;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+/**
+  * @brief  Configures the Low Speed APB clock (PCLK1).
+  * @param  RCC_HCLK: defines the APB1 clock divider. This clock is derived from 
+  *   the AHB clock (HCLK).
+  *   This parameter can be one of the following values:
+  *     @arg RCC_HCLK_Div1: APB1 clock = HCLK
+  *     @arg RCC_HCLK_Div2: APB1 clock = HCLK/2
+  *     @arg RCC_HCLK_Div4: APB1 clock = HCLK/4
+  *     @arg RCC_HCLK_Div8: APB1 clock = HCLK/8
+  *     @arg RCC_HCLK_Div16: APB1 clock = HCLK/16
+  * @retval None
+  */
+void RCC_PCLK1Config(uint32_t RCC_HCLK)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_PCLK(RCC_HCLK));
+  tmpreg = RCC->CFGR;
+  /* Clear PPRE1[2:0] bits */
+  tmpreg &= CFGR_PPRE1_Reset_Mask;
+  /* Set PPRE1[2:0] bits according to RCC_HCLK value */
+  tmpreg |= RCC_HCLK;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+/**
+  * @brief  Configures the High Speed APB clock (PCLK2).
+  * @param  RCC_HCLK: defines the APB2 clock divider. This clock is derived from 
+  *   the AHB clock (HCLK).
+  *   This parameter can be one of the following values:
+  *     @arg RCC_HCLK_Div1: APB2 clock = HCLK
+  *     @arg RCC_HCLK_Div2: APB2 clock = HCLK/2
+  *     @arg RCC_HCLK_Div4: APB2 clock = HCLK/4
+  *     @arg RCC_HCLK_Div8: APB2 clock = HCLK/8
+  *     @arg RCC_HCLK_Div16: APB2 clock = HCLK/16
+  * @retval None
+  */
+void RCC_PCLK2Config(uint32_t RCC_HCLK)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_PCLK(RCC_HCLK));
+  tmpreg = RCC->CFGR;
+  /* Clear PPRE2[2:0] bits */
+  tmpreg &= CFGR_PPRE2_Reset_Mask;
+  /* Set PPRE2[2:0] bits according to RCC_HCLK value */
+  tmpreg |= RCC_HCLK << 3;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+/**
+  * @brief  Enables or disables the specified RCC interrupts.
+  * @param  RCC_IT: specifies the RCC interrupt sources to be enabled or disabled.
+  * 
+  *   For @b STM32_Connectivity_line_devices, this parameter can be any combination
+  *   of the following values        
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *     @arg RCC_IT_PLL2RDY: PLL2 ready interrupt
+  *     @arg RCC_IT_PLL3RDY: PLL3 ready interrupt
+  * 
+  *   For @b other_STM32_devices, this parameter can be any combination of the 
+  *   following values        
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *       
+  * @param  NewState: new state of the specified RCC interrupts.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_IT(RCC_IT));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Perform Byte access to RCC_CIR bits to enable the selected interrupts */
+    *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT;
+  }
+  else
+  {
+    /* Perform Byte access to RCC_CIR bits to disable the selected interrupts */
+    *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT;
+  }
+}
+
+#ifndef STM32F10X_CL
+/**
+  * @brief  Configures the USB clock (USBCLK).
+  * @param  RCC_USBCLKSource: specifies the USB clock source. This clock is 
+  *   derived from the PLL output.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB 
+  *                                     clock source
+  *     @arg RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source
+  * @retval None
+  */
+void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_USBCLK_SOURCE(RCC_USBCLKSource));
+
+  *(__IO uint32_t *) CFGR_USBPRE_BB = RCC_USBCLKSource;
+}
+#else
+/**
+  * @brief  Configures the USB OTG FS clock (OTGFSCLK).
+  *   This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_OTGFSCLKSource: specifies the USB OTG FS clock source.
+  *   This clock is derived from the PLL output.
+  *   This parameter can be one of the following values:
+  *     @arg  RCC_OTGFSCLKSource_PLLVCO_Div3: PLL VCO clock divided by 2 selected as USB OTG FS clock source
+  *     @arg  RCC_OTGFSCLKSource_PLLVCO_Div2: PLL VCO clock divided by 2 selected as USB OTG FS clock source
+  * @retval None
+  */
+void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_OTGFSCLK_SOURCE(RCC_OTGFSCLKSource));
+
+  *(__IO uint32_t *) CFGR_OTGFSPRE_BB = RCC_OTGFSCLKSource;
+}
+#endif /* STM32F10X_CL */ 
+
+/**
+  * @brief  Configures the ADC clock (ADCCLK).
+  * @param  RCC_PCLK2: defines the ADC clock divider. This clock is derived from 
+  *   the APB2 clock (PCLK2).
+  *   This parameter can be one of the following values:
+  *     @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2
+  *     @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4
+  *     @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6
+  *     @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8
+  * @retval None
+  */
+void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
+{
+  uint32_t tmpreg = 0;
+  /* Check the parameters */
+  assert_param(IS_RCC_ADCCLK(RCC_PCLK2));
+  tmpreg = RCC->CFGR;
+  /* Clear ADCPRE[1:0] bits */
+  tmpreg &= CFGR_ADCPRE_Reset_Mask;
+  /* Set ADCPRE[1:0] bits according to RCC_PCLK2 value */
+  tmpreg |= RCC_PCLK2;
+  /* Store the new value */
+  RCC->CFGR = tmpreg;
+}
+
+#ifdef STM32F10X_CL
+/**
+  * @brief  Configures the I2S2 clock source(I2S2CLK).
+  * @note
+  *   - This function must be called before enabling I2S2 APB clock.
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_I2S2CLKSource: specifies the I2S2 clock source.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_I2S2CLKSource_SYSCLK: system clock selected as I2S2 clock entry
+  *     @arg RCC_I2S2CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S2 clock entry
+  * @retval None
+  */
+void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_I2S2CLK_SOURCE(RCC_I2S2CLKSource));
+
+  *(__IO uint32_t *) CFGR2_I2S2SRC_BB = RCC_I2S2CLKSource;
+}
+
+/**
+  * @brief  Configures the I2S3 clock source(I2S2CLK).
+  * @note
+  *   - This function must be called before enabling I2S3 APB clock.
+  *   - This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_I2S3CLKSource: specifies the I2S3 clock source.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_I2S3CLKSource_SYSCLK: system clock selected as I2S3 clock entry
+  *     @arg RCC_I2S3CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S3 clock entry
+  * @retval None
+  */
+void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_I2S3CLK_SOURCE(RCC_I2S3CLKSource));
+
+  *(__IO uint32_t *) CFGR2_I2S3SRC_BB = RCC_I2S3CLKSource;
+}
+#endif /* STM32F10X_CL */
+
+/**
+  * @brief  Configures the External Low Speed oscillator (LSE).
+  * @param  RCC_LSE: specifies the new state of the LSE.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_LSE_OFF: LSE oscillator OFF
+  *     @arg RCC_LSE_ON: LSE oscillator ON
+  *     @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock
+  * @retval None
+  */
+void RCC_LSEConfig(uint8_t RCC_LSE)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_LSE(RCC_LSE));
+  /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/
+  /* Reset LSEON bit */
+  *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
+  /* Reset LSEBYP bit */
+  *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
+  /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */
+  switch(RCC_LSE)
+  {
+    case RCC_LSE_ON:
+      /* Set LSEON bit */
+      *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON;
+      break;
+      
+    case RCC_LSE_Bypass:
+      /* Set LSEBYP and LSEON bits */
+      *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON;
+      break;            
+      
+    default:
+      break;      
+  }
+}
+
+/**
+  * @brief  Enables or disables the Internal Low Speed oscillator (LSI).
+  * @note   LSI can not be disabled if the IWDG is running.
+  * @param  NewState: new state of the LSI. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_LSICmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Configures the RTC clock (RTCCLK).
+  * @note   Once the RTC clock is selected it can't be changed unless the Backup domain is reset.
+  * @param  RCC_RTCCLKSource: specifies the RTC clock source.
+  *   This parameter can be one of the following values:
+  *     @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock
+  *     @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock
+  *     @arg RCC_RTCCLKSource_HSE_Div128: HSE clock divided by 128 selected as RTC clock
+  * @retval None
+  */
+void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource));
+  /* Select the RTC clock source */
+  RCC->BDCR |= RCC_RTCCLKSource;
+}
+
+/**
+  * @brief  Enables or disables the RTC clock.
+  * @note   This function must be used only after the RTC clock was selected using the RCC_RTCCLKConfig function.
+  * @param  NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_RTCCLKCmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Returns the frequencies of different on chip clocks.
+  * @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
+  *         the clocks frequencies.
+  * @note   The result of this function could be not correct when using 
+  *         fractional value for HSE crystal.  
+  * @retval None
+  */
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
+{
+  uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
+
+#ifdef  STM32F10X_CL
+  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
+#endif /* STM32F10X_CL */
+
+#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+  uint32_t prediv1factor = 0;
+#endif
+    
+  /* Get SYSCLK source -------------------------------------------------------*/
+  tmp = RCC->CFGR & CFGR_SWS_Mask;
+  
+  switch (tmp)
+  {
+    case 0x00:  /* HSI used as system clock */
+      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+      break;
+    case 0x04:  /* HSE used as system clock */
+      RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
+      break;
+    case 0x08:  /* PLL used as system clock */
+
+      /* Get PLL clock source and multiplication factor ----------------------*/
+      pllmull = RCC->CFGR & CFGR_PLLMull_Mask;
+      pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;
+      
+#ifndef STM32F10X_CL      
+      pllmull = ( pllmull >> 18) + 2;
+      
+      if (pllsource == 0x00)
+      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {
+ #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
+       prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
+       /* HSE oscillator clock selected as PREDIV1 clock entry */
+       RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull; 
+ #else
+        /* HSE selected as PLL clock entry */
+        if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
+        {/* HSE oscillator clock divided by 2 */
+          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
+        }
+        else
+        {
+          RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
+        }
+ #endif
+      }
+#else
+      pllmull = pllmull >> 18;
+      
+      if (pllmull != 0x0D)
+      {
+         pllmull += 2;
+      }
+      else
+      { /* PLL multiplication factor = PLL input clock * 6.5 */
+        pllmull = 13 / 2; 
+      }
+            
+      if (pllsource == 0x00)
+      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
+        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
+      }
+      else
+      {/* PREDIV1 selected as PLL clock entry */
+        
+        /* Get PREDIV1 clock source and division factor */
+        prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;
+        prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
+        
+        if (prediv1source == 0)
+        { /* HSE oscillator clock selected as PREDIV1 clock entry */
+          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;          
+        }
+        else
+        {/* PLL2 clock selected as PREDIV1 clock entry */
+          
+          /* Get PREDIV2 division factor and PLL2 multiplication factor */
+          prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;
+          pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; 
+          RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         
+        }
+      }
+#endif /* STM32F10X_CL */ 
+      break;
+
+    default:
+      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+      break;
+  }
+
+  /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
+  /* Get HCLK prescaler */
+  tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
+  tmp = tmp >> 4;
+  presc = APBAHBPrescTable[tmp];
+  /* HCLK clock frequency */
+  RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
+  /* Get PCLK1 prescaler */
+  tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
+  tmp = tmp >> 8;
+  presc = APBAHBPrescTable[tmp];
+  /* PCLK1 clock frequency */
+  RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+  /* Get PCLK2 prescaler */
+  tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
+  tmp = tmp >> 11;
+  presc = APBAHBPrescTable[tmp];
+  /* PCLK2 clock frequency */
+  RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+  /* Get ADCCLK prescaler */
+  tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
+  tmp = tmp >> 14;
+  presc = ADCPrescTable[tmp];
+  /* ADCCLK clock frequency */
+  RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
+}
+
+/**
+  * @brief  Enables or disables the AHB peripheral clock.
+  * @param  RCC_AHBPeriph: specifies the AHB peripheral to gates its clock.
+  *   
+  *   For @b STM32_Connectivity_line_devices, this parameter can be any combination
+  *   of the following values:        
+  *     @arg RCC_AHBPeriph_DMA1
+  *     @arg RCC_AHBPeriph_DMA2
+  *     @arg RCC_AHBPeriph_SRAM
+  *     @arg RCC_AHBPeriph_FLITF
+  *     @arg RCC_AHBPeriph_CRC
+  *     @arg RCC_AHBPeriph_OTG_FS    
+  *     @arg RCC_AHBPeriph_ETH_MAC   
+  *     @arg RCC_AHBPeriph_ETH_MAC_Tx
+  *     @arg RCC_AHBPeriph_ETH_MAC_Rx
+  * 
+  *   For @b other_STM32_devices, this parameter can be any combination of the 
+  *   following values:        
+  *     @arg RCC_AHBPeriph_DMA1
+  *     @arg RCC_AHBPeriph_DMA2
+  *     @arg RCC_AHBPeriph_SRAM
+  *     @arg RCC_AHBPeriph_FLITF
+  *     @arg RCC_AHBPeriph_CRC
+  *     @arg RCC_AHBPeriph_FSMC
+  *     @arg RCC_AHBPeriph_SDIO
+  *   
+  * @note SRAM and FLITF clock can be disabled only during sleep mode.
+  * @param  NewState: new state of the specified peripheral clock.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  if (NewState != DISABLE)
+  {
+    RCC->AHBENR |= RCC_AHBPeriph;
+  }
+  else
+  {
+    RCC->AHBENR &= ~RCC_AHBPeriph;
+  }
+}
+
+/**
+  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.
+  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
+  *   This parameter can be any combination of the following values:
+  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
+  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
+  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
+  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
+  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
+  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
+  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     
+  * @param  NewState: new state of the specified peripheral clock.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    RCC->APB2ENR |= RCC_APB2Periph;
+  }
+  else
+  {
+    RCC->APB2ENR &= ~RCC_APB2Periph;
+  }
+}
+
+/**
+  * @brief  Enables or disables the Low Speed APB (APB1) peripheral clock.
+  * @param  RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
+  *   This parameter can be any combination of the following values:
+  *     @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
+  *          RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
+  *          RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3,
+  *          RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, 
+  *          RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2,
+  *          RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP,
+  *          RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
+  *          RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14
+  * @param  NewState: new state of the specified peripheral clock.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    RCC->APB1ENR |= RCC_APB1Periph;
+  }
+  else
+  {
+    RCC->APB1ENR &= ~RCC_APB1Periph;
+  }
+}
+
+#ifdef STM32F10X_CL
+/**
+  * @brief  Forces or releases AHB peripheral reset.
+  * @note   This function applies only to STM32 Connectivity line devices.
+  * @param  RCC_AHBPeriph: specifies the AHB peripheral to reset.
+  *   This parameter can be any combination of the following values:
+  *     @arg RCC_AHBPeriph_OTG_FS 
+  *     @arg RCC_AHBPeriph_ETH_MAC
+  * @param  NewState: new state of the specified peripheral reset.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_AHB_PERIPH_RESET(RCC_AHBPeriph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+  if (NewState != DISABLE)
+  {
+    RCC->AHBRSTR |= RCC_AHBPeriph;
+  }
+  else
+  {
+    RCC->AHBRSTR &= ~RCC_AHBPeriph;
+  }
+}
+#endif /* STM32F10X_CL */ 
+
+/**
+  * @brief  Forces or releases High Speed APB (APB2) peripheral reset.
+  * @param  RCC_APB2Periph: specifies the APB2 peripheral to reset.
+  *   This parameter can be any combination of the following values:
+  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
+  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
+  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
+  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
+  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
+  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
+  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11  
+  * @param  NewState: new state of the specified peripheral reset.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    RCC->APB2RSTR |= RCC_APB2Periph;
+  }
+  else
+  {
+    RCC->APB2RSTR &= ~RCC_APB2Periph;
+  }
+}
+
+/**
+  * @brief  Forces or releases Low Speed APB (APB1) peripheral reset.
+  * @param  RCC_APB1Periph: specifies the APB1 peripheral to reset.
+  *   This parameter can be any combination of the following values:
+  *     @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
+  *          RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
+  *          RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3,
+  *          RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, 
+  *          RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2,
+  *          RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP,
+  *          RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
+  *          RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14  
+  * @param  NewState: new state of the specified peripheral clock.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    RCC->APB1RSTR |= RCC_APB1Periph;
+  }
+  else
+  {
+    RCC->APB1RSTR &= ~RCC_APB1Periph;
+  }
+}
+
+/**
+  * @brief  Forces or releases the Backup domain reset.
+  * @param  NewState: new state of the Backup domain reset.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_BackupResetCmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Enables or disables the Clock Security System.
+  * @param  NewState: new state of the Clock Security System..
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState;
+}
+
+/**
+  * @brief  Selects the clock source to output on MCO pin.
+  * @param  RCC_MCO: specifies the clock source to output.
+  *   
+  *   For @b STM32_Connectivity_line_devices, this parameter can be one of the
+  *   following values:       
+  *     @arg RCC_MCO_NoClock: No clock selected
+  *     @arg RCC_MCO_SYSCLK: System clock selected
+  *     @arg RCC_MCO_HSI: HSI oscillator clock selected
+  *     @arg RCC_MCO_HSE: HSE oscillator clock selected
+  *     @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected
+  *     @arg RCC_MCO_PLL2CLK: PLL2 clock selected                     
+  *     @arg RCC_MCO_PLL3CLK_Div2: PLL3 clock divided by 2 selected   
+  *     @arg RCC_MCO_XT1: External 3-25 MHz oscillator clock selected  
+  *     @arg RCC_MCO_PLL3CLK: PLL3 clock selected 
+  * 
+  *   For  @b other_STM32_devices, this parameter can be one of the following values:        
+  *     @arg RCC_MCO_NoClock: No clock selected
+  *     @arg RCC_MCO_SYSCLK: System clock selected
+  *     @arg RCC_MCO_HSI: HSI oscillator clock selected
+  *     @arg RCC_MCO_HSE: HSE oscillator clock selected
+  *     @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected
+  *   
+  * @retval None
+  */
+void RCC_MCOConfig(uint8_t RCC_MCO)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_MCO(RCC_MCO));
+
+  /* Perform Byte access to MCO bits to select the MCO source */
+  *(__IO uint8_t *) CFGR_BYTE4_ADDRESS = RCC_MCO;
+}
+
+/**
+  * @brief  Checks whether the specified RCC flag is set or not.
+  * @param  RCC_FLAG: specifies the flag to check.
+  *   
+  *   For @b STM32_Connectivity_line_devices, this parameter can be one of the
+  *   following values:
+  *     @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
+  *     @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
+  *     @arg RCC_FLAG_PLLRDY: PLL clock ready
+  *     @arg RCC_FLAG_PLL2RDY: PLL2 clock ready      
+  *     @arg RCC_FLAG_PLL3RDY: PLL3 clock ready                           
+  *     @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
+  *     @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
+  *     @arg RCC_FLAG_PINRST: Pin reset
+  *     @arg RCC_FLAG_PORRST: POR/PDR reset
+  *     @arg RCC_FLAG_SFTRST: Software reset
+  *     @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
+  *     @arg RCC_FLAG_WWDGRST: Window Watchdog reset
+  *     @arg RCC_FLAG_LPWRRST: Low Power reset
+  * 
+  *   For @b other_STM32_devices, this parameter can be one of the following values:        
+  *     @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
+  *     @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
+  *     @arg RCC_FLAG_PLLRDY: PLL clock ready
+  *     @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
+  *     @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
+  *     @arg RCC_FLAG_PINRST: Pin reset
+  *     @arg RCC_FLAG_PORRST: POR/PDR reset
+  *     @arg RCC_FLAG_SFTRST: Software reset
+  *     @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
+  *     @arg RCC_FLAG_WWDGRST: Window Watchdog reset
+  *     @arg RCC_FLAG_LPWRRST: Low Power reset
+  *   
+  * @retval The new state of RCC_FLAG (SET or RESET).
+  */
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
+{
+  uint32_t tmp = 0;
+  uint32_t statusreg = 0;
+  FlagStatus bitstatus = RESET;
+  /* Check the parameters */
+  assert_param(IS_RCC_FLAG(RCC_FLAG));
+
+  /* Get the RCC register index */
+  tmp = RCC_FLAG >> 5;
+  if (tmp == 1)               /* The flag to check is in CR register */
+  {
+    statusreg = RCC->CR;
+  }
+  else if (tmp == 2)          /* The flag to check is in BDCR register */
+  {
+    statusreg = RCC->BDCR;
+  }
+  else                       /* The flag to check is in CSR register */
+  {
+    statusreg = RCC->CSR;
+  }
+
+  /* Get the flag position */
+  tmp = RCC_FLAG & FLAG_Mask;
+  if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+
+  /* Return the flag status */
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the RCC reset flags.
+  * @note   The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST,
+  *   RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST
+  * @param  None
+  * @retval None
+  */
+void RCC_ClearFlag(void)
+{
+  /* Set RMVF bit to clear the reset flags */
+  RCC->CSR |= CSR_RMVF_Set;
+}
+
+/**
+  * @brief  Checks whether the specified RCC interrupt has occurred or not.
+  * @param  RCC_IT: specifies the RCC interrupt source to check.
+  *   
+  *   For @b STM32_Connectivity_line_devices, this parameter can be one of the
+  *   following values:
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *     @arg RCC_IT_PLL2RDY: PLL2 ready interrupt 
+  *     @arg RCC_IT_PLL3RDY: PLL3 ready interrupt                      
+  *     @arg RCC_IT_CSS: Clock Security System interrupt
+  * 
+  *   For @b other_STM32_devices, this parameter can be one of the following values:        
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *     @arg RCC_IT_CSS: Clock Security System interrupt
+  *   
+  * @retval The new state of RCC_IT (SET or RESET).
+  */
+ITStatus RCC_GetITStatus(uint8_t RCC_IT)
+{
+  ITStatus bitstatus = RESET;
+  /* Check the parameters */
+  assert_param(IS_RCC_GET_IT(RCC_IT));
+
+  /* Check the status of the specified RCC interrupt */
+  if ((RCC->CIR & RCC_IT) != (uint32_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+
+  /* Return the RCC_IT status */
+  return  bitstatus;
+}
+
+/**
+  * @brief  Clears the RCC's interrupt pending bits.
+  * @param  RCC_IT: specifies the interrupt pending bit to clear.
+  *   
+  *   For @b STM32_Connectivity_line_devices, this parameter can be any combination
+  *   of the following values:
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *     @arg RCC_IT_PLL2RDY: PLL2 ready interrupt 
+  *     @arg RCC_IT_PLL3RDY: PLL3 ready interrupt                      
+  *     @arg RCC_IT_CSS: Clock Security System interrupt
+  * 
+  *   For @b other_STM32_devices, this parameter can be any combination of the
+  *   following values:        
+  *     @arg RCC_IT_LSIRDY: LSI ready interrupt
+  *     @arg RCC_IT_LSERDY: LSE ready interrupt
+  *     @arg RCC_IT_HSIRDY: HSI ready interrupt
+  *     @arg RCC_IT_HSERDY: HSE ready interrupt
+  *     @arg RCC_IT_PLLRDY: PLL ready interrupt
+  *   
+  *     @arg RCC_IT_CSS: Clock Security System interrupt
+  * @retval None
+  */
+void RCC_ClearITPendingBit(uint8_t RCC_IT)
+{
+  /* Check the parameters */
+  assert_param(IS_RCC_CLEAR_IT(RCC_IT));
+
+  /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt
+     pending bits */
+  *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_tim.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2890 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_tim.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the TIM firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_tim.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup TIM 
+  * @brief TIM driver modules
+  * @{
+  */
+
+/** @defgroup TIM_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Defines
+  * @{
+  */
+
+/* ---------------------- TIM registers bit mask ------------------------ */
+#define SMCR_ETR_Mask               ((uint16_t)0x00FF) 
+#define CCMR_Offset                 ((uint16_t)0x0018)
+#define CCER_CCE_Set                ((uint16_t)0x0001)  
+#define	CCER_CCNE_Set               ((uint16_t)0x0004) 
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_FunctionPrototypes
+  * @{
+  */
+
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter);
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter);
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter);
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter);
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup TIM_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Deinitializes the TIMx peripheral registers to their default reset values.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @retval None
+  */
+void TIM_DeInit(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx)); 
+ 
+  if (TIMx == TIM1)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);  
+  }     
+  else if (TIMx == TIM2)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE);
+  }
+  else if (TIMx == TIM3)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE);
+  }
+  else if (TIMx == TIM4)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE);
+  } 
+  else if (TIMx == TIM5)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE);
+  } 
+  else if (TIMx == TIM6)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE);
+  } 
+  else if (TIMx == TIM7)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE);
+  } 
+  else if (TIMx == TIM8)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE);
+  }
+  else if (TIMx == TIM9)
+  {      
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE);  
+   }  
+  else if (TIMx == TIM10)
+  {      
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE);  
+  }  
+  else if (TIMx == TIM11) 
+  {     
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE);  
+  }  
+  else if (TIMx == TIM12)
+  {      
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE);  
+  }  
+  else if (TIMx == TIM13) 
+  {       
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE);  
+  }
+  else if (TIMx == TIM14) 
+  {       
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE);  
+  }        
+  else if (TIMx == TIM15)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, DISABLE);
+  } 
+  else if (TIMx == TIM16)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, DISABLE);
+  } 
+  else
+  {
+    if (TIMx == TIM17)
+    {
+      RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, ENABLE);
+      RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, DISABLE);
+    }  
+  }
+}
+
+/**
+  * @brief  Initializes the TIMx Time Base Unit peripheral according to 
+  *         the specified parameters in the TIM_TimeBaseInitStruct.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef
+  *         structure that contains the configuration information for the 
+  *         specified TIM peripheral.
+  * @retval None
+  */
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+  uint16_t tmpcr1 = 0;
+
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx)); 
+  assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
+  assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
+
+  tmpcr1 = TIMx->CR1;  
+
+  if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
+     (TIMx == TIM4) || (TIMx == TIM5)) 
+  {
+    /* Select the Counter Mode */
+    tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+    tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
+  }
+ 
+  if((TIMx != TIM6) && (TIMx != TIM7))
+  {
+    /* Set the clock division */
+    tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
+    tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
+  }
+
+  TIMx->CR1 = tmpcr1;
+
+  /* Set the Autoreload value */
+  TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
+ 
+  /* Set the Prescaler value */
+  TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
+    
+  if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))  
+  {
+    /* Set the Repetition Counter value */
+    TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
+  }
+
+  /* Generate an update event to reload the Prescaler and the Repetition counter
+     values immediately */
+  TIMx->EGR = TIM_PSCReloadMode_Immediate;           
+}
+
+/**
+  * @brief  Initializes the TIMx Channel1 according to the specified
+  *         parameters in the TIM_OCInitStruct.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+  uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+   
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+  assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));   
+ /* Disable the Channel 1: Reset the CC1E Bit */
+  TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E);
+  /* Get the TIMx CCER register value */
+  tmpccer = TIMx->CCER;
+  /* Get the TIMx CR2 register value */
+  tmpcr2 =  TIMx->CR2;
+  
+  /* Get the TIMx CCMR1 register value */
+  tmpccmrx = TIMx->CCMR1;
+    
+  /* Reset the Output Compare Mode Bits */
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M));
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S));
+
+  /* Select the Output Compare Mode */
+  tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+  
+  /* Reset the Output Polarity level */
+  tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P));
+  /* Set the Output Compare Polarity */
+  tmpccer |= TIM_OCInitStruct->TIM_OCPolarity;
+  
+  /* Set the Output State */
+  tmpccer |= TIM_OCInitStruct->TIM_OutputState;
+    
+  if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)||
+     (TIMx == TIM16)|| (TIMx == TIM17))
+  {
+    assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+    assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+    assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+    assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+    
+    /* Reset the Output N Polarity level */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NP));
+    /* Set the Output N Polarity */
+    tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity;
+    
+    /* Reset the Output N State */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NE));    
+    /* Set the Output N State */
+    tmpccer |= TIM_OCInitStruct->TIM_OutputNState;
+    
+    /* Reset the Output Compare and Output Compare N IDLE State */
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1));
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1N));
+    
+    /* Set the Output Idle state */
+    tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState;
+    /* Set the Output N Idle state */
+    tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState;
+  }
+  /* Write to TIMx CR2 */
+  TIMx->CR2 = tmpcr2;
+  
+  /* Write to TIMx CCMR1 */
+  TIMx->CCMR1 = tmpccmrx;
+
+  /* Set the Capture Compare Register value */
+  TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; 
+ 
+  /* Write to TIMx CCER */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Initializes the TIMx Channel2 according to the specified
+  *         parameters in the TIM_OCInitStruct.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select 
+  *         the TIM peripheral.
+  * @param  TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+  uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+   
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx)); 
+  assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+  assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));   
+   /* Disable the Channel 2: Reset the CC2E Bit */
+  TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E));
+  
+  /* Get the TIMx CCER register value */  
+  tmpccer = TIMx->CCER;
+  /* Get the TIMx CR2 register value */
+  tmpcr2 =  TIMx->CR2;
+  
+  /* Get the TIMx CCMR1 register value */
+  tmpccmrx = TIMx->CCMR1;
+    
+  /* Reset the Output Compare mode and Capture/Compare selection Bits */
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M));
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S));
+  
+  /* Select the Output Compare Mode */
+  tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+  
+  /* Reset the Output Polarity level */
+  tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P));
+  /* Set the Output Compare Polarity */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4);
+  
+  /* Set the Output State */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4);
+    
+  if((TIMx == TIM1) || (TIMx == TIM8))
+  {
+    assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+    assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+    assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+    assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+    
+    /* Reset the Output N Polarity level */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NP));
+    /* Set the Output N Polarity */
+    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4);
+    
+    /* Reset the Output N State */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NE));    
+    /* Set the Output N State */
+    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4);
+    
+    /* Reset the Output Compare and Output Compare N IDLE State */
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2));
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2N));
+    
+    /* Set the Output Idle state */
+    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2);
+    /* Set the Output N Idle state */
+    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2);
+  }
+  /* Write to TIMx CR2 */
+  TIMx->CR2 = tmpcr2;
+  
+  /* Write to TIMx CCMR1 */
+  TIMx->CCMR1 = tmpccmrx;
+
+  /* Set the Capture Compare Register value */
+  TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse;
+  
+  /* Write to TIMx CCER */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Initializes the TIMx Channel3 according to the specified
+  *         parameters in the TIM_OCInitStruct.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+  uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+   
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx)); 
+  assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+  assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));   
+  /* Disable the Channel 2: Reset the CC2E Bit */
+  TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E));
+  
+  /* Get the TIMx CCER register value */
+  tmpccer = TIMx->CCER;
+  /* Get the TIMx CR2 register value */
+  tmpcr2 =  TIMx->CR2;
+  
+  /* Get the TIMx CCMR2 register value */
+  tmpccmrx = TIMx->CCMR2;
+    
+  /* Reset the Output Compare mode and Capture/Compare selection Bits */
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M));
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC3S));  
+  /* Select the Output Compare Mode */
+  tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+  
+  /* Reset the Output Polarity level */
+  tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P));
+  /* Set the Output Compare Polarity */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8);
+  
+  /* Set the Output State */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8);
+    
+  if((TIMx == TIM1) || (TIMx == TIM8))
+  {
+    assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+    assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+    assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+    assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+    
+    /* Reset the Output N Polarity level */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NP));
+    /* Set the Output N Polarity */
+    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8);
+    /* Reset the Output N State */
+    tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NE));
+    
+    /* Set the Output N State */
+    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8);
+    /* Reset the Output Compare and Output Compare N IDLE State */
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3));
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3N));
+    /* Set the Output Idle state */
+    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4);
+    /* Set the Output N Idle state */
+    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4);
+  }
+  /* Write to TIMx CR2 */
+  TIMx->CR2 = tmpcr2;
+  
+  /* Write to TIMx CCMR2 */
+  TIMx->CCMR2 = tmpccmrx;
+
+  /* Set the Capture Compare Register value */
+  TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
+  
+  /* Write to TIMx CCER */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Initializes the TIMx Channel4 according to the specified
+  *         parameters in the TIM_OCInitStruct.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+  uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+   
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx)); 
+  assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+  assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));   
+  /* Disable the Channel 2: Reset the CC4E Bit */
+  TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E));
+  
+  /* Get the TIMx CCER register value */
+  tmpccer = TIMx->CCER;
+  /* Get the TIMx CR2 register value */
+  tmpcr2 =  TIMx->CR2;
+  
+  /* Get the TIMx CCMR2 register value */
+  tmpccmrx = TIMx->CCMR2;
+    
+  /* Reset the Output Compare mode and Capture/Compare selection Bits */
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M));
+  tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC4S));
+  
+  /* Select the Output Compare Mode */
+  tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+  
+  /* Reset the Output Polarity level */
+  tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P));
+  /* Set the Output Compare Polarity */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12);
+  
+  /* Set the Output State */
+  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12);
+    
+  if((TIMx == TIM1) || (TIMx == TIM8))
+  {
+    assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+    /* Reset the Output Compare IDLE State */
+    tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS4));
+    /* Set the Output Idle state */
+    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6);
+  }
+  /* Write to TIMx CR2 */
+  TIMx->CR2 = tmpcr2;
+  
+  /* Write to TIMx CCMR2 */  
+  TIMx->CCMR2 = tmpccmrx;
+
+  /* Set the Capture Compare Register value */
+  TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse;
+  
+  /* Write to TIMx CCER */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Initializes the TIM peripheral according to the specified
+  *         parameters in the TIM_ICInitStruct.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel));  
+  assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection));
+  assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler));
+  assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter));
+  
+  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+     (TIMx == TIM4) ||(TIMx == TIM5))
+  {
+    assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity));
+  }
+  else
+  {
+    assert_param(IS_TIM_IC_POLARITY_LITE(TIM_ICInitStruct->TIM_ICPolarity));
+  }
+  if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+  {
+    assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+    /* TI1 Configuration */
+    TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+               TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+  else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2)
+  {
+    assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+    /* TI2 Configuration */
+    TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+               TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+  else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3)
+  {
+    assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+    /* TI3 Configuration */
+    TI3_Config(TIMx,  TIM_ICInitStruct->TIM_ICPolarity,
+               TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+  else
+  {
+    assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+    /* TI4 Configuration */
+    TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+               TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+}
+
+/**
+  * @brief  Configures the TIM peripheral according to the specified
+  *         parameters in the TIM_ICInitStruct to measure an external PWM signal.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
+  *         that contains the configuration information for the specified TIM peripheral.
+  * @retval None
+  */
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+  uint16_t icoppositepolarity = TIM_ICPolarity_Rising;
+  uint16_t icoppositeselection = TIM_ICSelection_DirectTI;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  /* Select the Opposite Input Polarity */
+  if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising)
+  {
+    icoppositepolarity = TIM_ICPolarity_Falling;
+  }
+  else
+  {
+    icoppositepolarity = TIM_ICPolarity_Rising;
+  }
+  /* Select the Opposite Input */
+  if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI)
+  {
+    icoppositeselection = TIM_ICSelection_IndirectTI;
+  }
+  else
+  {
+    icoppositeselection = TIM_ICSelection_DirectTI;
+  }
+  if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+  {
+    /* TI1 Configuration */
+    TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+    /* TI2 Configuration */
+    TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+  else
+  { 
+    /* TI2 Configuration */
+    TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+               TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+    /* TI1 Configuration */
+    TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+    /* Set the Input Capture Prescaler value */
+    TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+  }
+}
+
+/**
+  * @brief  Configures the: Break feature, dead time, Lock level, the OSSI,
+  *         the OSSR State and the AOE(automatic output enable).
+  * @param  TIMx: where x can be  1 or 8 to select the TIM 
+  * @param  TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that
+  *         contains the BDTR Register configuration  information for the TIM peripheral.
+  * @retval None
+  */
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+  assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState));
+  assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState));
+  assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel));
+  assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break));
+  assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity));
+  assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput));
+  /* Set the Lock level, the Break enable Bit and the Ploarity, the OSSR State,
+     the OSSI State, the dead time value and the Automatic Output Enable Bit */
+  TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState |
+             TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime |
+             TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity |
+             TIM_BDTRInitStruct->TIM_AutomaticOutput;
+}
+
+/**
+  * @brief  Fills each TIM_TimeBaseInitStruct member with its default value.
+  * @param  TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef
+  *         structure which will be initialized.
+  * @retval None
+  */
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+  /* Set the default configuration */
+  TIM_TimeBaseInitStruct->TIM_Period = 0xFFFF;
+  TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000;
+  TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
+  TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000;
+}
+
+/**
+  * @brief  Fills each TIM_OCInitStruct member with its default value.
+  * @param  TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will
+  *         be initialized.
+  * @retval None
+  */
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+  /* Set the default configuration */
+  TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing;
+  TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable;
+  TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable;
+  TIM_OCInitStruct->TIM_Pulse = 0x0000;
+  TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High;
+  TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High;
+  TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset;
+  TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset;
+}
+
+/**
+  * @brief  Fills each TIM_ICInitStruct member with its default value.
+  * @param  TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will
+  *         be initialized.
+  * @retval None
+  */
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+  /* Set the default configuration */
+  TIM_ICInitStruct->TIM_Channel = TIM_Channel_1;
+  TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising;
+  TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI;
+  TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1;
+  TIM_ICInitStruct->TIM_ICFilter = 0x00;
+}
+
+/**
+  * @brief  Fills each TIM_BDTRInitStruct member with its default value.
+  * @param  TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which
+  *         will be initialized.
+  * @retval None
+  */
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct)
+{
+  /* Set the default configuration */
+  TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable;
+  TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable;
+  TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF;
+  TIM_BDTRInitStruct->TIM_DeadTime = 0x00;
+  TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable;
+  TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low;
+  TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
+}
+
+/**
+  * @brief  Enables or disables the specified TIM peripheral.
+  * @param  TIMx: where x can be 1 to 17 to select the TIMx peripheral.
+  * @param  NewState: new state of the TIMx peripheral.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the TIM Counter */
+    TIMx->CR1 |= TIM_CR1_CEN;
+  }
+  else
+  {
+    /* Disable the TIM Counter */
+    TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));
+  }
+}
+
+/**
+  * @brief  Enables or disables the TIM peripheral Main Outputs.
+  * @param  TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral.
+  * @param  NewState: new state of the TIM peripheral Main Outputs.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Enable the TIM Main Output */
+    TIMx->BDTR |= TIM_BDTR_MOE;
+  }
+  else
+  {
+    /* Disable the TIM Main Output */
+    TIMx->BDTR &= (uint16_t)(~((uint16_t)TIM_BDTR_MOE));
+  }  
+}
+
+/**
+  * @brief  Enables or disables the specified TIM interrupts.
+  * @param  TIMx: where x can be 1 to 17 to select the TIMx peripheral.
+  * @param  TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
+  *   This parameter can be any combination of the following values:
+  *     @arg TIM_IT_Update: TIM update Interrupt source
+  *     @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+  *     @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+  *     @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+  *     @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+  *     @arg TIM_IT_COM: TIM Commutation Interrupt source
+  *     @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+  *     @arg TIM_IT_Break: TIM Break Interrupt source
+  * @note 
+  *   - TIM6 and TIM7 can only generate an update interrupt.
+  *   - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+  *      TIM_IT_CC2 or TIM_IT_Trigger. 
+  *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.   
+  *   - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. 
+  *   - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.    
+  * @param  NewState: new state of the TIM interrupts.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
+{  
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_IT(TIM_IT));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the Interrupt sources */
+    TIMx->DIER |= TIM_IT;
+  }
+  else
+  {
+    /* Disable the Interrupt sources */
+    TIMx->DIER &= (uint16_t)~TIM_IT;
+  }
+}
+
+/**
+  * @brief  Configures the TIMx event to be generate by software.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_EventSource: specifies the event source.
+  *   This parameter can be one or more of the following values:	   
+  *     @arg TIM_EventSource_Update: Timer update Event source
+  *     @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source
+  *     @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source
+  *     @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source
+  *     @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source
+  *     @arg TIM_EventSource_COM: Timer COM event source  
+  *     @arg TIM_EventSource_Trigger: Timer Trigger Event source
+  *     @arg TIM_EventSource_Break: Timer Break event source
+  * @note 
+  *   - TIM6 and TIM7 can only generate an update event. 
+  *   - TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8.      
+  * @retval None
+  */
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource)
+{ 
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource));
+  
+  /* Set the event sources */
+  TIMx->EGR = TIM_EventSource;
+}
+
+/**
+  * @brief  Configures the TIMx's DMA interface.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 15, 16 or 17 to select 
+  *   the TIM peripheral.
+  * @param  TIM_DMABase: DMA Base address.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_DMABase_CR, TIM_DMABase_CR2, TIM_DMABase_SMCR,
+  *          TIM_DMABase_DIER, TIM1_DMABase_SR, TIM_DMABase_EGR,
+  *          TIM_DMABase_CCMR1, TIM_DMABase_CCMR2, TIM_DMABase_CCER,
+  *          TIM_DMABase_CNT, TIM_DMABase_PSC, TIM_DMABase_ARR,
+  *          TIM_DMABase_RCR, TIM_DMABase_CCR1, TIM_DMABase_CCR2,
+  *          TIM_DMABase_CCR3, TIM_DMABase_CCR4, TIM_DMABase_BDTR,
+  *          TIM_DMABase_DCR.
+  * @param  TIM_DMABurstLength: DMA Burst length.
+  *   This parameter can be one value between:
+  *   TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers.
+  * @retval None
+  */
+void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+  assert_param(IS_TIM_DMA_BASE(TIM_DMABase));
+  assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength));
+  /* Set the DMA Base and the DMA Burst Length */
+  TIMx->DCR = TIM_DMABase | TIM_DMABurstLength;
+}
+
+/**
+  * @brief  Enables or disables the TIMx's DMA Requests.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 6, 7, 8, 15, 16 or 17 
+  *   to select the TIM peripheral. 
+  * @param  TIM_DMASource: specifies the DMA Request sources.
+  *   This parameter can be any combination of the following values:
+  *     @arg TIM_DMA_Update: TIM update Interrupt source
+  *     @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
+  *     @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
+  *     @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
+  *     @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
+  *     @arg TIM_DMA_COM: TIM Commutation DMA source
+  *     @arg TIM_DMA_Trigger: TIM Trigger DMA source
+  * @param  NewState: new state of the DMA Request sources.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState)
+{ 
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST9_PERIPH(TIMx));
+  assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the DMA sources */
+    TIMx->DIER |= TIM_DMASource; 
+  }
+  else
+  {
+    /* Disable the DMA sources */
+    TIMx->DIER &= (uint16_t)~TIM_DMASource;
+  }
+}
+
+/**
+  * @brief  Configures the TIMx internal Clock
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15
+  *         to select the TIM peripheral.
+  * @retval None
+  */
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  /* Disable slave mode to clock the prescaler directly with the internal clock */
+  TIMx->SMCR &=  (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+}
+
+/**
+  * @brief  Configures the TIMx Internal Trigger as External Clock
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_ITRSource: Trigger source.
+  *   This parameter can be one of the following values:
+  * @param  TIM_TS_ITR0: Internal Trigger 0
+  * @param  TIM_TS_ITR1: Internal Trigger 1
+  * @param  TIM_TS_ITR2: Internal Trigger 2
+  * @param  TIM_TS_ITR3: Internal Trigger 3
+  * @retval None
+  */
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource));
+  /* Select the Internal Trigger */
+  TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource);
+  /* Select the External clock mode1 */
+  TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+  * @brief  Configures the TIMx Trigger as External Clock
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_TIxExternalCLKSource: Trigger source.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector
+  *     @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1
+  *     @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2
+  * @param  TIM_ICPolarity: specifies the TIx Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Rising
+  *     @arg TIM_ICPolarity_Falling
+  * @param  ICFilter : specifies the filter value.
+  *   This parameter must be a value between 0x0 and 0xF.
+  * @retval None
+  */
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+                                uint16_t TIM_ICPolarity, uint16_t ICFilter)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_TIXCLK_SOURCE(TIM_TIxExternalCLKSource));
+  assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity));
+  assert_param(IS_TIM_IC_FILTER(ICFilter));
+  /* Configure the Timer Input Clock Source */
+  if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2)
+  {
+    TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+  }
+  else
+  {
+    TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+  }
+  /* Select the Trigger source */
+  TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource);
+  /* Select the External clock mode1 */
+  TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+  * @brief  Configures the External clock Mode1
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+  *     @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+  *     @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+  *     @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+  * @param  TIM_ExtTRGPolarity: The external Trigger Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+  *     @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+  * @param  ExtTRGFilter: External Trigger Filter.
+  *   This parameter must be a value between 0x00 and 0x0F
+  * @retval None
+  */
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+                             uint16_t ExtTRGFilter)
+{
+  uint16_t tmpsmcr = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+  assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+  assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+  /* Configure the ETR Clock source */
+  TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+  
+  /* Get the TIMx SMCR register value */
+  tmpsmcr = TIMx->SMCR;
+  /* Reset the SMS Bits */
+  tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+  /* Select the External clock mode1 */
+  tmpsmcr |= TIM_SlaveMode_External1;
+  /* Select the Trigger selection : ETRF */
+  tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+  tmpsmcr |= TIM_TS_ETRF;
+  /* Write to TIMx SMCR */
+  TIMx->SMCR = tmpsmcr;
+}
+
+/**
+  * @brief  Configures the External clock Mode2
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+  *     @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+  *     @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+  *     @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+  * @param  TIM_ExtTRGPolarity: The external Trigger Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+  *     @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+  * @param  ExtTRGFilter: External Trigger Filter.
+  *   This parameter must be a value between 0x00 and 0x0F
+  * @retval None
+  */
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
+                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+  assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+  assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+  /* Configure the ETR Clock source */
+  TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+  /* Enable the External clock mode2 */
+  TIMx->SMCR |= TIM_SMCR_ECE;
+}
+
+/**
+  * @brief  Configures the TIMx External Trigger (ETR).
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+  *     @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+  *     @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+  *     @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+  * @param  TIM_ExtTRGPolarity: The external Trigger Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+  *     @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+  * @param  ExtTRGFilter: External Trigger Filter.
+  *   This parameter must be a value between 0x00 and 0x0F
+  * @retval None
+  */
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+                   uint16_t ExtTRGFilter)
+{
+  uint16_t tmpsmcr = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+  assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+  assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+  tmpsmcr = TIMx->SMCR;
+  /* Reset the ETR Bits */
+  tmpsmcr &= SMCR_ETR_Mask;
+  /* Set the Prescaler, the Filter value and the Polarity */
+  tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8)));
+  /* Write to TIMx SMCR */
+  TIMx->SMCR = tmpsmcr;
+}
+
+/**
+  * @brief  Configures the TIMx Prescaler.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  Prescaler: specifies the Prescaler Register value
+  * @param  TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode
+  *   This parameter can be one of the following values:
+  *     @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.
+  *     @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately.
+  * @retval None
+  */
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
+  /* Set the Prescaler value */
+  TIMx->PSC = Prescaler;
+  /* Set or reset the UG Bit */
+  TIMx->EGR = TIM_PSCReloadMode;
+}
+
+/**
+  * @brief  Specifies the TIMx Counter Mode to be used.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_CounterMode: specifies the Counter Mode to be used
+  *   This parameter can be one of the following values:
+  *     @arg TIM_CounterMode_Up: TIM Up Counting Mode
+  *     @arg TIM_CounterMode_Down: TIM Down Counting Mode
+  *     @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1
+  *     @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2
+  *     @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3
+  * @retval None
+  */
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode)
+{
+  uint16_t tmpcr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode));
+  tmpcr1 = TIMx->CR1;
+  /* Reset the CMS and DIR Bits */
+  tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
+  /* Set the Counter Mode */
+  tmpcr1 |= TIM_CounterMode;
+  /* Write to TIMx CR1 register */
+  TIMx->CR1 = tmpcr1;
+}
+
+/**
+  * @brief  Selects the Input Trigger source
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_InputTriggerSource: The Input Trigger source.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_TS_ITR0: Internal Trigger 0
+  *     @arg TIM_TS_ITR1: Internal Trigger 1
+  *     @arg TIM_TS_ITR2: Internal Trigger 2
+  *     @arg TIM_TS_ITR3: Internal Trigger 3
+  *     @arg TIM_TS_TI1F_ED: TI1 Edge Detector
+  *     @arg TIM_TS_TI1FP1: Filtered Timer Input 1
+  *     @arg TIM_TS_TI2FP2: Filtered Timer Input 2
+  *     @arg TIM_TS_ETRF: External Trigger input
+  * @retval None
+  */
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+  uint16_t tmpsmcr = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource));
+  /* Get the TIMx SMCR register value */
+  tmpsmcr = TIMx->SMCR;
+  /* Reset the TS Bits */
+  tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS));
+  /* Set the Input Trigger source */
+  tmpsmcr |= TIM_InputTriggerSource;
+  /* Write to TIMx SMCR */
+  TIMx->SMCR = tmpsmcr;
+}
+
+/**
+  * @brief  Configures the TIMx Encoder Interface.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_EncoderMode: specifies the TIMx Encoder Mode.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level.
+  *     @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level.
+  *     @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending
+  *                                on the level of the other input.
+  * @param  TIM_IC1Polarity: specifies the IC1 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Falling: IC Falling edge.
+  *     @arg TIM_ICPolarity_Rising: IC Rising edge.
+  * @param  TIM_IC2Polarity: specifies the IC2 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Falling: IC Falling edge.
+  *     @arg TIM_ICPolarity_Rising: IC Rising edge.
+  * @retval None
+  */
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
+{
+  uint16_t tmpsmcr = 0;
+  uint16_t tmpccmr1 = 0;
+  uint16_t tmpccer = 0;
+    
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+  assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode));
+  assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity));
+  assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity));
+
+  /* Get the TIMx SMCR register value */
+  tmpsmcr = TIMx->SMCR;
+  
+  /* Get the TIMx CCMR1 register value */
+  tmpccmr1 = TIMx->CCMR1;
+  
+  /* Get the TIMx CCER register value */
+  tmpccer = TIMx->CCER;
+  
+  /* Set the encoder Mode */
+  tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
+  tmpsmcr |= TIM_EncoderMode;
+  
+  /* Select the Capture Compare 1 and the Capture Compare 2 as input */
+  tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
+  tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
+  
+  /* Set the TI1 and the TI2 Polarities */
+  tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P)));
+  tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
+  
+  /* Write to TIMx SMCR */
+  TIMx->SMCR = tmpsmcr;
+  /* Write to TIMx CCMR1 */
+  TIMx->CCMR1 = tmpccmr1;
+  /* Write to TIMx CCER */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Forces the TIMx output 1 waveform to active or inactive level.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ForcedAction_Active: Force active level on OC1REF
+  *     @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF.
+  * @retval None
+  */
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC1M Bits */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M);
+  /* Configure The Forced output Mode */
+  tmpccmr1 |= TIM_ForcedAction;
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Forces the TIMx output 2 waveform to active or inactive level.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ForcedAction_Active: Force active level on OC2REF
+  *     @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF.
+  * @retval None
+  */
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC2M Bits */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M);
+  /* Configure The Forced output Mode */
+  tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8);
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Forces the TIMx output 3 waveform to active or inactive level.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ForcedAction_Active: Force active level on OC3REF
+  *     @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF.
+  * @retval None
+  */
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC1M Bits */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M);
+  /* Configure The Forced output Mode */
+  tmpccmr2 |= TIM_ForcedAction;
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Forces the TIMx output 4 waveform to active or inactive level.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ForcedAction_Active: Force active level on OC4REF
+  *     @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF.
+  * @retval None
+  */
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC2M Bits */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M);
+  /* Configure The Forced output Mode */
+  tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8);
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Enables or disables TIMx peripheral Preload register on ARR.
+  * @param  TIMx: where x can be  1 to 17 to select the TIM peripheral.
+  * @param  NewState: new state of the TIMx peripheral Preload register
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the ARR Preload Bit */
+    TIMx->CR1 |= TIM_CR1_ARPE;
+  }
+  else
+  {
+    /* Reset the ARR Preload Bit */
+    TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE);
+  }
+}
+
+/**
+  * @brief  Selects the TIM peripheral Commutation event.
+  * @param  TIMx: where x can be  1, 8, 15, 16 or 17 to select the TIMx peripheral
+  * @param  NewState: new state of the Commutation event.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the COM Bit */
+    TIMx->CR2 |= TIM_CR2_CCUS;
+  }
+  else
+  {
+    /* Reset the COM Bit */
+    TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCUS);
+  }
+}
+
+/**
+  * @brief  Selects the TIMx peripheral Capture Compare DMA source.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 15, 16 or 17 to select 
+  *         the TIM peripheral.
+  * @param  NewState: new state of the Capture Compare DMA source
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the CCDS Bit */
+    TIMx->CR2 |= TIM_CR2_CCDS;
+  }
+  else
+  {
+    /* Reset the CCDS Bit */
+    TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS);
+  }
+}
+
+/**
+  * @brief  Sets or Resets the TIM peripheral Capture Compare Preload Control bit.
+  * @param  TIMx: where x can be   1, 2, 3, 4, 5, 8 or 15 
+  *         to select the TIMx peripheral
+  * @param  NewState: new state of the Capture Compare Preload Control bit
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState)
+{ 
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the CCPC Bit */
+    TIMx->CR2 |= TIM_CR2_CCPC;
+  }
+  else
+  {
+    /* Reset the CCPC Bit */
+    TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCPC);
+  }
+}
+
+/**
+  * @brief  Enables or disables the TIMx peripheral Preload register on CCR1.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_OCPreload: new state of the TIMx peripheral Preload register
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPreload_Enable
+  *     @arg TIM_OCPreload_Disable
+  * @retval None
+  */
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC1PE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE);
+  /* Enable or Disable the Output Compare Preload feature */
+  tmpccmr1 |= TIM_OCPreload;
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Enables or disables the TIMx peripheral Preload register on CCR2.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select 
+  *         the TIM peripheral.
+  * @param  TIM_OCPreload: new state of the TIMx peripheral Preload register
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPreload_Enable
+  *     @arg TIM_OCPreload_Disable
+  * @retval None
+  */
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC2PE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE);
+  /* Enable or Disable the Output Compare Preload feature */
+  tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8);
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Enables or disables the TIMx peripheral Preload register on CCR3.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCPreload: new state of the TIMx peripheral Preload register
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPreload_Enable
+  *     @arg TIM_OCPreload_Disable
+  * @retval None
+  */
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC3PE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE);
+  /* Enable or Disable the Output Compare Preload feature */
+  tmpccmr2 |= TIM_OCPreload;
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Enables or disables the TIMx peripheral Preload register on CCR4.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCPreload: new state of the TIMx peripheral Preload register
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPreload_Enable
+  *     @arg TIM_OCPreload_Disable
+  * @retval None
+  */
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC4PE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE);
+  /* Enable or Disable the Output Compare Preload feature */
+  tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8);
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Configures the TIMx Output Compare 1 Fast feature.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCFast_Enable: TIM output compare fast enable
+  *     @arg TIM_OCFast_Disable: TIM output compare fast disable
+  * @retval None
+  */
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+  /* Get the TIMx CCMR1 register value */
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC1FE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE);
+  /* Enable or Disable the Output Compare Fast Bit */
+  tmpccmr1 |= TIM_OCFast;
+  /* Write to TIMx CCMR1 */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Configures the TIMx Output Compare 2 Fast feature.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5, 8, 9, 12 or 15 to select 
+  *         the TIM peripheral.
+  * @param  TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCFast_Enable: TIM output compare fast enable
+  *     @arg TIM_OCFast_Disable: TIM output compare fast disable
+  * @retval None
+  */
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+  /* Get the TIMx CCMR1 register value */
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC2FE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE);
+  /* Enable or Disable the Output Compare Fast Bit */
+  tmpccmr1 |= (uint16_t)(TIM_OCFast << 8);
+  /* Write to TIMx CCMR1 */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Configures the TIMx Output Compare 3 Fast feature.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCFast_Enable: TIM output compare fast enable
+  *     @arg TIM_OCFast_Disable: TIM output compare fast disable
+  * @retval None
+  */
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+  /* Get the TIMx CCMR2 register value */
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC3FE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE);
+  /* Enable or Disable the Output Compare Fast Bit */
+  tmpccmr2 |= TIM_OCFast;
+  /* Write to TIMx CCMR2 */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Configures the TIMx Output Compare 4 Fast feature.
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCFast_Enable: TIM output compare fast enable
+  *     @arg TIM_OCFast_Disable: TIM output compare fast disable
+  * @retval None
+  */
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+  /* Get the TIMx CCMR2 register value */
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC4FE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE);
+  /* Enable or Disable the Output Compare Fast Bit */
+  tmpccmr2 |= (uint16_t)(TIM_OCFast << 8);
+  /* Write to TIMx CCMR2 */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Clears or safeguards the OCREF1 signal on an external event
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCClear_Enable: TIM Output clear enable
+  *     @arg TIM_OCClear_Disable: TIM Output clear disable
+  * @retval None
+  */
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+  tmpccmr1 = TIMx->CCMR1;
+
+  /* Reset the OC1CE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE);
+  /* Enable or Disable the Output Compare Clear Bit */
+  tmpccmr1 |= TIM_OCClear;
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Clears or safeguards the OCREF2 signal on an external event
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCClear_Enable: TIM Output clear enable
+  *     @arg TIM_OCClear_Disable: TIM Output clear disable
+  * @retval None
+  */
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+  uint16_t tmpccmr1 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+  tmpccmr1 = TIMx->CCMR1;
+  /* Reset the OC2CE Bit */
+  tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE);
+  /* Enable or Disable the Output Compare Clear Bit */
+  tmpccmr1 |= (uint16_t)(TIM_OCClear << 8);
+  /* Write to TIMx CCMR1 register */
+  TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+  * @brief  Clears or safeguards the OCREF3 signal on an external event
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCClear_Enable: TIM Output clear enable
+  *     @arg TIM_OCClear_Disable: TIM Output clear disable
+  * @retval None
+  */
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC3CE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE);
+  /* Enable or Disable the Output Compare Clear Bit */
+  tmpccmr2 |= TIM_OCClear;
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Clears or safeguards the OCREF4 signal on an external event
+  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCClear_Enable: TIM Output clear enable
+  *     @arg TIM_OCClear_Disable: TIM Output clear disable
+  * @retval None
+  */
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+  uint16_t tmpccmr2 = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+  tmpccmr2 = TIMx->CCMR2;
+  /* Reset the OC4CE Bit */
+  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE);
+  /* Enable or Disable the Output Compare Clear Bit */
+  tmpccmr2 |= (uint16_t)(TIM_OCClear << 8);
+  /* Write to TIMx CCMR2 register */
+  TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+  * @brief  Configures the TIMx channel 1 polarity.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_OCPolarity: specifies the OC1 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPolarity_High: Output Compare active high
+  *     @arg TIM_OCPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC1P Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P);
+  tmpccer |= TIM_OCPolarity;
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx Channel 1N polarity.
+  * @param  TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral.
+  * @param  TIM_OCNPolarity: specifies the OC1N Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCNPolarity_High: Output Compare active high
+  *     @arg TIM_OCNPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+  assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+   
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC1NP Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1NP);
+  tmpccer |= TIM_OCNPolarity;
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx channel 2 polarity.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_OCPolarity: specifies the OC2 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPolarity_High: Output Compare active high
+  *     @arg TIM_OCPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC2P Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P);
+  tmpccer |= (uint16_t)(TIM_OCPolarity << 4);
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx Channel 2N polarity.
+  * @param  TIMx: where x can be 1 or 8 to select the TIM peripheral.
+  * @param  TIM_OCNPolarity: specifies the OC2N Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCNPolarity_High: Output Compare active high
+  *     @arg TIM_OCNPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+  assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+  
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC2NP Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2NP);
+  tmpccer |= (uint16_t)(TIM_OCNPolarity << 4);
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx channel 3 polarity.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCPolarity: specifies the OC3 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPolarity_High: Output Compare active high
+  *     @arg TIM_OCPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC3P Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P);
+  tmpccer |= (uint16_t)(TIM_OCPolarity << 8);
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx Channel 3N polarity.
+  * @param  TIMx: where x can be 1 or 8 to select the TIM peripheral.
+  * @param  TIM_OCNPolarity: specifies the OC3N Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCNPolarity_High: Output Compare active high
+  *     @arg TIM_OCNPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+  uint16_t tmpccer = 0;
+ 
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+  assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+    
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC3NP Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3NP);
+  tmpccer |= (uint16_t)(TIM_OCNPolarity << 8);
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configures the TIMx channel 4 polarity.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_OCPolarity: specifies the OC4 Polarity
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCPolarity_High: Output Compare active high
+  *     @arg TIM_OCPolarity_Low: Output Compare active low
+  * @retval None
+  */
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+  uint16_t tmpccer = 0;
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+  tmpccer = TIMx->CCER;
+  /* Set or Reset the CC4P Bit */
+  tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P);
+  tmpccer |= (uint16_t)(TIM_OCPolarity << 12);
+  /* Write to TIMx CCER register */
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Enables or disables the TIM Capture Compare Channel x.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_Channel: specifies the TIM Channel
+  *   This parameter can be one of the following values:
+  *     @arg TIM_Channel_1: TIM Channel 1
+  *     @arg TIM_Channel_2: TIM Channel 2
+  *     @arg TIM_Channel_3: TIM Channel 3
+  *     @arg TIM_Channel_4: TIM Channel 4
+  * @param  TIM_CCx: specifies the TIM Channel CCxE bit new state.
+  *   This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. 
+  * @retval None
+  */
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx)
+{
+  uint16_t tmp = 0;
+
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_CHANNEL(TIM_Channel));
+  assert_param(IS_TIM_CCX(TIM_CCx));
+
+  tmp = CCER_CCE_Set << TIM_Channel;
+
+  /* Reset the CCxE Bit */
+  TIMx->CCER &= (uint16_t)~ tmp;
+
+  /* Set or reset the CCxE Bit */ 
+  TIMx->CCER |=  (uint16_t)(TIM_CCx << TIM_Channel);
+}
+
+/**
+  * @brief  Enables or disables the TIM Capture Compare Channel xN.
+  * @param  TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral.
+  * @param  TIM_Channel: specifies the TIM Channel
+  *   This parameter can be one of the following values:
+  *     @arg TIM_Channel_1: TIM Channel 1
+  *     @arg TIM_Channel_2: TIM Channel 2
+  *     @arg TIM_Channel_3: TIM Channel 3
+  * @param  TIM_CCxN: specifies the TIM Channel CCxNE bit new state.
+  *   This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. 
+  * @retval None
+  */
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN)
+{
+  uint16_t tmp = 0;
+
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+  assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel));
+  assert_param(IS_TIM_CCXN(TIM_CCxN));
+
+  tmp = CCER_CCNE_Set << TIM_Channel;
+
+  /* Reset the CCxNE Bit */
+  TIMx->CCER &= (uint16_t) ~tmp;
+
+  /* Set or reset the CCxNE Bit */ 
+  TIMx->CCER |=  (uint16_t)(TIM_CCxN << TIM_Channel);
+}
+
+/**
+  * @brief  Selects the TIM Output Compare Mode.
+  * @note   This function disables the selected channel before changing the Output
+  *         Compare Mode.
+  *         User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_Channel: specifies the TIM Channel
+  *   This parameter can be one of the following values:
+  *     @arg TIM_Channel_1: TIM Channel 1
+  *     @arg TIM_Channel_2: TIM Channel 2
+  *     @arg TIM_Channel_3: TIM Channel 3
+  *     @arg TIM_Channel_4: TIM Channel 4
+  * @param  TIM_OCMode: specifies the TIM Output Compare Mode.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OCMode_Timing
+  *     @arg TIM_OCMode_Active
+  *     @arg TIM_OCMode_Toggle
+  *     @arg TIM_OCMode_PWM1
+  *     @arg TIM_OCMode_PWM2
+  *     @arg TIM_ForcedAction_Active
+  *     @arg TIM_ForcedAction_InActive
+  * @retval None
+  */
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
+{
+  uint32_t tmp = 0;
+  uint16_t tmp1 = 0;
+
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_CHANNEL(TIM_Channel));
+  assert_param(IS_TIM_OCM(TIM_OCMode));
+
+  tmp = (uint32_t) TIMx;
+  tmp += CCMR_Offset;
+
+  tmp1 = CCER_CCE_Set << (uint16_t)TIM_Channel;
+
+  /* Disable the Channel: Reset the CCxE Bit */
+  TIMx->CCER &= (uint16_t) ~tmp1;
+
+  if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3))
+  {
+    tmp += (TIM_Channel>>1);
+
+    /* Reset the OCxM bits in the CCMRx register */
+    *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M);
+   
+    /* Configure the OCxM bits in the CCMRx register */
+    *(__IO uint32_t *) tmp |= TIM_OCMode;
+  }
+  else
+  {
+    tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
+
+    /* Reset the OCxM bits in the CCMRx register */
+    *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M);
+    
+    /* Configure the OCxM bits in the CCMRx register */
+    *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);
+  }
+}
+
+/**
+  * @brief  Enables or Disables the TIMx Update event.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  NewState: new state of the TIMx UDIS bit
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the Update Disable Bit */
+    TIMx->CR1 |= TIM_CR1_UDIS;
+  }
+  else
+  {
+    /* Reset the Update Disable Bit */
+    TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS);
+  }
+}
+
+/**
+  * @brief  Configures the TIMx Update Request Interrupt source.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_UpdateSource: specifies the Update source.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_UpdateSource_Regular: Source of update is the counter overflow/underflow
+                                       or the setting of UG bit, or an update generation
+                                       through the slave mode controller.
+  *     @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow.
+  * @retval None
+  */
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource));
+  if (TIM_UpdateSource != TIM_UpdateSource_Global)
+  {
+    /* Set the URS Bit */
+    TIMx->CR1 |= TIM_CR1_URS;
+  }
+  else
+  {
+    /* Reset the URS Bit */
+    TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS);
+  }
+}
+
+/**
+  * @brief  Enables or disables the TIMx's Hall sensor interface.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  NewState: new state of the TIMx Hall sensor interface.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Set the TI1S Bit */
+    TIMx->CR2 |= TIM_CR2_TI1S;
+  }
+  else
+  {
+    /* Reset the TI1S Bit */
+    TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S);
+  }
+}
+
+/**
+  * @brief  Selects the TIMx's One Pulse Mode.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_OPMode: specifies the OPM Mode to be used.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_OPMode_Single
+  *     @arg TIM_OPMode_Repetitive
+  * @retval None
+  */
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_OPM_MODE(TIM_OPMode));
+  /* Reset the OPM Bit */
+  TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM);
+  /* Configure the OPM Mode */
+  TIMx->CR1 |= TIM_OPMode;
+}
+
+/**
+  * @brief  Selects the TIMx Trigger Output Mode.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_TRGOSource: specifies the Trigger Output source.
+  *   This paramter can be one of the following values:
+  *
+  *  - For all TIMx
+  *     @arg TIM_TRGOSource_Reset:  The UG bit in the TIM_EGR register is used as the trigger output (TRGO).
+  *     @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO).
+  *     @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO).
+  *
+  *  - For all TIMx except TIM6 and TIM7
+  *     @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag
+  *                              is to be set, as soon as a capture or compare match occurs (TRGO).
+  *     @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO).
+  *     @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO).
+  *     @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO).
+  *     @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO).
+  *
+  * @retval None
+  */
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST7_PERIPH(TIMx));
+  assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource));
+  /* Reset the MMS Bits */
+  TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS);
+  /* Select the TRGO source */
+  TIMx->CR2 |=  TIM_TRGOSource;
+}
+
+/**
+  * @brief  Selects the TIMx Slave Mode.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_SlaveMode: specifies the Timer Slave Mode.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes
+  *                               the counter and triggers an update of the registers.
+  *     @arg TIM_SlaveMode_Gated:     The counter clock is enabled when the trigger signal (TRGI) is high.
+  *     @arg TIM_SlaveMode_Trigger:   The counter starts at a rising edge of the trigger TRGI.
+  *     @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter.
+  * @retval None
+  */
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode));
+ /* Reset the SMS Bits */
+  TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS);
+  /* Select the Slave Mode */
+  TIMx->SMCR |= TIM_SlaveMode;
+}
+
+/**
+  * @brief  Sets or Resets the TIMx Master/Slave Mode.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_MasterSlaveMode: specifies the Timer Master Slave Mode.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer
+  *                                      and its slaves (through TRGO).
+  *     @arg TIM_MasterSlaveMode_Disable: No action
+  * @retval None
+  */
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode));
+  /* Reset the MSM Bit */
+  TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM);
+  
+  /* Set or Reset the MSM Bit */
+  TIMx->SMCR |= TIM_MasterSlaveMode;
+}
+
+/**
+  * @brief  Sets the TIMx Counter Register value
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  Counter: specifies the Counter register new value.
+  * @retval None
+  */
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  /* Set the Counter Register value */
+  TIMx->CNT = Counter;
+}
+
+/**
+  * @brief  Sets the TIMx Autoreload Register value
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  Autoreload: specifies the Autoreload register new value.
+  * @retval None
+  */
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  /* Set the Autoreload Register value */
+  TIMx->ARR = Autoreload;
+}
+
+/**
+  * @brief  Sets the TIMx Capture Compare1 Register value
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  Compare1: specifies the Capture Compare1 register new value.
+  * @retval None
+  */
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  /* Set the Capture Compare1 Register value */
+  TIMx->CCR1 = Compare1;
+}
+
+/**
+  * @brief  Sets the TIMx Capture Compare2 Register value
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  Compare2: specifies the Capture Compare2 register new value.
+  * @retval None
+  */
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  /* Set the Capture Compare2 Register value */
+  TIMx->CCR2 = Compare2;
+}
+
+/**
+  * @brief  Sets the TIMx Capture Compare3 Register value
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  Compare3: specifies the Capture Compare3 register new value.
+  * @retval None
+  */
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  /* Set the Capture Compare3 Register value */
+  TIMx->CCR3 = Compare3;
+}
+
+/**
+  * @brief  Sets the TIMx Capture Compare4 Register value
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  Compare4: specifies the Capture Compare4 register new value.
+  * @retval None
+  */
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  /* Set the Capture Compare4 Register value */
+  TIMx->CCR4 = Compare4;
+}
+
+/**
+  * @brief  Sets the TIMx Input Capture 1 prescaler.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_ICPSC: specifies the Input Capture1 prescaler new value.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPSC_DIV1: no prescaler
+  *     @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+  *     @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+  *     @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+  * @retval None
+  */
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+  /* Reset the IC1PSC Bits */
+  TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC);
+  /* Set the IC1PSC value */
+  TIMx->CCMR1 |= TIM_ICPSC;
+}
+
+/**
+  * @brief  Sets the TIMx Input Capture 2 prescaler.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_ICPSC: specifies the Input Capture2 prescaler new value.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPSC_DIV1: no prescaler
+  *     @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+  *     @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+  *     @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+  * @retval None
+  */
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+  /* Reset the IC2PSC Bits */
+  TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC);
+  /* Set the IC2PSC value */
+  TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+  * @brief  Sets the TIMx Input Capture 3 prescaler.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ICPSC: specifies the Input Capture3 prescaler new value.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPSC_DIV1: no prescaler
+  *     @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+  *     @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+  *     @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+  * @retval None
+  */
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+  /* Reset the IC3PSC Bits */
+  TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC);
+  /* Set the IC3PSC value */
+  TIMx->CCMR2 |= TIM_ICPSC;
+}
+
+/**
+  * @brief  Sets the TIMx Input Capture 4 prescaler.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ICPSC: specifies the Input Capture4 prescaler new value.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPSC_DIV1: no prescaler
+  *     @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+  *     @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+  *     @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+  * @retval None
+  */
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{  
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+  /* Reset the IC4PSC Bits */
+  TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC);
+  /* Set the IC4PSC value */
+  TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+  * @brief  Sets the TIMx Clock Division value.
+  * @param  TIMx: where x can be  1 to 17 except 6 and 7 to select 
+  *   the TIM peripheral.
+  * @param  TIM_CKD: specifies the clock division value.
+  *   This parameter can be one of the following value:
+  *     @arg TIM_CKD_DIV1: TDTS = Tck_tim
+  *     @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim
+  *     @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim
+  * @retval None
+  */
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  assert_param(IS_TIM_CKD_DIV(TIM_CKD));
+  /* Reset the CKD Bits */
+  TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD);
+  /* Set the CKD value */
+  TIMx->CR1 |= TIM_CKD;
+}
+
+/**
+  * @brief  Gets the TIMx Input Capture 1 value.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @retval Capture Compare 1 Register value.
+  */
+uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
+  /* Get the Capture 1 Register value */
+  return TIMx->CCR1;
+}
+
+/**
+  * @brief  Gets the TIMx Input Capture 2 value.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @retval Capture Compare 2 Register value.
+  */
+uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+  /* Get the Capture 2 Register value */
+  return TIMx->CCR2;
+}
+
+/**
+  * @brief  Gets the TIMx Input Capture 3 value.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @retval Capture Compare 3 Register value.
+  */
+uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx)); 
+  /* Get the Capture 3 Register value */
+  return TIMx->CCR3;
+}
+
+/**
+  * @brief  Gets the TIMx Input Capture 4 value.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @retval Capture Compare 4 Register value.
+  */
+uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+  /* Get the Capture 4 Register value */
+  return TIMx->CCR4;
+}
+
+/**
+  * @brief  Gets the TIMx Counter value.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @retval Counter Register value.
+  */
+uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  /* Get the Counter Register value */
+  return TIMx->CNT;
+}
+
+/**
+  * @brief  Gets the TIMx Prescaler value.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @retval Prescaler Register value.
+  */
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  /* Get the Prescaler Register value */
+  return TIMx->PSC;
+}
+
+/**
+  * @brief  Checks whether the specified TIM flag is set or not.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_FLAG: specifies the flag to check.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_FLAG_Update: TIM update Flag
+  *     @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+  *     @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+  *     @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+  *     @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+  *     @arg TIM_FLAG_COM: TIM Commutation Flag
+  *     @arg TIM_FLAG_Trigger: TIM Trigger Flag
+  *     @arg TIM_FLAG_Break: TIM Break Flag
+  *     @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+  *     @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+  *     @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+  *     @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+  * @note
+  *   - TIM6 and TIM7 can have only one update flag. 
+  *   - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1,
+  *      TIM_FLAG_CC2 or TIM_FLAG_Trigger. 
+  *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1.   
+  *   - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. 
+  *   - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.    
+  * @retval The new state of TIM_FLAG (SET or RESET).
+  */
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{ 
+  ITStatus bitstatus = RESET;  
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_GET_FLAG(TIM_FLAG));
+  
+  if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the TIMx's pending flags.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_FLAG: specifies the flag bit to clear.
+  *   This parameter can be any combination of the following values:
+  *     @arg TIM_FLAG_Update: TIM update Flag
+  *     @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+  *     @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+  *     @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+  *     @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+  *     @arg TIM_FLAG_COM: TIM Commutation Flag
+  *     @arg TIM_FLAG_Trigger: TIM Trigger Flag
+  *     @arg TIM_FLAG_Break: TIM Break Flag
+  *     @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag
+  *     @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag
+  *     @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag
+  *     @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag
+  * @note
+  *   - TIM6 and TIM7 can have only one update flag. 
+  *   - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1,
+  *      TIM_FLAG_CC2 or TIM_FLAG_Trigger. 
+  *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1.   
+  *   - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. 
+  *   - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.   
+  * @retval None
+  */
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{  
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG));
+   
+  /* Clear the flags */
+  TIMx->SR = (uint16_t)~TIM_FLAG;
+}
+
+/**
+  * @brief  Checks whether the TIM interrupt has occurred or not.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_IT: specifies the TIM interrupt source to check.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_IT_Update: TIM update Interrupt source
+  *     @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+  *     @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+  *     @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+  *     @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+  *     @arg TIM_IT_COM: TIM Commutation Interrupt source
+  *     @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+  *     @arg TIM_IT_Break: TIM Break Interrupt source
+  * @note
+  *   - TIM6 and TIM7 can generate only an update interrupt.
+  *   - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+  *      TIM_IT_CC2 or TIM_IT_Trigger. 
+  *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.   
+  *   - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. 
+  *   - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.  
+  * @retval The new state of the TIM_IT(SET or RESET).
+  */
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+  ITStatus bitstatus = RESET;  
+  uint16_t itstatus = 0x0, itenable = 0x0;
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_GET_IT(TIM_IT));
+   
+  itstatus = TIMx->SR & TIM_IT;
+  
+  itenable = TIMx->DIER & TIM_IT;
+  if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the TIMx's interrupt pending bits.
+  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
+  * @param  TIM_IT: specifies the pending bit to clear.
+  *   This parameter can be any combination of the following values:
+  *     @arg TIM_IT_Update: TIM1 update Interrupt source
+  *     @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+  *     @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+  *     @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+  *     @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+  *     @arg TIM_IT_COM: TIM Commutation Interrupt source
+  *     @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+  *     @arg TIM_IT_Break: TIM Break Interrupt source
+  * @note
+  *   - TIM6 and TIM7 can generate only an update interrupt.
+  *   - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1,
+  *      TIM_IT_CC2 or TIM_IT_Trigger. 
+  *   - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1.   
+  *   - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. 
+  *   - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17.    
+  * @retval None
+  */
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+  /* Check the parameters */
+  assert_param(IS_TIM_ALL_PERIPH(TIMx));
+  assert_param(IS_TIM_IT(TIM_IT));
+  /* Clear the IT pending Bit */
+  TIMx->SR = (uint16_t)~TIM_IT;
+}
+
+/**
+  * @brief  Configure the TI1 as Input.
+  * @param  TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
+  * @param  TIM_ICPolarity : The Input Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Rising
+  *     @arg TIM_ICPolarity_Falling
+  * @param  TIM_ICSelection: specifies the input to be used.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1.
+  *     @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2.
+  *     @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC.
+  * @param  TIM_ICFilter: Specifies the Input Capture Filter.
+  *   This parameter must be a value between 0x00 and 0x0F.
+  * @retval None
+  */
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter)
+{
+  uint16_t tmpccmr1 = 0, tmpccer = 0;
+  /* Disable the Channel 1: Reset the CC1E Bit */
+  TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E);
+  tmpccmr1 = TIMx->CCMR1;
+  tmpccer = TIMx->CCER;
+  /* Select the Input and set the filter */
+  tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F)));
+  tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+  
+  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+     (TIMx == TIM4) ||(TIMx == TIM5))
+  {
+    /* Select the Polarity and set the CC1E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P));
+    tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+  }
+  else
+  {
+    /* Select the Polarity and set the CC1E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP));
+    tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+  }
+
+  /* Write to TIMx CCMR1 and CCER registers */
+  TIMx->CCMR1 = tmpccmr1;
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configure the TI2 as Input.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
+  * @param  TIM_ICPolarity : The Input Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Rising
+  *     @arg TIM_ICPolarity_Falling
+  * @param  TIM_ICSelection: specifies the input to be used.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2.
+  *     @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1.
+  *     @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC.
+  * @param  TIM_ICFilter: Specifies the Input Capture Filter.
+  *   This parameter must be a value between 0x00 and 0x0F.
+  * @retval None
+  */
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter)
+{
+  uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0;
+  /* Disable the Channel 2: Reset the CC2E Bit */
+  TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E);
+  tmpccmr1 = TIMx->CCMR1;
+  tmpccer = TIMx->CCER;
+  tmp = (uint16_t)(TIM_ICPolarity << 4);
+  /* Select the Input and set the filter */
+  tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F)));
+  tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12);
+  tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8);
+  
+  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+     (TIMx == TIM4) ||(TIMx == TIM5))
+  {
+    /* Select the Polarity and set the CC2E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P));
+    tmpccer |=  (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E);
+  }
+  else
+  {
+    /* Select the Polarity and set the CC2E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP));
+    tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC2E);
+  }
+  
+  /* Write to TIMx CCMR1 and CCER registers */
+  TIMx->CCMR1 = tmpccmr1 ;
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configure the TI3 as Input.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ICPolarity : The Input Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Rising
+  *     @arg TIM_ICPolarity_Falling
+  * @param  TIM_ICSelection: specifies the input to be used.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3.
+  *     @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4.
+  *     @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC.
+  * @param  TIM_ICFilter: Specifies the Input Capture Filter.
+  *   This parameter must be a value between 0x00 and 0x0F.
+  * @retval None
+  */
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter)
+{
+  uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+  /* Disable the Channel 3: Reset the CC3E Bit */
+  TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E);
+  tmpccmr2 = TIMx->CCMR2;
+  tmpccer = TIMx->CCER;
+  tmp = (uint16_t)(TIM_ICPolarity << 8);
+  /* Select the Input and set the filter */
+  tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F)));
+  tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+    
+  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+     (TIMx == TIM4) ||(TIMx == TIM5))
+  {
+    /* Select the Polarity and set the CC3E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P));
+    tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E);
+  }
+  else
+  {
+    /* Select the Polarity and set the CC3E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP));
+    tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC3E);
+  }
+  
+  /* Write to TIMx CCMR2 and CCER registers */
+  TIMx->CCMR2 = tmpccmr2;
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @brief  Configure the TI4 as Input.
+  * @param  TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+  * @param  TIM_ICPolarity : The Input Polarity.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICPolarity_Rising
+  *     @arg TIM_ICPolarity_Falling
+  * @param  TIM_ICSelection: specifies the input to be used.
+  *   This parameter can be one of the following values:
+  *     @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4.
+  *     @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3.
+  *     @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC.
+  * @param  TIM_ICFilter: Specifies the Input Capture Filter.
+  *   This parameter must be a value between 0x00 and 0x0F.
+  * @retval None
+  */
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+                       uint16_t TIM_ICFilter)
+{
+  uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+
+   /* Disable the Channel 4: Reset the CC4E Bit */
+  TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E);
+  tmpccmr2 = TIMx->CCMR2;
+  tmpccer = TIMx->CCER;
+  tmp = (uint16_t)(TIM_ICPolarity << 12);
+  /* Select the Input and set the filter */
+  tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F)));
+  tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8);
+  tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12);
+  
+  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
+     (TIMx == TIM4) ||(TIMx == TIM5))
+  {
+    /* Select the Polarity and set the CC4E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P));
+    tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E);
+  }
+  else
+  {
+    /* Select the Polarity and set the CC4E Bit */
+    tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC4NP));
+    tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC4E);
+  }
+  /* Write to TIMx CCMR2 and CCER registers */
+  TIMx->CCMR2 = tmpccmr2;
+  TIMx->CCER = tmpccer;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_lib/src/stm32f10x_usart.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1058 @@
+/**
+  ******************************************************************************
+  * @file    stm32f10x_usart.c
+  * @author  MCD Application Team
+  * @version V3.5.0
+  * @date    11-March-2011
+  * @brief   This file provides all the USART firmware functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_usart.h"
+#include "stm32f10x_rcc.h"
+
+/** @addtogroup STM32F10x_StdPeriph_Driver
+  * @{
+  */
+
+/** @defgroup USART 
+  * @brief USART driver modules
+  * @{
+  */
+
+/** @defgroup USART_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_Defines
+  * @{
+  */
+
+#define CR1_UE_Set                ((uint16_t)0x2000)  /*!< USART Enable Mask */
+#define CR1_UE_Reset              ((uint16_t)0xDFFF)  /*!< USART Disable Mask */
+
+#define CR1_WAKE_Mask             ((uint16_t)0xF7FF)  /*!< USART WakeUp Method Mask */
+
+#define CR1_RWU_Set               ((uint16_t)0x0002)  /*!< USART mute mode Enable Mask */
+#define CR1_RWU_Reset             ((uint16_t)0xFFFD)  /*!< USART mute mode Enable Mask */
+#define CR1_SBK_Set               ((uint16_t)0x0001)  /*!< USART Break Character send Mask */
+#define CR1_CLEAR_Mask            ((uint16_t)0xE9F3)  /*!< USART CR1 Mask */
+#define CR2_Address_Mask          ((uint16_t)0xFFF0)  /*!< USART address Mask */
+
+#define CR2_LINEN_Set              ((uint16_t)0x4000)  /*!< USART LIN Enable Mask */
+#define CR2_LINEN_Reset            ((uint16_t)0xBFFF)  /*!< USART LIN Disable Mask */
+
+#define CR2_LBDL_Mask             ((uint16_t)0xFFDF)  /*!< USART LIN Break detection Mask */
+#define CR2_STOP_CLEAR_Mask       ((uint16_t)0xCFFF)  /*!< USART CR2 STOP Bits Mask */
+#define CR2_CLOCK_CLEAR_Mask      ((uint16_t)0xF0FF)  /*!< USART CR2 Clock Mask */
+
+#define CR3_SCEN_Set              ((uint16_t)0x0020)  /*!< USART SC Enable Mask */
+#define CR3_SCEN_Reset            ((uint16_t)0xFFDF)  /*!< USART SC Disable Mask */
+
+#define CR3_NACK_Set              ((uint16_t)0x0010)  /*!< USART SC NACK Enable Mask */
+#define CR3_NACK_Reset            ((uint16_t)0xFFEF)  /*!< USART SC NACK Disable Mask */
+
+#define CR3_HDSEL_Set             ((uint16_t)0x0008)  /*!< USART Half-Duplex Enable Mask */
+#define CR3_HDSEL_Reset           ((uint16_t)0xFFF7)  /*!< USART Half-Duplex Disable Mask */
+
+#define CR3_IRLP_Mask             ((uint16_t)0xFFFB)  /*!< USART IrDA LowPower mode Mask */
+#define CR3_CLEAR_Mask            ((uint16_t)0xFCFF)  /*!< USART CR3 Mask */
+
+#define CR3_IREN_Set              ((uint16_t)0x0002)  /*!< USART IrDA Enable Mask */
+#define CR3_IREN_Reset            ((uint16_t)0xFFFD)  /*!< USART IrDA Disable Mask */
+#define GTPR_LSB_Mask             ((uint16_t)0x00FF)  /*!< Guard Time Register LSB Mask */
+#define GTPR_MSB_Mask             ((uint16_t)0xFF00)  /*!< Guard Time Register MSB Mask */
+#define IT_Mask                   ((uint16_t)0x001F)  /*!< USART Interrupt Mask */
+
+/* USART OverSampling-8 Mask */
+#define CR1_OVER8_Set             ((u16)0x8000)  /* USART OVER8 mode Enable Mask */
+#define CR1_OVER8_Reset           ((u16)0x7FFF)  /* USART OVER8 mode Disable Mask */
+
+/* USART One Bit Sampling Mask */
+#define CR3_ONEBITE_Set           ((u16)0x0800)  /* USART ONEBITE mode Enable Mask */
+#define CR3_ONEBITE_Reset         ((u16)0xF7FF)  /* USART ONEBITE mode Disable Mask */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Deinitializes the USARTx peripheral registers to their default reset values.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values: 
+  *      USART1, USART2, USART3, UART4 or UART5.
+  * @retval None
+  */
+void USART_DeInit(USART_TypeDef* USARTx)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+  if (USARTx == USART1)
+  {
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
+    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
+  }
+  else if (USARTx == USART2)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
+  }
+  else if (USARTx == USART3)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
+  }    
+  else if (USARTx == UART4)
+  {
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE);
+    RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE);
+  }    
+  else
+  {
+    if (USARTx == UART5)
+    { 
+      RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE);
+      RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE);
+    }
+  }
+}
+
+/**
+  * @brief  Initializes the USARTx peripheral according to the specified
+  *         parameters in the USART_InitStruct .
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_InitStruct: pointer to a USART_InitTypeDef structure
+  *         that contains the configuration information for the specified USART 
+  *         peripheral.
+  * @retval None
+  */
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
+{
+  uint32_t tmpreg = 0x00, apbclock = 0x00;
+  uint32_t integerdivider = 0x00;
+  uint32_t fractionaldivider = 0x00;
+  uint32_t usartxbase = 0;
+  RCC_ClocksTypeDef RCC_ClocksStatus;
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));  
+  assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));
+  assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));
+  assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));
+  assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));
+  assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));
+  /* The hardware flow control is available only for USART1, USART2 and USART3 */
+  if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  }
+
+  usartxbase = (uint32_t)USARTx;
+
+/*---------------------------- USART CR2 Configuration -----------------------*/
+  tmpreg = USARTx->CR2;
+  /* Clear STOP[13:12] bits */
+  tmpreg &= CR2_STOP_CLEAR_Mask;
+  /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/
+  /* Set STOP[13:12] bits according to USART_StopBits value */
+  tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;
+  
+  /* Write to USART CR2 */
+  USARTx->CR2 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR1 Configuration -----------------------*/
+  tmpreg = USARTx->CR1;
+  /* Clear M, PCE, PS, TE and RE bits */
+  tmpreg &= CR1_CLEAR_Mask;
+  /* Configure the USART Word Length, Parity and mode ----------------------- */
+  /* Set the M bits according to USART_WordLength value */
+  /* Set PCE and PS bits according to USART_Parity value */
+  /* Set TE and RE bits according to USART_Mode value */
+  tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
+            USART_InitStruct->USART_Mode;
+  /* Write to USART CR1 */
+  USARTx->CR1 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR3 Configuration -----------------------*/  
+  tmpreg = USARTx->CR3;
+  /* Clear CTSE and RTSE bits */
+  tmpreg &= CR3_CLEAR_Mask;
+  /* Configure the USART HFC -------------------------------------------------*/
+  /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
+  tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
+  /* Write to USART CR3 */
+  USARTx->CR3 = (uint16_t)tmpreg;
+
+/*---------------------------- USART BRR Configuration -----------------------*/
+  /* Configure the USART Baud Rate -------------------------------------------*/
+  RCC_GetClocksFreq(&RCC_ClocksStatus);
+  if (usartxbase == USART1_BASE)
+  {
+    apbclock = RCC_ClocksStatus.PCLK2_Frequency;
+  }
+  else
+  {
+    apbclock = RCC_ClocksStatus.PCLK1_Frequency;
+  }
+  
+  /* Determine the integer part */
+  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
+  {
+    /* Integer part computing in case Oversampling mode is 8 Samples */
+    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));    
+  }
+  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+  {
+    /* Integer part computing in case Oversampling mode is 16 Samples */
+    integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));    
+  }
+  tmpreg = (integerdivider / 100) << 4;
+
+  /* Determine the fractional part */
+  fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
+
+  /* Implement the fractional part in the register */
+  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
+  {
+    tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
+  }
+  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+  {
+    tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
+  }
+  
+  /* Write to USART BRR */
+  USARTx->BRR = (uint16_t)tmpreg;
+}
+
+/**
+  * @brief  Fills each USART_InitStruct member with its default value.
+  * @param  USART_InitStruct: pointer to a USART_InitTypeDef structure
+  *         which will be initialized.
+  * @retval None
+  */
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct)
+{
+  /* USART_InitStruct members default value */
+  USART_InitStruct->USART_BaudRate = 9600;
+  USART_InitStruct->USART_WordLength = USART_WordLength_8b;
+  USART_InitStruct->USART_StopBits = USART_StopBits_1;
+  USART_InitStruct->USART_Parity = USART_Parity_No ;
+  USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+  USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
+}
+
+/**
+  * @brief  Initializes the USARTx peripheral Clock according to the 
+  *          specified parameters in the USART_ClockInitStruct .
+  * @param  USARTx: where x can be 1, 2, 3 to select the USART peripheral.
+  * @param  USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+  *         structure that contains the configuration information for the specified 
+  *         USART peripheral.  
+  * @note The Smart Card and Synchronous modes are not available for UART4 and UART5.
+  * @retval None
+  */
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+  uint32_t tmpreg = 0x00;
+  /* Check the parameters */
+  assert_param(IS_USART_123_PERIPH(USARTx));
+  assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock));
+  assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL));
+  assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA));
+  assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit));
+  
+/*---------------------------- USART CR2 Configuration -----------------------*/
+  tmpreg = USARTx->CR2;
+  /* Clear CLKEN, CPOL, CPHA and LBCL bits */
+  tmpreg &= CR2_CLOCK_CLEAR_Mask;
+  /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/
+  /* Set CLKEN bit according to USART_Clock value */
+  /* Set CPOL bit according to USART_CPOL value */
+  /* Set CPHA bit according to USART_CPHA value */
+  /* Set LBCL bit according to USART_LastBit value */
+  tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | 
+                 USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit;
+  /* Write to USART CR2 */
+  USARTx->CR2 = (uint16_t)tmpreg;
+}
+
+/**
+  * @brief  Fills each USART_ClockInitStruct member with its default value.
+  * @param  USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+  *         structure which will be initialized.
+  * @retval None
+  */
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+  /* USART_ClockInitStruct members default value */
+  USART_ClockInitStruct->USART_Clock = USART_Clock_Disable;
+  USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low;
+  USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge;
+  USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable;
+}
+
+/**
+  * @brief  Enables or disables the specified USART peripheral.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *         This parameter can be one of the following values:
+  *           USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USARTx peripheral.
+  *         This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the selected USART by setting the UE bit in the CR1 register */
+    USARTx->CR1 |= CR1_UE_Set;
+  }
+  else
+  {
+    /* Disable the selected USART by clearing the UE bit in the CR1 register */
+    USARTx->CR1 &= CR1_UE_Reset;
+  }
+}
+
+/**
+  * @brief  Enables or disables the specified USART interrupts.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_IT: specifies the USART interrupt sources to be enabled or disabled.
+  *   This parameter can be one of the following values:
+  *     @arg USART_IT_CTS:  CTS change interrupt (not available for UART4 and UART5)
+  *     @arg USART_IT_LBD:  LIN Break detection interrupt
+  *     @arg USART_IT_TXE:  Transmit Data Register empty interrupt
+  *     @arg USART_IT_TC:   Transmission complete interrupt
+  *     @arg USART_IT_RXNE: Receive Data register not empty interrupt
+  *     @arg USART_IT_IDLE: Idle line detection interrupt
+  *     @arg USART_IT_PE:   Parity Error interrupt
+  *     @arg USART_IT_ERR:  Error interrupt(Frame error, noise error, overrun error)
+  * @param  NewState: new state of the specified USARTx interrupts.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
+{
+  uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
+  uint32_t usartxbase = 0x00;
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_CONFIG_IT(USART_IT));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  /* The CTS interrupt is not available for UART4 and UART5 */
+  if (USART_IT == USART_IT_CTS)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  }   
+  
+  usartxbase = (uint32_t)USARTx;
+
+  /* Get the USART register index */
+  usartreg = (((uint8_t)USART_IT) >> 0x05);
+
+  /* Get the interrupt position */
+  itpos = USART_IT & IT_Mask;
+  itmask = (((uint32_t)0x01) << itpos);
+    
+  if (usartreg == 0x01) /* The IT is in CR1 register */
+  {
+    usartxbase += 0x0C;
+  }
+  else if (usartreg == 0x02) /* The IT is in CR2 register */
+  {
+    usartxbase += 0x10;
+  }
+  else /* The IT is in CR3 register */
+  {
+    usartxbase += 0x14; 
+  }
+  if (NewState != DISABLE)
+  {
+    *(__IO uint32_t*)usartxbase  |= itmask;
+  }
+  else
+  {
+    *(__IO uint32_t*)usartxbase &= ~itmask;
+  }
+}
+
+/**
+  * @brief  Enables or disables the USART’s DMA interface.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_DMAReq: specifies the DMA request.
+  *   This parameter can be any combination of the following values:
+  *     @arg USART_DMAReq_Tx: USART DMA transmit request
+  *     @arg USART_DMAReq_Rx: USART DMA receive request
+  * @param  NewState: new state of the DMA Request sources.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @note The DMA mode is not available for UART5 except in the STM32
+  *       High density value line devices(STM32F10X_HD_VL).  
+  * @retval None
+  */
+void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_DMAREQ(USART_DMAReq));  
+  assert_param(IS_FUNCTIONAL_STATE(NewState)); 
+  if (NewState != DISABLE)
+  {
+    /* Enable the DMA transfer for selected requests by setting the DMAT and/or
+       DMAR bits in the USART CR3 register */
+    USARTx->CR3 |= USART_DMAReq;
+  }
+  else
+  {
+    /* Disable the DMA transfer for selected requests by clearing the DMAT and/or
+       DMAR bits in the USART CR3 register */
+    USARTx->CR3 &= (uint16_t)~USART_DMAReq;
+  }
+}
+
+/**
+  * @brief  Sets the address of the USART node.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_Address: Indicates the address of the USART node.
+  * @retval None
+  */
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_ADDRESS(USART_Address)); 
+    
+  /* Clear the USART address */
+  USARTx->CR2 &= CR2_Address_Mask;
+  /* Set the USART address node */
+  USARTx->CR2 |= USART_Address;
+}
+
+/**
+  * @brief  Selects the USART WakeUp method.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_WakeUp: specifies the USART wakeup method.
+  *   This parameter can be one of the following values:
+  *     @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection
+  *     @arg USART_WakeUp_AddressMark: WakeUp by an address mark
+  * @retval None
+  */
+void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_WAKEUP(USART_WakeUp));
+  
+  USARTx->CR1 &= CR1_WAKE_Mask;
+  USARTx->CR1 |= USART_WakeUp;
+}
+
+/**
+  * @brief  Determines if the USART is in mute mode or not.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USART mute mode.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState)); 
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the USART mute mode  by setting the RWU bit in the CR1 register */
+    USARTx->CR1 |= CR1_RWU_Set;
+  }
+  else
+  {
+    /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+    USARTx->CR1 &= CR1_RWU_Reset;
+  }
+}
+
+/**
+  * @brief  Sets the USART LIN Break detection length.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_LINBreakDetectLength: specifies the LIN break detection length.
+  *   This parameter can be one of the following values:
+  *     @arg USART_LINBreakDetectLength_10b: 10-bit break detection
+  *     @arg USART_LINBreakDetectLength_11b: 11-bit break detection
+  * @retval None
+  */
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength));
+  
+  USARTx->CR2 &= CR2_LBDL_Mask;
+  USARTx->CR2 |= USART_LINBreakDetectLength;  
+}
+
+/**
+  * @brief  Enables or disables the USART’s LIN mode.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USART LIN mode.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+    USARTx->CR2 |= CR2_LINEN_Set;
+  }
+  else
+  {
+    /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */
+    USARTx->CR2 &= CR2_LINEN_Reset;
+  }
+}
+
+/**
+  * @brief  Transmits single data through the USARTx peripheral.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  Data: the data to transmit.
+  * @retval None
+  */
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_DATA(Data)); 
+    
+  /* Transmit Data */
+  USARTx->DR = (Data & (uint16_t)0x01FF);
+}
+
+/**
+  * @brief  Returns the most recent received data by the USARTx peripheral.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @retval The received data.
+  */
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  
+  /* Receive Data */
+  return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
+}
+
+/**
+  * @brief  Transmits break characters.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @retval None
+  */
+void USART_SendBreak(USART_TypeDef* USARTx)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  
+  /* Send break characters */
+  USARTx->CR1 |= CR1_SBK_Set;
+}
+
+/**
+  * @brief  Sets the specified USART guard time.
+  * @param  USARTx: where x can be 1, 2 or 3 to select the USART peripheral.
+  * @param  USART_GuardTime: specifies the guard time.
+  * @note The guard time bits are not available for UART4 and UART5.   
+  * @retval None
+  */
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime)
+{    
+  /* Check the parameters */
+  assert_param(IS_USART_123_PERIPH(USARTx));
+  
+  /* Clear the USART Guard time */
+  USARTx->GTPR &= GTPR_LSB_Mask;
+  /* Set the USART guard time */
+  USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08);
+}
+
+/**
+  * @brief  Sets the system clock prescaler.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_Prescaler: specifies the prescaler clock.  
+  * @note   The function is used for IrDA mode with UART4 and UART5.
+  * @retval None
+  */
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler)
+{ 
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  
+  /* Clear the USART prescaler */
+  USARTx->GTPR &= GTPR_MSB_Mask;
+  /* Set the USART prescaler */
+  USARTx->GTPR |= USART_Prescaler;
+}
+
+/**
+  * @brief  Enables or disables the USART’s Smart Card mode.
+  * @param  USARTx: where x can be 1, 2 or 3 to select the USART peripheral.
+  * @param  NewState: new state of the Smart Card mode.
+  *   This parameter can be: ENABLE or DISABLE.     
+  * @note The Smart Card mode is not available for UART4 and UART5. 
+  * @retval None
+  */
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_123_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Enable the SC mode by setting the SCEN bit in the CR3 register */
+    USARTx->CR3 |= CR3_SCEN_Set;
+  }
+  else
+  {
+    /* Disable the SC mode by clearing the SCEN bit in the CR3 register */
+    USARTx->CR3 &= CR3_SCEN_Reset;
+  }
+}
+
+/**
+  * @brief  Enables or disables NACK transmission.
+  * @param  USARTx: where x can be 1, 2 or 3 to select the USART peripheral. 
+  * @param  NewState: new state of the NACK transmission.
+  *   This parameter can be: ENABLE or DISABLE.  
+  * @note The Smart Card mode is not available for UART4 and UART5.
+  * @retval None
+  */
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_123_PERIPH(USARTx));  
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  if (NewState != DISABLE)
+  {
+    /* Enable the NACK transmission by setting the NACK bit in the CR3 register */
+    USARTx->CR3 |= CR3_NACK_Set;
+  }
+  else
+  {
+    /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */
+    USARTx->CR3 &= CR3_NACK_Reset;
+  }
+}
+
+/**
+  * @brief  Enables or disables the USART’s Half Duplex communication.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USART Communication.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+    USARTx->CR3 |= CR3_HDSEL_Set;
+  }
+  else
+  {
+    /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */
+    USARTx->CR3 &= CR3_HDSEL_Reset;
+  }
+}
+
+
+/**
+  * @brief  Enables or disables the USART's 8x oversampling mode.
+  * @param  USARTx: Select the USART or the UART peripheral.
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USART one bit sampling method.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @note
+  *     This function has to be called before calling USART_Init()
+  *     function in order to have correct baudrate Divider value.   
+  * @retval None
+  */
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */
+    USARTx->CR1 |= CR1_OVER8_Set;
+  }
+  else
+  {
+    /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */
+    USARTx->CR1 &= CR1_OVER8_Reset;
+  }
+}
+
+/**
+  * @brief  Enables or disables the USART's one bit sampling method.
+  * @param  USARTx: Select the USART or the UART peripheral.
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the USART one bit sampling method.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */
+    USARTx->CR3 |= CR3_ONEBITE_Set;
+  }
+  else
+  {
+    /* Disable tthe one bit method by clearing the ONEBITE bit in the CR3 register */
+    USARTx->CR3 &= CR3_ONEBITE_Reset;
+  }
+}
+
+/**
+  * @brief  Configures the USART's IrDA interface.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_IrDAMode: specifies the IrDA mode.
+  *   This parameter can be one of the following values:
+  *     @arg USART_IrDAMode_LowPower
+  *     @arg USART_IrDAMode_Normal
+  * @retval None
+  */
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
+    
+  USARTx->CR3 &= CR3_IRLP_Mask;
+  USARTx->CR3 |= USART_IrDAMode;
+}
+
+/**
+  * @brief  Enables or disables the USART's IrDA interface.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  NewState: new state of the IrDA mode.
+  *   This parameter can be: ENABLE or DISABLE.
+  * @retval None
+  */
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_FUNCTIONAL_STATE(NewState));
+    
+  if (NewState != DISABLE)
+  {
+    /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
+    USARTx->CR3 |= CR3_IREN_Set;
+  }
+  else
+  {
+    /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
+    USARTx->CR3 &= CR3_IREN_Reset;
+  }
+}
+
+/**
+  * @brief  Checks whether the specified USART flag is set or not.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_FLAG: specifies the flag to check.
+  *   This parameter can be one of the following values:
+  *     @arg USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5)
+  *     @arg USART_FLAG_LBD:  LIN Break detection flag
+  *     @arg USART_FLAG_TXE:  Transmit data register empty flag
+  *     @arg USART_FLAG_TC:   Transmission Complete flag
+  *     @arg USART_FLAG_RXNE: Receive data register not empty flag
+  *     @arg USART_FLAG_IDLE: Idle Line detection flag
+  *     @arg USART_FLAG_ORE:  OverRun Error flag
+  *     @arg USART_FLAG_NE:   Noise Error flag
+  *     @arg USART_FLAG_FE:   Framing Error flag
+  *     @arg USART_FLAG_PE:   Parity Error flag
+  * @retval The new state of USART_FLAG (SET or RESET).
+  */
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+  FlagStatus bitstatus = RESET;
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_FLAG(USART_FLAG));
+  /* The CTS flag is not available for UART4 and UART5 */
+  if (USART_FLAG == USART_FLAG_CTS)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  }  
+  
+  if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Clears the USARTx's pending flags.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_FLAG: specifies the flag to clear.
+  *   This parameter can be any combination of the following values:
+  *     @arg USART_FLAG_CTS:  CTS Change flag (not available for UART4 and UART5).
+  *     @arg USART_FLAG_LBD:  LIN Break detection flag.
+  *     @arg USART_FLAG_TC:   Transmission Complete flag.
+  *     @arg USART_FLAG_RXNE: Receive data register not empty flag.
+  *   
+  * @note
+  *   - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun 
+  *     error) and IDLE (Idle line detected) flags are cleared by software 
+  *     sequence: a read operation to USART_SR register (USART_GetFlagStatus()) 
+  *     followed by a read operation to USART_DR register (USART_ReceiveData()).
+  *   - RXNE flag can be also cleared by a read to the USART_DR register 
+  *     (USART_ReceiveData()).
+  *   - TC flag can be also cleared by software sequence: a read operation to 
+  *     USART_SR register (USART_GetFlagStatus()) followed by a write operation
+  *     to USART_DR register (USART_SendData()).
+  *   - TXE flag is cleared only by a write to the USART_DR register 
+  *     (USART_SendData()).
+  * @retval None
+  */
+void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
+  /* The CTS flag is not available for UART4 and UART5 */
+  if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  } 
+   
+  USARTx->SR = (uint16_t)~USART_FLAG;
+}
+
+/**
+  * @brief  Checks whether the specified USART interrupt has occurred or not.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_IT: specifies the USART interrupt source to check.
+  *   This parameter can be one of the following values:
+  *     @arg USART_IT_CTS:  CTS change interrupt (not available for UART4 and UART5)
+  *     @arg USART_IT_LBD:  LIN Break detection interrupt
+  *     @arg USART_IT_TXE:  Tansmit Data Register empty interrupt
+  *     @arg USART_IT_TC:   Transmission complete interrupt
+  *     @arg USART_IT_RXNE: Receive Data register not empty interrupt
+  *     @arg USART_IT_IDLE: Idle line detection interrupt
+  *     @arg USART_IT_ORE:  OverRun Error interrupt
+  *     @arg USART_IT_NE:   Noise Error interrupt
+  *     @arg USART_IT_FE:   Framing Error interrupt
+  *     @arg USART_IT_PE:   Parity Error interrupt
+  * @retval The new state of USART_IT (SET or RESET).
+  */
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+  uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
+  ITStatus bitstatus = RESET;
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_GET_IT(USART_IT));
+  /* The CTS interrupt is not available for UART4 and UART5 */ 
+  if (USART_IT == USART_IT_CTS)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  }   
+  
+  /* Get the USART register index */
+  usartreg = (((uint8_t)USART_IT) >> 0x05);
+  /* Get the interrupt position */
+  itmask = USART_IT & IT_Mask;
+  itmask = (uint32_t)0x01 << itmask;
+  
+  if (usartreg == 0x01) /* The IT  is in CR1 register */
+  {
+    itmask &= USARTx->CR1;
+  }
+  else if (usartreg == 0x02) /* The IT  is in CR2 register */
+  {
+    itmask &= USARTx->CR2;
+  }
+  else /* The IT  is in CR3 register */
+  {
+    itmask &= USARTx->CR3;
+  }
+  
+  bitpos = USART_IT >> 0x08;
+  bitpos = (uint32_t)0x01 << bitpos;
+  bitpos &= USARTx->SR;
+  if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
+  {
+    bitstatus = SET;
+  }
+  else
+  {
+    bitstatus = RESET;
+  }
+  
+  return bitstatus;  
+}
+
+/**
+  * @brief  Clears the USARTx's interrupt pending bits.
+  * @param  USARTx: Select the USART or the UART peripheral. 
+  *   This parameter can be one of the following values:
+  *   USART1, USART2, USART3, UART4 or UART5.
+  * @param  USART_IT: specifies the interrupt pending bit to clear.
+  *   This parameter can be one of the following values:
+  *     @arg USART_IT_CTS:  CTS change interrupt (not available for UART4 and UART5)
+  *     @arg USART_IT_LBD:  LIN Break detection interrupt
+  *     @arg USART_IT_TC:   Transmission complete interrupt. 
+  *     @arg USART_IT_RXNE: Receive Data register not empty interrupt.
+  *   
+  * @note
+  *   - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun 
+  *     error) and IDLE (Idle line detected) pending bits are cleared by 
+  *     software sequence: a read operation to USART_SR register 
+  *     (USART_GetITStatus()) followed by a read operation to USART_DR register 
+  *     (USART_ReceiveData()).
+  *   - RXNE pending bit can be also cleared by a read to the USART_DR register 
+  *     (USART_ReceiveData()).
+  *   - TC pending bit can be also cleared by software sequence: a read 
+  *     operation to USART_SR register (USART_GetITStatus()) followed by a write 
+  *     operation to USART_DR register (USART_SendData()).
+  *   - TXE pending bit is cleared only by a write to the USART_DR register 
+  *     (USART_SendData()).
+  * @retval None
+  */
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+  uint16_t bitpos = 0x00, itmask = 0x00;
+  /* Check the parameters */
+  assert_param(IS_USART_ALL_PERIPH(USARTx));
+  assert_param(IS_USART_CLEAR_IT(USART_IT));
+  /* The CTS interrupt is not available for UART4 and UART5 */
+  if (USART_IT == USART_IT_CTS)
+  {
+    assert_param(IS_USART_123_PERIPH(USARTx));
+  }   
+  
+  bitpos = USART_IT >> 0x08;
+  itmask = ((uint16_t)0x01 << (uint16_t)bitpos);
+  USARTx->SR = (uint16_t)~itmask;
+}
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_conf.hh	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,186 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_conf.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Custom HID demo configuration file
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF_H
+#define __USB_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/* EP_NUM */
+/* defines how many endpoints are used by the device */
+/*-------------------------------------------------------------*/
+#define EP_NUM     (2)
+
+#ifndef STM32F10X_CL
+/*-------------------------------------------------------------*/
+/* --------------   Buffer Description Table  -----------------*/
+/*-------------------------------------------------------------*/
+/* buffer table base address */
+/* buffer table base address */
+#define BTABLE_ADDRESS      (0x00)
+
+/* EP0  */
+/* rx/tx buffer base address */
+#define ENDP0_RXADDR        (0x18)
+#define ENDP0_TXADDR        (0x58)
+
+/* EP1  */
+/* tx buffer base address */
+#define ENDP1_TXADDR        (0x100)
+#define ENDP1_RXADDR        (0x104)
+
+/*-------------------------------------------------------------*/
+/* -------------------   ISTR events  -------------------------*/
+/*-------------------------------------------------------------*/
+/* IMR_MSK */
+/* mask defining which events has to be handled */
+/* by the device application software */
+#define IMR_MSK (CNTR_CTRM  | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM  | CNTR_SOFM \
+                 | CNTR_ESOFM | CNTR_RESETM )
+#endif /* STM32F10X_CL */
+
+#ifdef STM32F10X_CL
+
+/*******************************************************************************
+*                              FIFO Size Configuration
+*
+*  (i) Dedicated data FIFO SPRAM of 1.25 Kbytes = 1280 bytes = 320 32-bits words
+*      available for the endpoints IN and OUT.
+*      Device mode features:
+*      -1 bidirectional CTRL EP 0
+*      -3 IN EPs to support any kind of Bulk, Interrupt or Isochronous transfer
+*      -3 OUT EPs to support any kind of Bulk, Interrupt or Isochronous transfer
+*
+*  ii) Receive data FIFO size = RAM for setup packets +
+*                   OUT endpoint control information +
+*                   data OUT packets + miscellaneous
+*      Space = ONE 32-bits words
+*     --> RAM for setup packets = 4 * n + 6 space
+*        (n is the nbr of CTRL EPs the device core supports)
+*     --> OUT EP CTRL info      = 1 space
+*        (one space for status information written to the FIFO along with each
+*        received packet)
+*     --> data OUT packets      = (Largest Packet Size / 4) + 1 spaces
+*        (MINIMUM to receive packets)
+*     --> OR data OUT packets  = at least 2*(Largest Packet Size / 4) + 1 spaces
+*        (if high-bandwidth EP is enabled or multiple isochronous EPs)
+*     --> miscellaneous = 1 space per OUT EP
+*        (one space for transfer complete status information also pushed to the
+*        FIFO with each endpoint's last packet)
+*
+*  (iii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
+*       that particular IN EP. More space allocated in the IN EP Tx FIFO results
+*       in a better performance on the USB and can hide latencies on the AHB.
+*
+*  (iv) TXn min size = 16 words. (n  : Transmit FIFO index)
+*   (v) When a TxFIFO is not used, the Configuration should be as follows:
+*       case 1 :  n > m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txm can use the space allocated for Txn.
+*       case2  :  n < m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txn should be configured with the minimum space of 16 words
+*  (vi) The FIFO is used optimally when used TxFIFOs are allocated in the top
+*       of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+*******************************************************************************/
+
+#define RX_FIFO_SIZE                          128
+#define TX0_FIFO_SIZE                          64
+#define TX1_FIFO_SIZE                          64
+#define TX2_FIFO_SIZE                          16
+#define TX3_FIFO_SIZE                          16
+
+/* OTGD-FS-DEVICE IP interrupts Enable definitions */
+/* Uncomment the define to enable the selected interrupt */
+//#define INTR_MODEMISMATCH
+#define INTR_SOFINTR
+#define INTR_RXSTSQLVL           /* Mandatory */
+//#define INTR_NPTXFEMPTY
+//#define INTR_GINNAKEFF
+//#define INTR_GOUTNAKEFF
+//#define INTR_ERLYSUSPEND
+#define INTR_USBSUSPEND          /* Mandatory */
+#define INTR_USBRESET            /* Mandatory */
+#define INTR_ENUMDONE            /* Mandatory */
+//#define INTR_ISOOUTDROP
+//#define INTR_EOPFRAME
+//#define INTR_EPMISMATCH
+#define INTR_INEPINTR            /* Mandatory */
+#define INTR_OUTEPINTR           /* Mandatory */
+//#define INTR_INCOMPLISOIN
+//#define INTR_INCOMPLISOOUT
+#define INTR_WKUPINTR            /* Mandatory */
+
+/* OTGD-FS-DEVICE IP interrupts subroutines */
+/* Comment the define to enable the selected interrupt subroutine and replace it
+   by user code */
+#define  INTR_MODEMISMATCH_Callback      NOP_Process
+#define  INTR_SOFINTR_Callback           NOP_Process
+#define  INTR_RXSTSQLVL_Callback         NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_GINNAKEFF_Callback         NOP_Process
+#define  INTR_GOUTNAKEFF_Callback        NOP_Process
+#define  INTR_ERLYSUSPEND_Callback       NOP_Process
+#define  INTR_USBSUSPEND_Callback        NOP_Process
+#define  INTR_USBRESET_Callback          NOP_Process
+#define  INTR_ENUMDONE_Callback          NOP_Process
+#define  INTR_ISOOUTDROP_Callback        NOP_Process
+#define  INTR_EOPFRAME_Callback          NOP_Process
+#define  INTR_EPMISMATCH_Callback        NOP_Process
+#define  INTR_INEPINTR_Callback          NOP_Process
+#define  INTR_OUTEPINTR_Callback         NOP_Process
+#define  INTR_INCOMPLISOIN_Callback      NOP_Process
+#define  INTR_INCOMPLISOOUT_Callback     NOP_Process
+#define  INTR_WKUPINTR_Callback          NOP_Process
+
+/* Isochronous data update */
+#define  INTR_RXSTSQLVL_ISODU_Callback   NOP_Process
+
+/* Isochronous transfer parameters */
+/* Size of a single Isochronous buffer (size of a single transfer) */
+#define ISOC_BUFFER_SZE                  1
+/* Number of sub-buffers (number of single buffers/transfers), should be even */
+#define NUM_SUB_BUFFERS                  2
+
+#endif /* STM32F10X_CL */
+
+
+/* CTR service routines */
+/* associated to defined endpoints */
+#define  EP1_IN_Callback   NOP_Process
+#define  EP2_IN_Callback   NOP_Process
+#define  EP3_IN_Callback   NOP_Process
+#define  EP4_IN_Callback   NOP_Process
+#define  EP5_IN_Callback   NOP_Process
+#define  EP6_IN_Callback   NOP_Process
+#define  EP7_IN_Callback   NOP_Process
+
+//#define  EP1_OUT_Callback   NOP_Process
+#define  EP2_OUT_Callback   NOP_Process
+#define  EP3_OUT_Callback   NOP_Process
+#define  EP4_OUT_Callback   NOP_Process
+#define  EP5_OUT_Callback   NOP_Process
+#define  EP6_OUT_Callback   NOP_Process
+#define  EP7_OUT_Callback   NOP_Process
+
+#endif /*__USB_CONF_H*/
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_core.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,246 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_core.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Standard protocol processing functions prototypes
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CORE_H
+#define __USB_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _CONTROL_STATE
+{
+  WAIT_SETUP,       /* 0 */
+  SETTING_UP,       /* 1 */
+  IN_DATA,          /* 2 */
+  OUT_DATA,         /* 3 */
+  LAST_IN_DATA,     /* 4 */
+  LAST_OUT_DATA,    /* 5 */
+  WAIT_STATUS_IN,   /* 7 */
+  WAIT_STATUS_OUT,  /* 8 */
+  STALLED,          /* 9 */
+  PAUSE             /* 10 */
+} CONTROL_STATE;    /* The state machine states of a control pipe */
+
+typedef struct OneDescriptor
+{
+  uint8_t *Descriptor;
+  uint16_t Descriptor_Size;
+}
+ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
+/* All the request process routines return a value of this type
+   If the return value is not SUCCESS or NOT_READY,
+   the software will STALL the correspond endpoint */
+typedef enum _RESULT
+{
+  USB_SUCCESS = 0,    /* Process sucessfully */
+  USB_ERROR,
+  USB_UNSUPPORT,
+  USB_NOT_READY       /* The process has not been finished, endpoint will be
+                         NAK to further rquest */
+} RESULT;
+
+
+/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
+typedef struct _ENDPOINT_INFO
+{
+  /* When send data out of the device,
+   CopyData() is used to get data buffer 'Length' bytes data
+   if Length is 0,
+    CopyData() returns the total length of the data
+    if the request is not supported, returns 0
+    (NEW Feature )
+     if CopyData() returns -1, the calling routine should not proceed
+     further and will resume the SETUP process by the class device
+   if Length is not 0,
+    CopyData() returns a pointer to indicate the data location
+   Usb_wLength is the data remain to be sent,
+   Usb_wOffset is the Offset of original data
+  When receive data from the host,
+   CopyData() is used to get user data buffer which is capable
+   of Length bytes data to copy data from the endpoint buffer.
+   if Length is 0,
+    CopyData() returns the available data length,
+   if Length is not 0,
+    CopyData() returns user buffer address
+   Usb_rLength is the data remain to be received,
+   Usb_rPointer is the Offset of data buffer
+  */
+  uint16_t  Usb_wLength;
+  uint16_t  Usb_wOffset;
+  uint16_t  PacketSize;
+  uint8_t   *(*CopyData)(uint16_t Length);
+}ENDPOINT_INFO;
+
+/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
+
+typedef struct _DEVICE
+{
+  uint8_t Total_Endpoint;     /* Number of endpoints that are used */
+  uint8_t Total_Configuration;/* Number of configuration available */
+}
+DEVICE;
+
+typedef union
+{
+  uint16_t w;
+  struct BW
+  {
+    uint8_t bb1;
+    uint8_t bb0;
+  }
+  bw;
+} uint16_t_uint8_t;
+
+typedef struct _DEVICE_INFO
+{
+  uint8_t USBbmRequestType;       /* bmRequestType */
+  uint8_t USBbRequest;            /* bRequest */
+  uint16_t_uint8_t USBwValues;         /* wValue */
+  uint16_t_uint8_t USBwIndexs;         /* wIndex */
+  uint16_t_uint8_t USBwLengths;        /* wLength */
+
+  uint8_t ControlState;           /* of type CONTROL_STATE */
+  uint8_t Current_Feature;
+  uint8_t Current_Configuration;   /* Selected configuration */
+  uint8_t Current_Interface;       /* Selected interface of current configuration */
+  uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
+                                     interface*/
+
+  ENDPOINT_INFO Ctrl_Info;
+}DEVICE_INFO;
+
+typedef struct _DEVICE_PROP
+{
+  void (*Init)(void);        /* Initialize the device */
+  void (*Reset)(void);       /* Reset routine of this device */
+
+  /* Device dependent process after the status stage */
+  void (*Process_Status_IN)(void);
+  void (*Process_Status_OUT)(void);
+
+  /* Procedure of process on setup stage of a class specified request with data stage */
+  /* All class specified requests with data stage are processed in Class_Data_Setup
+   Class_Data_Setup()
+    responses to check all special requests and fills ENDPOINT_INFO
+    according to the request
+    If IN tokens are expected, then wLength & wOffset will be filled
+    with the total transferring bytes and the starting position
+    If OUT tokens are expected, then rLength & rOffset will be filled
+    with the total expected bytes and the starting position in the buffer
+
+    If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
+
+   CAUTION:
+    Since GET_CONFIGURATION & GET_INTERFACE are highly related to
+    the individual classes, they will be checked and processed here.
+  */
+  RESULT (*Class_Data_Setup)(uint8_t RequestNo);
+
+  /* Procedure of process on setup stage of a class specified request without data stage */
+  /* All class specified requests without data stage are processed in Class_NoData_Setup
+   Class_NoData_Setup
+    responses to check all special requests and perform the request
+
+   CAUTION:
+    Since SET_CONFIGURATION & SET_INTERFACE are highly related to
+    the individual classes, they will be checked and processed here.
+  */
+  RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
+
+  /*Class_Get_Interface_Setting
+   This function is used by the file usb_core.c to test if the selected Interface
+   and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
+   the application.
+   This function is writing by user. It should return "SUCCESS" if the Interface
+   and Alternate Setting are supported by the application or "UNSUPPORT" if they
+   are not supported. */
+
+  RESULT  (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
+
+  uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
+  uint8_t* (*GetConfigDescriptor)(uint16_t Length);
+  uint8_t* (*GetStringDescriptor)(uint16_t Length);
+
+  /* This field is not used in current library version. It is kept only for 
+   compatibility with previous versions */
+  void* RxEP_buffer;
+   
+  uint8_t MaxPacketSize;
+
+}DEVICE_PROP;
+
+typedef struct _USER_STANDARD_REQUESTS
+{
+  void (*User_GetConfiguration)(void);       /* Get Configuration */
+  void (*User_SetConfiguration)(void);       /* Set Configuration */
+  void (*User_GetInterface)(void);           /* Get Interface */
+  void (*User_SetInterface)(void);           /* Set Interface */
+  void (*User_GetStatus)(void);              /* Get Status */
+  void (*User_ClearFeature)(void);           /* Clear Feature */
+  void (*User_SetEndPointFeature)(void);     /* Set Endpoint Feature */
+  void (*User_SetDeviceFeature)(void);       /* Set Device Feature */
+  void (*User_SetDeviceAddress)(void);       /* Set Device Address */
+}
+USER_STANDARD_REQUESTS;
+
+/* Exported constants --------------------------------------------------------*/
+#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
+
+#define Usb_rLength Usb_wLength
+#define Usb_rOffset Usb_wOffset
+
+#define USBwValue USBwValues.w
+#define USBwValue0 USBwValues.bw.bb0
+#define USBwValue1 USBwValues.bw.bb1
+#define USBwIndex USBwIndexs.w
+#define USBwIndex0 USBwIndexs.bw.bb0
+#define USBwIndex1 USBwIndexs.bw.bb1
+#define USBwLength USBwLengths.w
+#define USBwLength0 USBwLengths.bw.bb0
+#define USBwLength1 USBwLengths.bw.bb1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+uint8_t Setup0_Process(void);
+uint8_t Post0_Process(void);
+uint8_t Out0_Process(void);
+uint8_t In0_Process(void);
+
+RESULT Standard_SetEndPointFeature(void);
+RESULT Standard_SetDeviceFeature(void);
+
+uint8_t *Standard_GetConfiguration(uint16_t Length);
+RESULT Standard_SetConfiguration(void);
+uint8_t *Standard_GetInterface(uint16_t Length);
+RESULT Standard_SetInterface(void);
+uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc);
+
+uint8_t *Standard_GetStatus(uint16_t Length);
+RESULT Standard_ClearFeature(void);
+void SetDeviceAddress(uint8_t);
+void NOP_Process(void);
+
+extern DEVICE_PROP Device_Property;
+extern  USER_STANDARD_REQUESTS User_Standard_Requests;
+extern  DEVICE  Device_Table;
+extern DEVICE_INFO Device_Info;
+
+/* cells saving status during interrupt servicing */
+extern __IO uint16_t SaveRState;
+extern __IO uint16_t SaveTState;
+
+#endif /* __USB_CORE_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_def.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,80 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_def.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Definitions related to USB Core
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DEF_H
+#define __USB_DEF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _RECIPIENT_TYPE
+{
+  DEVICE_RECIPIENT,     /* Recipient device */
+  INTERFACE_RECIPIENT,  /* Recipient interface */
+  ENDPOINT_RECIPIENT,   /* Recipient endpoint */
+  OTHER_RECIPIENT
+} RECIPIENT_TYPE;
+
+
+typedef enum _STANDARD_REQUESTS
+{
+  GET_STATUS = 0,
+  CLEAR_FEATURE,
+  RESERVED1,
+  SET_FEATURE,
+  RESERVED2,
+  SET_ADDRESS,
+  GET_DESCRIPTOR,
+  SET_DESCRIPTOR,
+  GET_CONFIGURATION,
+  SET_CONFIGURATION,
+  GET_INTERFACE,
+  SET_INTERFACE,
+  TOTAL_sREQUEST,  /* Total number of Standard request */
+  SYNCH_FRAME = 12
+} STANDARD_REQUESTS;
+
+/* Definition of "USBwValue" */
+typedef enum _DESCRIPTOR_TYPE
+{
+  DEVICE_DESCRIPTOR = 1,
+  CONFIG_DESCRIPTOR,
+  STRING_DESCRIPTOR,
+  INTERFACE_DESCRIPTOR,
+  ENDPOINT_DESCRIPTOR
+} DESCRIPTOR_TYPE;
+
+/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
+typedef enum _FEATURE_SELECTOR
+{
+  ENDPOINT_STALL,
+  DEVICE_REMOTE_WAKEUP
+} FEATURE_SELECTOR;
+
+/* Exported constants --------------------------------------------------------*/
+/* Definition of "USBbmRequestType" */
+#define REQUEST_TYPE      0x60  /* Mask to get request type */
+#define STANDARD_REQUEST  0x00  /* Standard request */
+#define CLASS_REQUEST     0x20  /* Class request */
+#define VENDOR_REQUEST    0x40  /* Vendor request */
+
+#define RECIPIENT         0x1F  /* Mask to get recipient */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __USB_DEF_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_init.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,49 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_init.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Initialization routines & global variables
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_INIT_H
+#define __USB_INIT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void USB_Init(void);
+
+/* External variables --------------------------------------------------------*/
+/*  The number of current endpoint, it will be used to specify an endpoint */
+extern uint8_t	EPindex;
+/*  The number of current device, it is an index to the Device_Table */
+/*extern uint8_t	Device_no; */
+/*  Points to the DEVICE_INFO structure of current device */
+/*  The purpose of this register is to speed up the execution */
+extern DEVICE_INFO*	pInformation;
+/*  Points to the DEVICE_PROP structure of current device */
+/*  The purpose of this register is to speed up the execution */
+extern DEVICE_PROP*	pProperty;
+/*  Temporary save the state of Rx & Tx status. */
+/*  Whenever the Rx or Tx state is changed, its value is saved */
+/*  in this variable first and will be set to the EPRB or EPRA */
+/*  at the end of interrupt process */
+extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
+
+extern uint16_t	SaveState ;
+extern uint16_t wInterrupt_Mask;
+
+#endif /* __USB_INIT_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_int.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,33 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_int.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Endpoint CTR (Low and High) interrupt's service routines
+*                      prototypes
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_INT_H
+#define __USB_INT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void CTR_LP(void);
+void CTR_HP(void);
+
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_INT_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_lib.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,50 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_lib.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : USB library include files
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_LIB_H
+#define __USB_LIB_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_type.h"
+#include "usb_regs.h"
+#include "usb_def.h"
+#include "usb_core.h"
+#include "usb_init.h"
+#ifndef STM32F10X_CL
+ #include "usb_mem.h"
+ #include "usb_int.h"
+#endif /* STM32F10X_CL */
+
+#include "usb_sil.h"
+
+#ifdef STM32F10X_CL
+ #include "otgd_fs_cal.h"
+ #include "otgd_fs_pcd.h"
+ #include "otgd_fs_dev.h"
+ #include "otgd_fs_int.h"
+#endif /* STM32F10X_CL */
+
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_LIB_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_mem.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,32 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_mem.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Utility prototypes functions for memory/PMA transfers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_MEM_H
+#define __USB_MEM_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+
+/* External variables --------------------------------------------------------*/
+
+#endif  /*__USB_MEM_H*/
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_regs.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,671 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_regs.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Interface prototype functions to USB cell registers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_REGS_H
+#define __USB_REGS_H
+
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _EP_DBUF_DIR
+{
+  /* double buffered endpoint direction */
+  EP_DBUF_ERR,
+  EP_DBUF_OUT,
+  EP_DBUF_IN
+}EP_DBUF_DIR;
+
+/* endpoint buffer number */
+enum EP_BUF_NUM
+{
+  EP_NOBUF,
+  EP_BUF0,
+  EP_BUF1
+};
+
+/* Exported constants --------------------------------------------------------*/
+#define RegBase  (0x40005C00L)  /* USB_IP Peripheral Registers base address */
+#define PMAAddr  (0x40006000L)  /* USB_IP Packet Memory Area base address   */
+
+/******************************************************************************/
+/*                         General registers                                  */
+/******************************************************************************/
+
+/* Control register */
+#define CNTR    ((__IO unsigned *)(RegBase + 0x40))
+/* Interrupt status register */
+#define ISTR    ((__IO unsigned *)(RegBase + 0x44))
+/* Frame number register */
+#define FNR     ((__IO unsigned *)(RegBase + 0x48))
+/* Device address register */
+#define DADDR   ((__IO unsigned *)(RegBase + 0x4C))
+/* Buffer Table address register */
+#define BTABLE  ((__IO unsigned *)(RegBase + 0x50))
+/******************************************************************************/
+/*                         Endpoint registers                                 */
+/******************************************************************************/
+#define EP0REG  ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */
+
+/* Endpoint Addresses (w/direction) */
+#define EP0_OUT     ((uint8_t)0x00)  
+#define EP0_IN      ((uint8_t)0x80) 
+#define EP1_OUT     ((uint8_t)0x01)  
+#define EP1_IN      ((uint8_t)0x81)  
+#define EP2_OUT     ((uint8_t)0x02)  
+#define EP2_IN      ((uint8_t)0x82)  
+#define EP3_OUT     ((uint8_t)0x03)  
+#define EP3_IN      ((uint8_t)0x83) 
+#define EP4_OUT     ((uint8_t)0x04)  
+#define EP4_IN      ((uint8_t)0x84)
+#define EP5_OUT     ((uint8_t)0x05)  
+#define EP5_IN      ((uint8_t)0x85)
+#define EP6_OUT     ((uint8_t)0x06)  
+#define EP6_IN      ((uint8_t)0x86)
+#define EP7_OUT     ((uint8_t)0x07)  
+#define EP7_IN      ((uint8_t)0x87)
+
+/* endpoints enumeration */
+#define ENDP0       ((uint8_t)0)
+#define ENDP1       ((uint8_t)1)
+#define ENDP2       ((uint8_t)2)
+#define ENDP3       ((uint8_t)3)
+#define ENDP4       ((uint8_t)4)
+#define ENDP5       ((uint8_t)5)
+#define ENDP6       ((uint8_t)6)
+#define ENDP7       ((uint8_t)7)
+
+/******************************************************************************/
+/*                       ISTR interrupt events                                */
+/******************************************************************************/
+#define ISTR_CTR    (0x8000) /* Correct TRansfer (clear-only bit) */
+#define ISTR_DOVR   (0x4000) /* DMA OVeR/underrun (clear-only bit) */
+#define ISTR_ERR    (0x2000) /* ERRor (clear-only bit) */
+#define ISTR_WKUP   (0x1000) /* WaKe UP (clear-only bit) */
+#define ISTR_SUSP   (0x0800) /* SUSPend (clear-only bit) */
+#define ISTR_RESET  (0x0400) /* RESET (clear-only bit) */
+#define ISTR_SOF    (0x0200) /* Start Of Frame (clear-only bit) */
+#define ISTR_ESOF   (0x0100) /* Expected Start Of Frame (clear-only bit) */
+
+
+#define ISTR_DIR    (0x0010)  /* DIRection of transaction (read-only bit)  */
+#define ISTR_EP_ID  (0x000F)  /* EndPoint IDentifier (read-only bit)  */
+
+#define CLR_CTR    (~ISTR_CTR)   /* clear Correct TRansfer bit */
+#define CLR_DOVR   (~ISTR_DOVR)  /* clear DMA OVeR/underrun bit*/
+#define CLR_ERR    (~ISTR_ERR)   /* clear ERRor bit */
+#define CLR_WKUP   (~ISTR_WKUP)  /* clear WaKe UP bit     */
+#define CLR_SUSP   (~ISTR_SUSP)  /* clear SUSPend bit     */
+#define CLR_RESET  (~ISTR_RESET) /* clear RESET bit      */
+#define CLR_SOF    (~ISTR_SOF)   /* clear Start Of Frame bit   */
+#define CLR_ESOF   (~ISTR_ESOF)  /* clear Expected Start Of Frame bit */
+
+/******************************************************************************/
+/*             CNTR control register bits definitions                         */
+/******************************************************************************/
+#define CNTR_CTRM   (0x8000) /* Correct TRansfer Mask */
+#define CNTR_DOVRM  (0x4000) /* DMA OVeR/underrun Mask */
+#define CNTR_ERRM   (0x2000) /* ERRor Mask */
+#define CNTR_WKUPM  (0x1000) /* WaKe UP Mask */
+#define CNTR_SUSPM  (0x0800) /* SUSPend Mask */
+#define CNTR_RESETM (0x0400) /* RESET Mask   */
+#define CNTR_SOFM   (0x0200) /* Start Of Frame Mask */
+#define CNTR_ESOFM  (0x0100) /* Expected Start Of Frame Mask */
+
+
+#define CNTR_RESUME (0x0010) /* RESUME request */
+#define CNTR_FSUSP  (0x0008) /* Force SUSPend */
+#define CNTR_LPMODE (0x0004) /* Low-power MODE */
+#define CNTR_PDWN   (0x0002) /* Power DoWN */
+#define CNTR_FRES   (0x0001) /* Force USB RESet */
+
+/******************************************************************************/
+/*                FNR Frame Number Register bit definitions                   */
+/******************************************************************************/
+#define FNR_RXDP (0x8000) /* status of D+ data line */
+#define FNR_RXDM (0x4000) /* status of D- data line */
+#define FNR_LCK  (0x2000) /* LoCKed */
+#define FNR_LSOF (0x1800) /* Lost SOF */
+#define FNR_FN  (0x07FF) /* Frame Number */
+/******************************************************************************/
+/*               DADDR Device ADDRess bit definitions                         */
+/******************************************************************************/
+#define DADDR_EF (0x80)
+#define DADDR_ADD (0x7F)
+/******************************************************************************/
+/*                            Endpoint register                               */
+/******************************************************************************/
+/* bit positions */
+#define EP_CTR_RX      (0x8000) /* EndPoint Correct TRansfer RX */
+#define EP_DTOG_RX     (0x4000) /* EndPoint Data TOGGLE RX */
+#define EPRX_STAT      (0x3000) /* EndPoint RX STATus bit field */
+#define EP_SETUP       (0x0800) /* EndPoint SETUP */
+#define EP_T_FIELD     (0x0600) /* EndPoint TYPE */
+#define EP_KIND        (0x0100) /* EndPoint KIND */
+#define EP_CTR_TX      (0x0080) /* EndPoint Correct TRansfer TX */
+#define EP_DTOG_TX     (0x0040) /* EndPoint Data TOGGLE TX */
+#define EPTX_STAT      (0x0030) /* EndPoint TX STATus bit field */
+#define EPADDR_FIELD   (0x000F) /* EndPoint ADDRess FIELD */
+
+/* EndPoint REGister MASK (no toggle fields) */
+#define EPREG_MASK     (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
+
+/* EP_TYPE[1:0] EndPoint TYPE */
+#define EP_TYPE_MASK   (0x0600) /* EndPoint TYPE Mask */
+#define EP_BULK        (0x0000) /* EndPoint BULK */
+#define EP_CONTROL     (0x0200) /* EndPoint CONTROL */
+#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
+#define EP_INTERRUPT   (0x0600) /* EndPoint INTERRUPT */
+#define EP_T_MASK      (~EP_T_FIELD & EPREG_MASK)
+
+
+/* EP_KIND EndPoint KIND */
+#define EPKIND_MASK    (~EP_KIND & EPREG_MASK)
+
+/* STAT_TX[1:0] STATus for TX transfer */
+#define EP_TX_DIS      (0x0000) /* EndPoint TX DISabled */
+#define EP_TX_STALL    (0x0010) /* EndPoint TX STALLed */
+#define EP_TX_NAK      (0x0020) /* EndPoint TX NAKed */
+#define EP_TX_VALID    (0x0030) /* EndPoint TX VALID */
+#define EPTX_DTOG1     (0x0010) /* EndPoint TX Data TOGgle bit1 */
+#define EPTX_DTOG2     (0x0020) /* EndPoint TX Data TOGgle bit2 */
+#define EPTX_DTOGMASK  (EPTX_STAT|EPREG_MASK)
+
+/* STAT_RX[1:0] STATus for RX transfer */
+#define EP_RX_DIS      (0x0000) /* EndPoint RX DISabled */
+#define EP_RX_STALL    (0x1000) /* EndPoint RX STALLed */
+#define EP_RX_NAK      (0x2000) /* EndPoint RX NAKed */
+#define EP_RX_VALID    (0x3000) /* EndPoint RX VALID */
+#define EPRX_DTOG1     (0x1000) /* EndPoint RX Data TOGgle bit1 */
+#define EPRX_DTOG2     (0x2000) /* EndPoint RX Data TOGgle bit1 */
+#define EPRX_DTOGMASK  (EPRX_STAT|EPREG_MASK)
+/* Exported macro ------------------------------------------------------------*/
+/* SetCNTR */
+#define _SetCNTR(wRegValue)  (*CNTR   = (uint16_t)wRegValue)
+
+/* SetISTR */
+#define _SetISTR(wRegValue)  (*ISTR   = (uint16_t)wRegValue)
+
+/* SetDADDR */
+#define _SetDADDR(wRegValue) (*DADDR  = (uint16_t)wRegValue)
+
+/* SetBTABLE */
+#define _SetBTABLE(wRegValue)(*BTABLE = (uint16_t)(wRegValue & 0xFFF8))
+
+/* GetCNTR */
+#define _GetCNTR()   ((uint16_t) *CNTR)
+
+/* GetISTR */
+#define _GetISTR()   ((uint16_t) *ISTR)
+
+/* GetFNR */
+#define _GetFNR()    ((uint16_t) *FNR)
+
+/* GetDADDR */
+#define _GetDADDR()  ((uint16_t) *DADDR)
+
+/* GetBTABLE */
+#define _GetBTABLE() ((uint16_t) *BTABLE)
+
+/* SetENDPOINT */
+#define _SetENDPOINT(bEpNum,wRegValue)  (*(EP0REG + bEpNum)= \
+    (uint16_t)wRegValue)
+
+/* GetENDPOINT */
+#define _GetENDPOINT(bEpNum)        ((uint16_t)(*(EP0REG + bEpNum)))
+
+/*******************************************************************************
+* Macro Name     : SetEPType
+* Description    : sets the type in the endpoint register(bits EP_TYPE[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wType											 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
+                                  ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType )))
+
+/*******************************************************************************
+* Macro Name     : GetEPType
+* Description    : gets the type in the endpoint register(bits EP_TYPE[1:0]) 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint Type
+*******************************************************************************/
+#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
+
+/*******************************************************************************
+* Macro Name     : SetEPTxStatus
+* Description    : sets the status for tx transfer (bits STAT_TX[1:0]).
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxStatus(bEpNum,wState) {\
+    register uint16_t _wRegVal;       \
+    _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
+    /* toggle first bit ? */     \
+    if((EPTX_DTOG1 & wState)!= 0)      \
+      _wRegVal ^= EPTX_DTOG1;        \
+    /* toggle second bit ?  */         \
+    if((EPTX_DTOG2 & wState)!= 0)      \
+      _wRegVal ^= EPTX_DTOG2;        \
+    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX));    \
+  } /* _SetEPTxStatus */
+
+/*******************************************************************************
+* Macro Name     : SetEPRxStatus
+* Description    : sets the status for rx transfer (bits STAT_TX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPRxStatus(bEpNum,wState) {\
+    register uint16_t _wRegVal;   \
+    \
+    _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
+    /* toggle first bit ? */  \
+    if((EPRX_DTOG1 & wState)!= 0) \
+      _wRegVal ^= EPRX_DTOG1;  \
+    /* toggle second bit ? */  \
+    if((EPRX_DTOG2 & wState)!= 0) \
+      _wRegVal ^= EPRX_DTOG2;  \
+    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \
+  } /* _SetEPRxStatus */
+
+/*******************************************************************************
+* Macro Name     : SetEPRxTxStatus
+* Description    : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wStaterx: new state.
+*                  wStatetx: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\
+    register uint32_t _wRegVal;   \
+    \
+    _wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EPTX_STAT) ;\
+    /* toggle first bit ? */  \
+    if((EPRX_DTOG1 & wStaterx)!= 0) \
+      _wRegVal ^= EPRX_DTOG1;  \
+    /* toggle second bit ? */  \
+    if((EPRX_DTOG2 & wStaterx)!= 0) \
+      _wRegVal ^= EPRX_DTOG2;  \
+    /* toggle first bit ? */     \
+    if((EPTX_DTOG1 & wStatetx)!= 0)      \
+      _wRegVal ^= EPTX_DTOG1;        \
+    /* toggle second bit ?  */         \
+    if((EPTX_DTOG2 & wStatetx)!= 0)      \
+      _wRegVal ^= EPTX_DTOG2;        \
+    _SetENDPOINT(bEpNum, _wRegVal | EP_CTR_RX|EP_CTR_TX);    \
+  } /* _SetEPRxTxStatus */
+/*******************************************************************************
+* Macro Name     : GetEPTxStatus / GetEPRxStatus 
+* Description    : gets the status for tx/rx transfer (bits STAT_TX[1:0]
+*                  /STAT_RX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : status .
+*******************************************************************************/
+#define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPTX_STAT)
+
+#define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPRX_STAT)
+
+/*******************************************************************************
+* Macro Name     : SetEPTxValid / SetEPRxValid 
+* Description    : sets directly the VALID tx/rx-status into the enpoint register
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxValid(bEpNum)     (_SetEPTxStatus(bEpNum, EP_TX_VALID))
+
+#define _SetEPRxValid(bEpNum)     (_SetEPRxStatus(bEpNum, EP_RX_VALID))
+
+/*******************************************************************************
+* Macro Name     : GetTxStallStatus / GetRxStallStatus.
+* Description    : checks stall condition in an endpoint.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : TRUE = endpoint in stall condition.
+*******************************************************************************/
+#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
+                                   == EP_TX_STALL)
+#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
+                                   == EP_RX_STALL)
+
+/*******************************************************************************
+* Macro Name     : SetEP_KIND / ClearEP_KIND.
+* Description    : set & clear EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEP_KIND(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                (EP_CTR_RX|EP_CTR_TX|((_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK))))
+#define _ClearEP_KIND(bEpNum)  (_SetENDPOINT(bEpNum, \
+                                (EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK))))
+
+/*******************************************************************************
+* Macro Name     : Set_Status_Out / Clear_Status_Out.
+* Description    : Sets/clears directly STATUS_OUT bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _Set_Status_Out(bEpNum)    _SetEP_KIND(bEpNum)
+#define _Clear_Status_Out(bEpNum)  _ClearEP_KIND(bEpNum)
+
+/*******************************************************************************
+* Macro Name     : SetEPDoubleBuff / ClearEPDoubleBuff.
+* Description    : Sets/clears directly EP_KIND bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDoubleBuff(bEpNum)   _SetEP_KIND(bEpNum)
+#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum)
+
+/*******************************************************************************
+* Macro Name     : ClearEP_CTR_RX / ClearEP_CTR_TX.
+* Description    : Clears bit CTR_RX / CTR_TX in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ClearEP_CTR_RX(bEpNum)   (_SetENDPOINT(bEpNum,\
+                                   _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
+#define _ClearEP_CTR_TX(bEpNum)   (_SetENDPOINT(bEpNum,\
+                                   _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
+
+/*******************************************************************************
+* Macro Name     : ToggleDTOG_RX / ToggleDTOG_TX .
+* Description    : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ToggleDTOG_RX(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                   EP_CTR_RX|EP_CTR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
+#define _ToggleDTOG_TX(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                   EP_CTR_RX|EP_CTR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
+
+/*******************************************************************************
+* Macro Name     : ClearDTOG_RX / ClearDTOG_TX.
+* Description    : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ClearDTOG_RX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
+    _ToggleDTOG_RX(bEpNum)
+#define _ClearDTOG_TX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
+    _ToggleDTOG_TX(bEpNum)
+/*******************************************************************************
+* Macro Name     : SetEPAddress.
+* Description    : Sets address in an endpoint register.
+* Input          : bEpNum: Endpoint Number.
+*                  bAddr: Address. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
+    EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
+
+/*******************************************************************************
+* Macro Name     : GetEPAddress.
+* Description    : Gets address in an endpoint register.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADDR_FIELD))
+
+#define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8  )*2 + PMAAddr))
+#define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr))
+#define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
+#define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr))
+
+/*******************************************************************************
+* Macro Name     : SetEPTxAddr / SetEPRxAddr.
+* Description    : sets address of the tx/rx buffer.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: address to be set (must be word aligned).
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
+#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
+
+/*******************************************************************************
+* Macro Name     : GetEPTxAddr / GetEPRxAddr.
+* Description    : Gets address of the tx/rx buffer.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : address of the buffer.
+*******************************************************************************/
+#define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum))
+#define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum))
+
+/*******************************************************************************
+* Macro Name     : SetEPCountRxReg.
+* Description    : Sets counter of rx buffer with no. of blocks.
+* Input          : pdwReg: pointer to counter.
+*                  wCount: Counter.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
+    wNBlocks = wCount >> 5;\
+    if((wCount & 0x1f) == 0)\
+      wNBlocks--;\
+    *pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\
+  }/* _BlocksOf32 */
+
+#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
+    wNBlocks = wCount >> 1;\
+    if((wCount & 0x1) != 0)\
+      wNBlocks++;\
+    *pdwReg = (uint32_t)(wNBlocks << 10);\
+  }/* _BlocksOf2 */
+
+#define _SetEPCountRxReg(dwReg,wCount)  {\
+    uint16_t wNBlocks;\
+    if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
+    else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
+  }/* _SetEPCountRxReg */
+
+
+
+#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
+    uint32_t *pdwReg = _pEPTxCount(bEpNum); \
+    _SetEPCountRxReg(pdwReg, wCount);\
+  }
+/*******************************************************************************
+* Macro Name     : SetEPTxCount / SetEPRxCount.
+* Description    : sets counter for the tx/rx buffer.
+* Input          : bEpNum: endpoint number.
+*                  wCount: Counter value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
+#define _SetEPRxCount(bEpNum,wCount) {\
+    uint32_t *pdwReg = _pEPRxCount(bEpNum); \
+    _SetEPCountRxReg(pdwReg, wCount);\
+  }
+/*******************************************************************************
+* Macro Name     : GetEPTxCount / GetEPRxCount.
+* Description    : gets counter of the tx buffer.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : Counter value.
+*******************************************************************************/
+#define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff)
+#define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff)
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
+* Description    : Sets buffer 0/1 address in a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : wBuf0Addr: buffer 0 address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
+#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuffAddr.
+* Description    : Sets addresses in a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : wBuf0Addr: buffer 0 address.
+*                : wBuf1Addr = buffer 1 address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
+    _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
+    _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
+  } /* _SetEPDblBuffAddr */
+
+/*******************************************************************************
+* Macro Name     : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
+* Description    : Gets buffer 0/1 address of a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
+#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
+* Description    : Gets buffer 0/1 address of a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : bDir: endpoint dir  EP_DBUF_OUT = OUT 
+*                                      EP_DBUF_IN  = IN 
+*                : wCount: Counter value    
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuf0Count(bEpNum, bDir, wCount)  { \
+    if(bDir == EP_DBUF_OUT)\
+      /* OUT endpoint */ \
+    {_SetEPRxDblBuf0Count(bEpNum,wCount);} \
+    else if(bDir == EP_DBUF_IN)\
+      /* IN endpoint */ \
+      *_pEPTxCount(bEpNum) = (uint32_t)wCount;  \
+  } /* SetEPDblBuf0Count*/
+
+#define _SetEPDblBuf1Count(bEpNum, bDir, wCount)  { \
+    if(bDir == EP_DBUF_OUT)\
+      /* OUT endpoint */ \
+    {_SetEPRxCount(bEpNum,wCount);}\
+    else if(bDir == EP_DBUF_IN)\
+      /* IN endpoint */\
+      *_pEPRxCount(bEpNum) = (uint32_t)wCount; \
+  } /* SetEPDblBuf1Count */
+
+#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
+    _SetEPDblBuf0Count(bEpNum, bDir, wCount); \
+    _SetEPDblBuf1Count(bEpNum, bDir, wCount); \
+  } /* _SetEPDblBuffCount  */
+
+/*******************************************************************************
+* Macro Name     : GetEPDblBuf0Count / GetEPDblBuf1Count.
+* Description    : Gets buffer 0/1 rx/tx counter for double buffering.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
+#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
+
+
+/* External variables --------------------------------------------------------*/
+extern __IO uint16_t wIstr;  /* ISTR register last read value */
+
+/* Exported functions ------------------------------------------------------- */
+void SetCNTR(uint16_t /*wRegValue*/);
+void SetISTR(uint16_t /*wRegValue*/);
+void SetDADDR(uint16_t /*wRegValue*/);
+void SetBTABLE(uint16_t /*wRegValue*/);
+void SetBTABLE(uint16_t /*wRegValue*/);
+uint16_t GetCNTR(void);
+uint16_t GetISTR(void);
+uint16_t GetFNR(void);
+uint16_t GetDADDR(void);
+uint16_t GetBTABLE(void);
+void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/);
+uint16_t GetENDPOINT(uint8_t /*bEpNum*/);
+void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/);
+uint16_t GetEPType(uint8_t /*bEpNum*/);
+void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
+void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
+void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir);
+uint16_t GetEPTxStatus(uint8_t /*bEpNum*/);
+uint16_t GetEPRxStatus(uint8_t /*bEpNum*/);
+void SetEPTxValid(uint8_t /*bEpNum*/);
+void SetEPRxValid(uint8_t /*bEpNum*/);
+uint16_t GetTxStallStatus(uint8_t /*bEpNum*/);
+uint16_t GetRxStallStatus(uint8_t /*bEpNum*/);
+void SetEP_KIND(uint8_t /*bEpNum*/);
+void ClearEP_KIND(uint8_t /*bEpNum*/);
+void Set_Status_Out(uint8_t /*bEpNum*/);
+void Clear_Status_Out(uint8_t /*bEpNum*/);
+void SetEPDoubleBuff(uint8_t /*bEpNum*/);
+void ClearEPDoubleBuff(uint8_t /*bEpNum*/);
+void ClearEP_CTR_RX(uint8_t /*bEpNum*/);
+void ClearEP_CTR_TX(uint8_t /*bEpNum*/);
+void ToggleDTOG_RX(uint8_t /*bEpNum*/);
+void ToggleDTOG_TX(uint8_t /*bEpNum*/);
+void ClearDTOG_RX(uint8_t /*bEpNum*/);
+void ClearDTOG_TX(uint8_t /*bEpNum*/);
+void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/);
+uint8_t GetEPAddress(uint8_t /*bEpNum*/);
+void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
+void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
+uint16_t GetEPTxAddr(uint8_t /*bEpNum*/);
+uint16_t GetEPRxAddr(uint8_t /*bEpNum*/);
+void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/);
+void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
+void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
+uint16_t GetEPTxCount(uint8_t /*bEpNum*/);
+uint16_t GetEPRxCount(uint8_t /*bEpNum*/);
+void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/);
+void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/);
+void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/);
+uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/);
+uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/);
+void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/);
+uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/);
+EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/);
+void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir);
+uint16_t ToWord(uint8_t, uint8_t);
+uint16_t ByteSwap(uint16_t);
+
+#endif /* STM32F10X_CL */
+
+#endif /* __USB_REGS_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_sil.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,34 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_sil.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Simplified Interface Layer function prototypes.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_SIL_H
+#define __USB_SIL_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+uint32_t USB_SIL_Init(void);
+uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize);
+uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer);
+
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_SIL_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/inc/usb_type.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,70 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_type.h
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Type definitions used by the USB Library
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_TYPE_H
+#define __USB_TYPE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+typedef signed long      s32;
+typedef signed short     s16;
+typedef signed char      s8;
+
+typedef volatile signed long      vs32;
+typedef volatile signed short     vs16;
+typedef volatile signed char      vs8;
+
+typedef unsigned long       u32;
+typedef unsigned short      u16;
+typedef unsigned char       u8;
+
+typedef unsigned long  const    uc32;  /* Read Only */
+typedef unsigned short const    uc16;  /* Read Only */
+typedef unsigned char  const    uc8;   /* Read Only */
+
+typedef volatile unsigned long      vu32;
+typedef volatile unsigned short     vu16;
+typedef volatile unsigned char      vu8;
+
+typedef volatile unsigned long  const    vuc32;  /* Read Only */
+typedef volatile unsigned short const    vuc16;  /* Read Only */
+typedef volatile unsigned char  const    vuc8;   /* Read Only */
+
+#define FALSE 0
+#define TRUE  1
+typedef int bool;
+
+#ifndef __STM32F10x_H
+typedef enum { RESET = 0, SET   = !RESET } FlagStatus, ITStatus;
+
+typedef enum { DISABLE = 0, ENABLE  = !DISABLE} FunctionalState;
+
+typedef enum { ERROR = 0, SUCCESS  = !ERROR} ErrorStatus;
+#endif
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_TYPE_H */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_core.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1086 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_core.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Standard protocol processing (USB v2.0)
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define ValBit(VAR,Place)    (VAR & (1 << Place))
+#define SetBit(VAR,Place)    (VAR |= (1 << Place))
+#define ClrBit(VAR,Place)    (VAR &= ((1 << Place) ^ 255))
+
+#ifdef STM32F10X_CL
+ #define Send0LengthData()  {PCD_EP_Write (0, 0, 0) ; vSetEPTxStatus(EP_TX_VALID);}
+#else
+#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \
+    vSetEPTxStatus(EP_TX_VALID); \
+  }
+#endif /* STM32F10X_CL */
+
+#define vSetEPRxStatus(st) (SaveRState = st)
+#define vSetEPTxStatus(st) (SaveTState = st)
+
+#define USB_StatusIn() Send0LengthData()
+#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)
+
+#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
+#define StatusInfo1 StatusInfo.bw.bb0
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint16_t_uint8_t StatusInfo;
+
+bool Data_Mul_MaxPacketSize = FALSE;
+/* Private function prototypes -----------------------------------------------*/
+static void DataStageOut(void);
+static void DataStageIn(void);
+static void NoData_Setup0(void);
+static void Data_Setup0(void);
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : Standard_GetConfiguration.
+* Description    : Return the current configuration variable address.
+* Input          : Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 1 , if the request is invalid when "Length" is 0.
+*                  Return "Buffer" if the "Length" is not 0.
+*******************************************************************************/
+uint8_t *Standard_GetConfiguration(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength =
+      sizeof(pInformation->Current_Configuration);
+    return 0;
+  }
+  pUser_Standard_Requests->User_GetConfiguration();
+  return (uint8_t *)&pInformation->Current_Configuration;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetConfiguration.
+* Description    : This routine is called to set the configuration value
+*                  Then each class should configure device themself.
+* Input          : None.
+* Output         : None.
+* Return         : Return USB_SUCCESS, if the request is performed.
+*                  Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetConfiguration(void)
+{
+
+  if ((pInformation->USBwValue0 <=
+      Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0)
+      && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/
+  {
+    pInformation->Current_Configuration = pInformation->USBwValue0;
+    pUser_Standard_Requests->User_SetConfiguration();
+    return USB_SUCCESS;
+  }
+  else
+  {
+    return USB_UNSUPPORT;
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetInterface.
+* Description    : Return the Alternate Setting of the current interface.
+* Input          : Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 0, if the request is invalid when "Length" is 0.
+*                  Return "Buffer" if the "Length" is not 0.
+*******************************************************************************/
+uint8_t *Standard_GetInterface(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength =
+      sizeof(pInformation->Current_AlternateSetting);
+    return 0;
+  }
+  pUser_Standard_Requests->User_GetInterface();
+  return (uint8_t *)&pInformation->Current_AlternateSetting;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetInterface.
+* Description    : This routine is called to set the interface.
+*                  Then each class should configure the interface them self.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetInterface(void)
+{
+  RESULT Re;
+  /*Test if the specified Interface and Alternate Setting are supported by
+    the application Firmware*/
+  Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
+
+  if (pInformation->Current_Configuration != 0)
+  {
+    if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
+        || (pInformation->USBwValue1 != 0))
+    {
+      return  USB_UNSUPPORT;
+    }
+    else if (Re == USB_SUCCESS)
+    {
+      pUser_Standard_Requests->User_SetInterface();
+      pInformation->Current_Interface = pInformation->USBwIndex0;
+      pInformation->Current_AlternateSetting = pInformation->USBwValue0;
+      return USB_SUCCESS;
+    }
+
+  }
+
+  return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetStatus.
+* Description    : Copy the device request data to "StatusInfo buffer".
+* Input          : - Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 0, if the request is at end of data block,
+*                  or is invalid when "Length" is 0.
+*******************************************************************************/
+uint8_t *Standard_GetStatus(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = 2;
+    return 0;
+  }
+
+  /* Reset Status Information */
+  StatusInfo.w = 0;
+
+  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {
+    /*Get Device Status */
+    uint8_t Feature = pInformation->Current_Feature;
+
+    /* Remote Wakeup enabled */
+    if (ValBit(Feature, 5))
+    {
+      SetBit(StatusInfo0, 1);
+    }
+    else
+    {
+      ClrBit(StatusInfo0, 1);
+    }      
+
+    /* Bus-powered */
+    if (ValBit(Feature, 6))
+    {
+      SetBit(StatusInfo0, 0);
+    }
+    else /* Self-powered */
+    {
+      ClrBit(StatusInfo0, 0);
+    }
+  }
+  /*Interface Status*/
+  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+  {
+    return (uint8_t *)&StatusInfo;
+  }
+  /*Get EndPoint Status*/
+  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {
+    uint8_t Related_Endpoint;
+    uint8_t wIndex0 = pInformation->USBwIndex0;
+
+    Related_Endpoint = (wIndex0 & 0x0f);
+    if (ValBit(wIndex0, 7))
+    {
+      /* IN endpoint */
+      if (_GetTxStallStatus(Related_Endpoint))
+      {
+        SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
+      }
+    }
+    else
+    {
+      /* OUT endpoint */
+      if (_GetRxStallStatus(Related_Endpoint))
+      {
+        SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
+      }
+    }
+
+  }
+  else
+  {
+    return NULL;
+  }
+  pUser_Standard_Requests->User_GetStatus();
+  return (uint8_t *)&StatusInfo;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_ClearFeature.
+* Description    : Clear or disable a specific feature.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_ClearFeature(void)
+{
+  uint32_t     Type_Rec = Type_Recipient;
+  uint32_t     Status;
+
+
+  if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {/*Device Clear Feature*/
+    ClrBit(pInformation->Current_Feature, 5);
+    return USB_SUCCESS;
+  }
+  else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {/*EndPoint Clear Feature*/
+    DEVICE* pDev;
+    uint32_t Related_Endpoint;
+    uint32_t wIndex0;
+    uint32_t rEP;
+
+    if ((pInformation->USBwValue != ENDPOINT_STALL)
+        || (pInformation->USBwIndex1 != 0))
+    {
+      return USB_UNSUPPORT;
+    }
+
+    pDev = &Device_Table;
+    wIndex0 = pInformation->USBwIndex0;
+    rEP = wIndex0 & ~0x80;
+    Related_Endpoint = ENDP0 + rEP;
+
+    if (ValBit(pInformation->USBwIndex0, 7))
+    {
+      /*Get Status of endpoint & stall the request if the related_ENdpoint
+      is Disabled*/
+      Status = _GetEPTxStatus(Related_Endpoint);
+    }
+    else
+    {
+      Status = _GetEPRxStatus(Related_Endpoint);
+    }
+
+    if ((rEP >= pDev->Total_Endpoint) || (Status == 0)
+        || (pInformation->Current_Configuration == 0))
+    {
+      return USB_UNSUPPORT;
+    }
+
+
+    if (wIndex0 & 0x80)
+    {
+      /* IN endpoint */
+      if (_GetTxStallStatus(Related_Endpoint ))
+      {
+      #ifndef STM32F10X_CL
+        ClearDTOG_TX(Related_Endpoint);
+      #endif /* STM32F10X_CL */
+        SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
+      }
+    }
+    else
+    {
+      /* OUT endpoint */
+      if (_GetRxStallStatus(Related_Endpoint))
+      {
+        if (Related_Endpoint == ENDP0)
+        {
+          /* After clear the STALL, enable the default endpoint receiver */
+          SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
+          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
+        }
+        else
+        {
+        #ifndef STM32F10X_CL
+          ClearDTOG_RX(Related_Endpoint);
+        #endif /* STM32F10X_CL */
+          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
+        }
+      }
+    }
+    pUser_Standard_Requests->User_ClearFeature();
+    return USB_SUCCESS;
+  }
+
+  return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetEndPointFeature
+* Description    : Set or enable a specific feature of EndPoint
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetEndPointFeature(void)
+{
+  uint32_t    wIndex0;
+  uint32_t    Related_Endpoint;
+  uint32_t    rEP;
+  uint32_t    Status;
+
+  wIndex0 = pInformation->USBwIndex0;
+  rEP = wIndex0 & ~0x80;
+  Related_Endpoint = ENDP0 + rEP;
+
+  if (ValBit(pInformation->USBwIndex0, 7))
+  {
+    /* get Status of endpoint & stall the request if the related_ENdpoint
+    is Disabled*/
+    Status = _GetEPTxStatus(Related_Endpoint);
+  }
+  else
+  {
+    Status = _GetEPRxStatus(Related_Endpoint);
+  }
+
+  if (Related_Endpoint >= Device_Table.Total_Endpoint
+      || pInformation->USBwValue != 0 || Status == 0
+      || pInformation->Current_Configuration == 0)
+  {
+    return USB_UNSUPPORT;
+  }
+  else
+  {
+    if (wIndex0 & 0x80)
+    {
+      /* IN endpoint */
+      _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
+    }
+
+    else
+    {
+      /* OUT endpoint */
+      _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
+    }
+  }
+  pUser_Standard_Requests->User_SetEndPointFeature();
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetDeviceFeature.
+* Description    : Set or enable a specific feature of Device.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetDeviceFeature(void)
+{
+  SetBit(pInformation->Current_Feature, 5);
+  pUser_Standard_Requests->User_SetDeviceFeature();
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetDescriptorData.
+* Description    : Standard_GetDescriptorData is used for descriptors transfer.
+*                : This routine is used for the descriptors resident in Flash
+*                  or RAM
+*                  pDesc can be in either Flash or RAM
+*                  The purpose of this routine is to have a versatile way to
+*                  response descriptors request. It allows user to generate
+*                  certain descriptors with software or read descriptors from
+*                  external storage part by part.
+* Input          : - Length - Length of the data in this transfer.
+*                  - pDesc - A pointer points to descriptor struct.
+*                  The structure gives the initial address of the descriptor and
+*                  its original size.
+* Output         : None.
+* Return         : Address of a part of the descriptor pointed by the Usb_
+*                  wOffset The buffer pointed by this address contains at least
+*                  Length bytes.
+*******************************************************************************/
+uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
+{
+  uint32_t  wOffset;
+
+  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
+    return 0;
+  }
+
+  return pDesc->Descriptor + wOffset;
+}
+
+/*******************************************************************************
+* Function Name  : DataStageOut.
+* Description    : Data stage of a Control Write Transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void DataStageOut(void)
+{
+  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
+  uint32_t save_rLength;
+
+  save_rLength = pEPinfo->Usb_rLength;
+
+  if (pEPinfo->CopyData && save_rLength)
+  {
+    uint8_t *Buffer;
+    uint32_t Length;
+
+    Length = pEPinfo->PacketSize;
+    if (Length > save_rLength)
+    {
+      Length = save_rLength;
+    }
+
+    Buffer = (*pEPinfo->CopyData)(Length);
+    pEPinfo->Usb_rLength -= Length;
+    pEPinfo->Usb_rOffset += Length;
+
+  #ifdef STM32F10X_CL  
+    PCD_EP_Read(ENDP0, Buffer, Length); 
+  #else  
+    PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
+  #endif  /* STM32F10X_CL */
+  }
+
+  if (pEPinfo->Usb_rLength != 0)
+  {
+    vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
+    SetEPTxCount(ENDP0, 0);
+    vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
+  }
+  /* Set the next State*/
+  if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
+  {
+    pInformation->ControlState = OUT_DATA;
+  }
+  else
+  {
+    if (pEPinfo->Usb_rLength > 0)
+    {
+      pInformation->ControlState = LAST_OUT_DATA;
+    }
+    else if (pEPinfo->Usb_rLength == 0)
+    {
+      pInformation->ControlState = WAIT_STATUS_IN;
+      USB_StatusIn();
+    }
+  }
+}
+
+/*******************************************************************************
+* Function Name  : DataStageIn.
+* Description    : Data stage of a Control Read Transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void DataStageIn(void)
+{
+  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
+  uint32_t save_wLength = pEPinfo->Usb_wLength;
+  uint32_t ControlState = pInformation->ControlState;
+
+  uint8_t *DataBuffer;
+  uint32_t Length;
+
+  if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
+  {
+    if(Data_Mul_MaxPacketSize == TRUE)
+    {
+      /* No more data to send and empty packet */
+      Send0LengthData();
+      ControlState = LAST_IN_DATA;
+      Data_Mul_MaxPacketSize = FALSE;
+    }
+    else 
+    {
+      /* No more data to send so STALL the TX Status*/
+      ControlState = WAIT_STATUS_OUT;
+
+    #ifdef STM32F10X_CL      
+      PCD_EP_Read (ENDP0, 0, 0);
+    #endif  /* STM32F10X_CL */ 
+    
+    #ifndef STM32F10X_CL 
+      vSetEPTxStatus(EP_TX_STALL);
+    #endif  /* STM32F10X_CL */ 
+    }
+    
+    goto Expect_Status_Out;
+  }
+
+  Length = pEPinfo->PacketSize;
+  ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
+
+  if (Length > save_wLength)
+  {
+    Length = save_wLength;
+  }
+
+  DataBuffer = (*pEPinfo->CopyData)(Length);
+
+#ifdef STM32F10X_CL
+  PCD_EP_Write (ENDP0, DataBuffer, Length);
+#else   
+  UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
+#endif /* STM32F10X_CL */ 
+
+  SetEPTxCount(ENDP0, Length);
+
+  pEPinfo->Usb_wLength -= Length;
+  pEPinfo->Usb_wOffset += Length;
+  vSetEPTxStatus(EP_TX_VALID);
+
+  USB_StatusOut();/* Expect the host to abort the data IN stage */
+
+Expect_Status_Out:
+  pInformation->ControlState = ControlState;
+}
+
+/*******************************************************************************
+* Function Name  : NoData_Setup0.
+* Description    : Proceed the processing of setup request without data stage.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void NoData_Setup0(void)
+{
+  RESULT Result = USB_UNSUPPORT;
+  uint32_t RequestNo = pInformation->USBbRequest;
+  uint32_t ControlState;
+
+  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {
+    /* Device Request*/
+    /* SET_CONFIGURATION*/
+    if (RequestNo == SET_CONFIGURATION)
+    {
+      Result = Standard_SetConfiguration();
+    }
+
+    /*SET ADDRESS*/
+    else if (RequestNo == SET_ADDRESS)
+    {
+      if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
+          || (pInformation->USBwIndex != 0)
+          || (pInformation->Current_Configuration != 0))
+        /* Device Address should be 127 or less*/
+      {
+        ControlState = STALLED;
+        goto exit_NoData_Setup0;
+      }
+      else
+      {
+        Result = USB_SUCCESS;
+
+      #ifdef STM32F10X_CL
+         SetDeviceAddress(pInformation->USBwValue0);
+      #endif  /* STM32F10X_CL */
+      }
+    }
+    /*SET FEATURE for Device*/
+    else if (RequestNo == SET_FEATURE)
+    {
+      if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP)
+          && (pInformation->USBwIndex == 0)
+          && (ValBit(pInformation->Current_Feature, 5)))
+      {
+        Result = Standard_SetDeviceFeature();
+      }
+      else
+      {
+        Result = USB_UNSUPPORT;
+      }
+    }
+    /*Clear FEATURE for Device */
+    else if (RequestNo == CLEAR_FEATURE)
+    {
+      if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
+          && pInformation->USBwIndex == 0
+          && ValBit(pInformation->Current_Feature, 5))
+      {
+        Result = Standard_ClearFeature();
+      }
+      else
+      {
+        Result = USB_UNSUPPORT;
+      }
+    }
+
+  }
+
+  /* Interface Request*/
+  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+  {
+    /*SET INTERFACE*/
+    if (RequestNo == SET_INTERFACE)
+    {
+      Result = Standard_SetInterface();
+    }
+  }
+
+  /* EndPoint Request*/
+  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {
+    /*CLEAR FEATURE for EndPoint*/
+    if (RequestNo == CLEAR_FEATURE)
+    {
+      Result = Standard_ClearFeature();
+    }
+    /* SET FEATURE for EndPoint*/
+    else if (RequestNo == SET_FEATURE)
+    {
+      Result = Standard_SetEndPointFeature();
+    }
+  }
+  else
+  {
+    Result = USB_UNSUPPORT;
+  }
+
+
+  if (Result != USB_SUCCESS)
+  {
+    Result = (*pProperty->Class_NoData_Setup)(RequestNo);
+    if (Result == USB_NOT_READY)
+    {
+      ControlState = PAUSE;
+      goto exit_NoData_Setup0;
+    }
+  }
+
+  if (Result != USB_SUCCESS)
+  {
+    ControlState = STALLED;
+    goto exit_NoData_Setup0;
+  }
+
+  ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
+
+  USB_StatusIn();
+
+exit_NoData_Setup0:
+  pInformation->ControlState = ControlState;
+  return;
+}
+
+/*******************************************************************************
+* Function Name  : Data_Setup0.
+* Description    : Proceed the processing of setup request with data stage.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Data_Setup0(void)
+{
+  uint8_t *(*CopyRoutine)(uint16_t);
+  RESULT Result;
+  uint32_t Request_No = pInformation->USBbRequest;
+
+  uint32_t Related_Endpoint, Reserved;
+  uint32_t wOffset, Status;
+
+
+
+  CopyRoutine = NULL;
+  wOffset = 0;
+
+  /*GET DESCRIPTOR*/
+  if (Request_No == GET_DESCRIPTOR)
+  {
+    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+    {
+      uint8_t wValue1 = pInformation->USBwValue1;
+      if (wValue1 == DEVICE_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetDeviceDescriptor;
+      }
+      else if (wValue1 == CONFIG_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetConfigDescriptor;
+      }
+      else if (wValue1 == STRING_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetStringDescriptor;
+      }  /* End of GET_DESCRIPTOR */
+    }
+  }
+
+  /*GET STATUS*/
+  else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
+           && (pInformation->USBwLength == 0x0002)
+           && (pInformation->USBwIndex1 == 0))
+  {
+    /* GET STATUS for Device*/
+    if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+        && (pInformation->USBwIndex == 0))
+    {
+      CopyRoutine = Standard_GetStatus;
+    }
+
+    /* GET STATUS for Interface*/
+    else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+    {
+      if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
+          && (pInformation->Current_Configuration != 0))
+      {
+        CopyRoutine = Standard_GetStatus;
+      }
+    }
+
+    /* GET STATUS for EndPoint*/
+    else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+    {
+      Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
+      Reserved = pInformation->USBwIndex0 & 0x70;
+
+      if (ValBit(pInformation->USBwIndex0, 7))
+      {
+        /*Get Status of endpoint & stall the request if the related_ENdpoint
+        is Disabled*/
+        Status = _GetEPTxStatus(Related_Endpoint);
+      }
+      else
+      {
+        Status = _GetEPRxStatus(Related_Endpoint);
+      }
+
+      if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
+          && (Status != 0))
+      {
+        CopyRoutine = Standard_GetStatus;
+      }
+    }
+
+  }
+
+  /*GET CONFIGURATION*/
+  else if (Request_No == GET_CONFIGURATION)
+  {
+    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+    {
+      CopyRoutine = Standard_GetConfiguration;
+    }
+  }
+  /*GET INTERFACE*/
+  else if (Request_No == GET_INTERFACE)
+  {
+    if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+        && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
+        && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
+        && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
+    {
+      CopyRoutine = Standard_GetInterface;
+    }
+
+  }
+  
+  if (CopyRoutine)
+  {
+    pInformation->Ctrl_Info.Usb_wOffset = wOffset;
+    pInformation->Ctrl_Info.CopyData = CopyRoutine;
+    /* sb in the original the cast to word was directly */
+    /* now the cast is made step by step */
+    (*CopyRoutine)(0);
+    Result = USB_SUCCESS;
+  }
+  else
+  {
+    Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
+    if (Result == USB_NOT_READY)
+    {
+      pInformation->ControlState = PAUSE;
+      return;
+    }
+  }
+
+  if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
+  {
+    /* Data is not ready, wait it */
+    pInformation->ControlState = PAUSE;
+    return;
+  }
+  if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
+  {
+    /* Unsupported request */
+    pInformation->ControlState = STALLED;
+    return;
+  }
+
+
+  if (ValBit(pInformation->USBbmRequestType, 7))
+  {
+    /* Device ==> Host */
+    __IO uint32_t wLength = pInformation->USBwLength;
+     
+    /* Restrict the data length to be the one host asks for */
+    if (pInformation->Ctrl_Info.Usb_wLength > wLength)
+    {
+      pInformation->Ctrl_Info.Usb_wLength = wLength;
+    }
+    
+    else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
+    {
+      if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
+      {
+        Data_Mul_MaxPacketSize = FALSE;
+      }
+      else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
+      {
+        Data_Mul_MaxPacketSize = TRUE;
+      }
+    }   
+
+    pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
+    DataStageIn();
+  }
+  else
+  {
+    pInformation->ControlState = OUT_DATA;
+    vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
+  }
+
+  return;
+}
+
+/*******************************************************************************
+* Function Name  : Setup0_Process
+* Description    : Get the device request data and dispatch to individual process.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t Setup0_Process(void)
+{
+
+  union
+  {
+    uint8_t* b;
+    uint16_t* w;
+  } pBuf;
+
+#ifdef STM32F10X_CL
+  USB_OTG_EP *ep;
+  uint16_t offset = 0;
+ 
+  ep = PCD_GetOutEP(ENDP0);
+  pBuf.b = ep->xfer_buff;
+#else  
+  uint16_t offset = 1;
+  
+  pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
+#endif /* STM32F10X_CL */
+
+  if (pInformation->ControlState != PAUSE)
+  {
+    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
+    pInformation->USBbRequest = *pBuf.b++; /* bRequest */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwLength = *pBuf.w; /* wLength */
+  }
+
+  pInformation->ControlState = SETTING_UP;
+  if (pInformation->USBwLength == 0)
+  {
+    /* Setup with no data stage */
+    NoData_Setup0();
+  }
+  else
+  {
+    /* Setup with data stage */
+    Data_Setup0();
+  }
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : In0_Process
+* Description    : Process the IN token on all default endpoint.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t In0_Process(void)
+{
+  uint32_t ControlState = pInformation->ControlState;
+
+  if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
+  {
+    DataStageIn();
+    /* ControlState may be changed outside the function */
+    ControlState = pInformation->ControlState;
+  }
+
+  else if (ControlState == WAIT_STATUS_IN)
+  {
+    if ((pInformation->USBbRequest == SET_ADDRESS) &&
+        (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
+    {
+      SetDeviceAddress(pInformation->USBwValue0);
+      pUser_Standard_Requests->User_SetDeviceAddress();
+    }
+    (*pProperty->Process_Status_IN)();
+    ControlState = STALLED;
+  }
+
+  else
+  {
+    ControlState = STALLED;
+  }
+
+  pInformation->ControlState = ControlState;
+
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : Out0_Process
+* Description    : Process the OUT token on all default endpoint.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t Out0_Process(void)
+{
+  uint32_t ControlState = pInformation->ControlState;
+
+  if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
+  {
+    /* host aborts the transfer before finish */
+    ControlState = STALLED;
+  }
+  else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
+  {
+    DataStageOut();
+    ControlState = pInformation->ControlState; /* may be changed outside the function */
+  }
+
+  else if (ControlState == WAIT_STATUS_OUT)
+  {
+    (*pProperty->Process_Status_OUT)();
+  #ifndef STM32F10X_CL
+    ControlState = STALLED;
+  #endif /* STM32F10X_CL */
+  }
+
+
+  /* Unexpect state, STALL the endpoint */
+  else
+  {
+    ControlState = STALLED;
+  }
+
+  pInformation->ControlState = ControlState;
+
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : Post0_Process
+* Description    : Stall the Endpoint 0 in case of error.
+* Input          : None.
+* Output         : None.
+* Return         : - 0 if the control State is in PAUSE
+*                  - 1 if not.
+*******************************************************************************/
+uint8_t Post0_Process(void)
+{
+#ifdef STM32F10X_CL  
+  USB_OTG_EP *ep;
+#endif /* STM32F10X_CL */
+      
+  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+
+  if (pInformation->ControlState == STALLED)
+  {
+    vSetEPRxStatus(EP_RX_STALL);
+    vSetEPTxStatus(EP_TX_STALL);
+  }
+
+#ifdef STM32F10X_CL
+  else if ((pInformation->ControlState == OUT_DATA) ||
+      (pInformation->ControlState == WAIT_STATUS_OUT))
+  {
+    ep = PCD_GetInEP(0);
+    ep->is_in = 0;
+    OTGD_FS_EP0StartXfer(ep);
+    
+    vSetEPTxStatus(EP_TX_VALID);
+  }
+  
+  else if ((pInformation->ControlState == IN_DATA) || 
+      (pInformation->ControlState == WAIT_STATUS_IN))
+  {
+    ep = PCD_GetInEP(0);
+    ep->is_in = 1;
+    OTGD_FS_EP0StartXfer(ep);    
+  }  
+#endif /* STM32F10X_CL */
+
+  return (pInformation->ControlState == PAUSE);
+}
+
+/*******************************************************************************
+* Function Name  : SetDeviceAddress.
+* Description    : Set the device and all the used Endpoints addresses.
+* Input          : - Val: device adress.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDeviceAddress(uint8_t Val)
+{
+#ifdef STM32F10X_CL 
+  PCD_EP_SetAddress ((uint8_t)Val);
+#else 
+  uint32_t i;
+  uint32_t nEP = Device_Table.Total_Endpoint;
+
+  /* set address in every used endpoint */
+  for (i = 0; i < nEP; i++)
+  {
+    _SetEPAddress((uint8_t)i, (uint8_t)i);
+  } /* for */
+  _SetDADDR(Val | DADDR_EF); /* set device address and enable function */
+#endif  /* STM32F10X_CL */  
+}
+
+/*******************************************************************************
+* Function Name  : NOP_Process
+* Description    : No operation function.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void NOP_Process(void)
+{
+}
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_init.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,63 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_init.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Initialization routines & global variables
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/*  The number of current endpoint, it will be used to specify an endpoint */
+ uint8_t	EPindex;
+/*  The number of current device, it is an index to the Device_Table */
+/* uint8_t	Device_no; */
+/*  Points to the DEVICE_INFO structure of current device */
+/*  The purpose of this register is to speed up the execution */
+DEVICE_INFO *pInformation;
+/*  Points to the DEVICE_PROP structure of current device */
+/*  The purpose of this register is to speed up the execution */
+DEVICE_PROP *pProperty;
+/*  Temporary save the state of Rx & Tx status. */
+/*  Whenever the Rx or Tx state is changed, its value is saved */
+/*  in this variable first and will be set to the EPRB or EPRA */
+/*  at the end of interrupt process */
+uint16_t	SaveState ;
+uint16_t  wInterrupt_Mask;
+DEVICE_INFO	Device_Info;
+USER_STANDARD_REQUESTS  *pUser_Standard_Requests;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : USB_Init
+* Description    : USB system initialization
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Init(void)
+{
+  pInformation = &Device_Info;
+  pInformation->ControlState = 2;
+  pProperty = &Device_Property;
+  pUser_Standard_Requests = &User_Standard_Requests;
+  /* Initialize devices one by one */
+  pProperty->Init();
+}
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_int.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,188 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_int.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Endpoint CTR (Low and High) interrupt's service routines
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint16_t SaveRState;
+__IO uint16_t SaveTState;
+
+/* Extern variables ----------------------------------------------------------*/
+extern void (*pEpInt_IN[7])(void);    /*  Handles IN  interrupts   */
+extern void (*pEpInt_OUT[7])(void);   /*  Handles OUT interrupts   */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : CTR_LP.
+* Description    : Low priority Endpoint Correct Transfer interrupt's service
+*                  routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void CTR_LP(void)
+{
+  __IO uint16_t wEPVal = 0;
+  /* stay in loop while pending ints */
+  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
+  {
+    /* extract highest priority endpoint number */
+    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
+    if (EPindex == 0)
+    {
+      /* Decode and service control endpoint interrupt */
+      /* calling related service routine */
+      /* (Setup0_Process, In0_Process, Out0_Process) */
+
+      /* save RX & TX status */
+      /* and set both to NAK */
+
+
+	    SaveRState = _GetENDPOINT(ENDP0);
+	    SaveTState = SaveRState & EPTX_STAT;
+	    SaveRState &=  EPRX_STAT;	
+
+	    _SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK);
+
+      /* DIR bit = origin of the interrupt */
+
+      if ((wIstr & ISTR_DIR) == 0)
+      {
+        /* DIR = 0 */
+
+        /* DIR = 0      => IN  int */
+        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
+
+
+        _ClearEP_CTR_TX(ENDP0);
+        In0_Process();
+
+           /* before terminate set Tx & Rx status */
+
+            _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+		  return;
+      }
+      else
+      {
+        /* DIR = 1 */
+
+        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
+        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
+
+        wEPVal = _GetENDPOINT(ENDP0);
+        
+        if ((wEPVal &EP_SETUP) != 0)
+        {
+          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
+          Setup0_Process();
+          /* before terminate set Tx & Rx status */
+
+		      _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+          return;
+        }
+
+        else if ((wEPVal & EP_CTR_RX) != 0)
+        {
+          _ClearEP_CTR_RX(ENDP0);
+          Out0_Process();
+          /* before terminate set Tx & Rx status */
+     
+		     _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+          return;
+        }
+      }
+    }/* if(EPindex == 0) */
+    else
+    {
+      /* Decode and service non control endpoints interrupt  */
+
+      /* process related endpoint register */
+      wEPVal = _GetENDPOINT(EPindex);
+      if ((wEPVal & EP_CTR_RX) != 0)
+      {
+        /* clear int flag */
+        _ClearEP_CTR_RX(EPindex);
+
+        /* call OUT service function */
+        (*pEpInt_OUT[EPindex-1])();
+
+      } /* if((wEPVal & EP_CTR_RX) */
+
+      if ((wEPVal & EP_CTR_TX) != 0)
+      {
+        /* clear int flag */
+        _ClearEP_CTR_TX(EPindex);
+
+        /* call IN service function */
+        (*pEpInt_IN[EPindex-1])();
+      } /* if((wEPVal & EP_CTR_TX) != 0) */
+
+    }/* if(EPindex == 0) else */
+
+  }/* while(...) */
+}
+
+/*******************************************************************************
+* Function Name  : CTR_HP.
+* Description    : High Priority Endpoint Correct Transfer interrupt's service 
+*                  routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void CTR_HP(void)
+{
+  uint32_t wEPVal = 0;
+
+  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
+  {
+    _SetISTR((uint16_t)CLR_CTR); /* clear CTR flag */
+    /* extract highest priority endpoint number */
+    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
+    /* process related endpoint register */
+    wEPVal = _GetENDPOINT(EPindex);
+    if ((wEPVal & EP_CTR_RX) != 0)
+    {
+      /* clear int flag */
+      _ClearEP_CTR_RX(EPindex);
+
+      /* call OUT service function */
+      (*pEpInt_OUT[EPindex-1])();
+
+    } /* if((wEPVal & EP_CTR_RX) */
+    else if ((wEPVal & EP_CTR_TX) != 0)
+    {
+      /* clear int flag */
+      _ClearEP_CTR_TX(EPindex);
+
+      /* call IN service function */
+      (*pEpInt_IN[EPindex-1])();
+
+
+    } /* if((wEPVal & EP_CTR_TX) != 0) */
+
+  }/* while(...) */
+}
+
+#endif  /* STM32F10X_CL */
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_mem.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,74 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_mem.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Utility functions for memory transfers to/from PMA
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : UserToPMABufferCopy
+* Description    : Copy a buffer from user memory area to packet memory area (PMA)
+* Input          : - pbUsrBuf: pointer to user memory area.
+*                  - wPMABufAddr: address into PMA.
+*                  - wNBytes: no. of bytes to be copied.
+* Output         : None.
+* Return         : None	.
+*******************************************************************************/
+void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+  uint32_t n = (wNBytes + 1) >> 1;   /* n = (wNBytes + 1) / 2 */
+  uint32_t i, temp1;
+  uint16_t *pdwVal;
+  pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
+  for (i = n; i != 0; i--)
+  {
+    temp1 = (uint16_t) * pbUsrBuf;
+    pbUsrBuf++;
+    *pdwVal++ = temp1 | (uint16_t) * pbUsrBuf << 8;
+    pdwVal++;
+    pbUsrBuf++;
+  }
+}
+/*******************************************************************************
+* Function Name  : PMAToUserBufferCopy
+* Description    : Copy a buffer from user memory area to packet memory area (PMA)
+* Input          : - pbUsrBuf    = pointer to user memory area.
+*                  - wPMABufAddr = address into PMA.
+*                  - wNBytes     = no. of bytes to be copied.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+  uint32_t n = (wNBytes + 1) >> 1;/* /2*/
+  uint32_t i;
+  uint32_t *pdwVal;
+  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
+  for (i = n; i != 0; i--)
+  {
+    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
+    pbUsrBuf++;
+  }
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_regs.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,750 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_regs.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Interface functions to USB cell registers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : SetCNTR.
+* Description    : Set the CNTR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetCNTR(uint16_t wRegValue)
+{
+  _SetCNTR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetCNTR.
+* Description    : returns the CNTR register value.
+* Input          : None.
+* Output         : None.
+* Return         : CNTR register Value.
+*******************************************************************************/
+uint16_t GetCNTR(void)
+{
+  return(_GetCNTR());
+}
+
+/*******************************************************************************
+* Function Name  : SetISTR.
+* Description    : Set the ISTR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetISTR(uint16_t wRegValue)
+{
+  _SetISTR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetISTR
+* Description    : Returns the ISTR register value.
+* Input          : None.
+* Output         : None.
+* Return         : ISTR register Value
+*******************************************************************************/
+uint16_t GetISTR(void)
+{
+  return(_GetISTR());
+}
+
+/*******************************************************************************
+* Function Name  : GetFNR
+* Description    : Returns the FNR register value.
+* Input          : None.
+* Output         : None.
+* Return         : FNR register Value
+*******************************************************************************/
+uint16_t GetFNR(void)
+{
+  return(_GetFNR());
+}
+
+/*******************************************************************************
+* Function Name  : SetDADDR
+* Description    : Set the DADDR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDADDR(uint16_t wRegValue)
+{
+  _SetDADDR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetDADDR
+* Description    : Returns the DADDR register value.
+* Input          : None.
+* Output         : None.
+* Return         : DADDR register Value
+*******************************************************************************/
+uint16_t GetDADDR(void)
+{
+  return(_GetDADDR());
+}
+
+/*******************************************************************************
+* Function Name  : SetBTABLE
+* Description    : Set the BTABLE.
+* Input          : wRegValue: New register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetBTABLE(uint16_t wRegValue)
+{
+  _SetBTABLE(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetBTABLE.
+* Description    : Returns the BTABLE register value.
+* Input          : None. 
+* Output         : None.
+* Return         : BTABLE address.
+*******************************************************************************/
+uint16_t GetBTABLE(void)
+{
+  return(_GetBTABLE());
+}
+
+/*******************************************************************************
+* Function Name  : SetENDPOINT
+* Description    : Setthe Endpoint register value.
+* Input          : bEpNum: Endpoint Number. 
+*                  wRegValue.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetENDPOINT(uint8_t bEpNum, uint16_t wRegValue)
+{
+  _SetENDPOINT(bEpNum, wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetENDPOINT
+* Description    : Return the Endpoint register value.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint register value.
+*******************************************************************************/
+uint16_t GetENDPOINT(uint8_t bEpNum)
+{
+  return(_GetENDPOINT(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPType
+* Description    : sets the type in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+*                  wType: type definition.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPType(uint8_t bEpNum, uint16_t wType)
+{
+  _SetEPType(bEpNum, wType);
+}
+
+/*******************************************************************************
+* Function Name  : GetEPType
+* Description    : Returns the endpoint type.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint Type
+*******************************************************************************/
+uint16_t GetEPType(uint8_t bEpNum)
+{
+  return(_GetEPType(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxStatus
+* Description    : Set the status of Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPTxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxStatus
+* Description    : Set the status of Rx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPRxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : SetDouBleBuffEPStall
+* Description    : sets the status for Double Buffer Endpoint to STALL
+* Input          : bEpNum: Endpoint Number. 
+*                  bDir: Endpoint direction.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDouBleBuffEPStall(uint8_t bEpNum, uint8_t bDir)
+{
+  uint16_t Endpoint_DTOG_Status;
+  Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
+  if (bDir == EP_DBUF_OUT)
+  { /* OUT double buffered endpoint */
+    _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
+  }
+  else if (bDir == EP_DBUF_IN)
+  { /* IN double buffered endpoint */
+    _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
+  }
+}
+
+/*******************************************************************************
+* Function Name  : GetEPTxStatus
+* Description    : Returns the endpoint Tx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint TX Status
+*******************************************************************************/
+uint16_t GetEPTxStatus(uint8_t bEpNum)
+{
+  return(_GetEPTxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : GetEPRxStatus
+* Description    : Returns the endpoint Rx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint RX Status
+*******************************************************************************/
+uint16_t GetEPRxStatus(uint8_t bEpNum)
+{
+  return(_GetEPRxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxValid
+* Description    : Valid the endpoint Tx Status.
+* Input          : bEpNum: Endpoint Number.  
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxValid(uint8_t bEpNum)
+{
+  _SetEPTxStatus(bEpNum, EP_TX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxValid
+* Description    : Valid the endpoint Rx Status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxValid(uint8_t bEpNum)
+{
+  _SetEPRxStatus(bEpNum, EP_RX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : SetEP_KIND
+* Description    : Clear the EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEP_KIND(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+
+/*******************************************************************************
+* Function Name  : ClearEP_KIND
+* Description    : set the  EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_KIND(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : Clear_Status_Out
+* Description    : Clear the Status Out of the related Endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Clear_Status_Out(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : Set_Status_Out
+* Description    : Set the Status Out of the related Endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Set_Status_Out(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : SetEPDoubleBuff
+* Description    : Enable the double buffer feature for the endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDoubleBuff(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearEPDoubleBuff
+* Description    : Disable the double buffer feature for the endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEPDoubleBuff(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : GetTxStallStatus
+* Description    : Returns the Stall status of the Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Tx Stall status.
+*******************************************************************************/
+uint16_t GetTxStallStatus(uint8_t bEpNum)
+{
+  return(_GetTxStallStatus(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetRxStallStatus
+* Description    : Returns the Stall status of the Rx endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx Stall status.
+*******************************************************************************/
+uint16_t GetRxStallStatus(uint8_t bEpNum)
+{
+  return(_GetRxStallStatus(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : ClearEP_CTR_RX
+* Description    : Clear the CTR_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_CTR_RX(uint8_t bEpNum)
+{
+  _ClearEP_CTR_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearEP_CTR_TX
+* Description    : Clear the CTR_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_CTR_TX(uint8_t bEpNum)
+{
+  _ClearEP_CTR_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ToggleDTOG_RX
+* Description    : Toggle the DTOG_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ToggleDTOG_RX(uint8_t bEpNum)
+{
+  _ToggleDTOG_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ToggleDTOG_TX
+* Description    : Toggle the DTOG_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ToggleDTOG_TX(uint8_t bEpNum)
+{
+  _ToggleDTOG_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearDTOG_RX.
+* Description    : Clear the DTOG_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearDTOG_RX(uint8_t bEpNum)
+{
+  _ClearDTOG_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearDTOG_TX.
+* Description    : Clear the DTOG_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearDTOG_TX(uint8_t bEpNum)
+{
+  _ClearDTOG_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : SetEPAddress
+* Description    : Set the endpoint address.
+* Input          : bEpNum: Endpoint Number.
+*                  bAddr: New endpoint address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPAddress(uint8_t bEpNum, uint8_t bAddr)
+{
+  _SetEPAddress(bEpNum, bAddr);
+}
+/*******************************************************************************
+* Function Name  : GetEPAddress
+* Description    : Get the endpoint address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint address.
+*******************************************************************************/
+uint8_t GetEPAddress(uint8_t bEpNum)
+{
+  return(_GetEPAddress(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPTxAddr
+* Description    : Set the endpoint Tx buffer address.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: new address. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxAddr(uint8_t bEpNum, uint16_t wAddr)
+{
+  _SetEPTxAddr(bEpNum, wAddr);
+}
+/*******************************************************************************
+* Function Name  : SetEPRxAddr
+* Description    : Set the endpoint Rx buffer address.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxAddr(uint8_t bEpNum, uint16_t wAddr)
+{
+  _SetEPRxAddr(bEpNum, wAddr);
+}
+/*******************************************************************************
+* Function Name  : GetEPTxAddr
+* Description    : Returns the endpoint Tx buffer address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx buffer address. 
+*******************************************************************************/
+uint16_t GetEPTxAddr(uint8_t bEpNum)
+{
+  return(_GetEPTxAddr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPRxAddr.
+* Description    : Returns the endpoint Rx buffer address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx buffer address.
+*******************************************************************************/
+uint16_t GetEPRxAddr(uint8_t bEpNum)
+{
+  return(_GetEPRxAddr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPTxCount.
+* Description    : Set the Tx count.
+* Input          : bEpNum: Endpoint Number.
+*                  wCount: new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
+{
+  _SetEPTxCount(bEpNum, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPCountRxReg.
+* Description    : Set the Count Rx Register value.
+* Input          : *pdwReg: point to the register.
+*                  wCount: the new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPCountRxReg(uint32_t *pdwReg, uint16_t wCount)
+{
+  _SetEPCountRxReg(dwReg, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPRxCount
+* Description    : Set the Rx count.
+* Input          : bEpNum: Endpoint Number. 
+*                  wCount: the new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
+{
+  _SetEPRxCount(bEpNum, wCount);
+}
+/*******************************************************************************
+* Function Name  : GetEPTxCount
+* Description    : Get the Tx count.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None
+* Return         : Tx count value.
+*******************************************************************************/
+uint16_t GetEPTxCount(uint8_t bEpNum)
+{
+  return(_GetEPTxCount(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPRxCount
+* Description    : Get the Rx count.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx count value.
+*******************************************************************************/
+uint16_t GetEPRxCount(uint8_t bEpNum)
+{
+  return(_GetEPRxCount(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuffAddr
+* Description    : Set the addresses of the buffer 0 and 1.
+* Input          : bEpNum: Endpoint Number.  
+*                  wBuf0Addr: new address of buffer 0. 
+*                  wBuf1Addr: new address of buffer 1.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuffAddr(uint8_t bEpNum, uint16_t wBuf0Addr, uint16_t wBuf1Addr)
+{
+  _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf0Addr
+* Description    : Set the Buffer 1 address.
+* Input          : bEpNum: Endpoint Number
+*                  wBuf0Addr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf0Addr(uint8_t bEpNum, uint16_t wBuf0Addr)
+{
+  _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf1Addr
+* Description    : Set the Buffer 1 address.
+* Input          : bEpNum: Endpoint Number
+*                  wBuf1Addr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf1Addr(uint8_t bEpNum, uint16_t wBuf1Addr)
+{
+  _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf0Addr
+* Description    : Returns the address of the Buffer 0.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint16_t GetEPDblBuf0Addr(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf0Addr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf1Addr
+* Description    : Returns the address of the Buffer 1.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Address of the Buffer 1.
+*******************************************************************************/
+uint16_t GetEPDblBuf1Addr(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf1Addr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuffCount
+* Description    : Set the number of bytes for a double Buffer 
+*                  endpoint.
+* Input          : bEpNum,bDir, wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuffCount(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf0Count
+* Description    : Set the number of bytes in the buffer 0 of a double Buffer 
+*                  endpoint.
+* Input          : bEpNum, bDir,  wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuf0Count(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf1Count
+* Description    : Set the number of bytes in the buffer 0 of a double Buffer 
+*                  endpoint.
+* Input          : bEpNum,  bDir,  wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuf1Count(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf0Count
+* Description    : Returns the number of byte received in the buffer 0 of a double
+*                  Buffer endpoint.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Endpoint Buffer 0 count
+*******************************************************************************/
+uint16_t GetEPDblBuf0Count(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf0Count(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf1Count
+* Description    : Returns the number of data received in the buffer 1 of a double
+*                  Buffer endpoint.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Endpoint Buffer 1 count.
+*******************************************************************************/
+uint16_t GetEPDblBuf1Count(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf1Count(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBufDir
+* Description    : gets direction of the double buffered endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : EP_DBUF_OUT, EP_DBUF_IN,
+*                  EP_DBUF_ERR if the endpoint counter not yet programmed.
+*******************************************************************************/
+EP_DBUF_DIR GetEPDblBufDir(uint8_t bEpNum)
+{
+  if ((uint16_t)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
+    return(EP_DBUF_OUT);
+  else if (((uint16_t)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
+    return(EP_DBUF_IN);
+  else
+    return(EP_DBUF_ERR);
+}
+/*******************************************************************************
+* Function Name  : FreeUserBuffer
+* Description    : free buffer used from the application realizing it to the line
+                   toggles bit SW_BUF in the double buffered endpoint register
+* Input          : bEpNum, bDir
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir)
+{
+  if (bDir == EP_DBUF_OUT)
+  { /* OUT double buffered endpoint */
+    _ToggleDTOG_TX(bEpNum);
+  }
+  else if (bDir == EP_DBUF_IN)
+  { /* IN double buffered endpoint */
+    _ToggleDTOG_RX(bEpNum);
+  }
+}
+
+/*******************************************************************************
+* Function Name  : ToWord
+* Description    : merge two byte in a word.
+* Input          : bh: byte high, bl: bytes low.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ToWord(uint8_t bh, uint8_t bl)
+{
+  uint16_t wRet;
+  wRet = (uint16_t)bl | ((uint16_t)bh << 8);
+  return(wRet);
+}
+/*******************************************************************************
+* Function Name  : ByteSwap
+* Description    : Swap two byte in a word.
+* Input          : wSwW: word to Swap.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ByteSwap(uint16_t wSwW)
+{
+  uint8_t bTemp;
+  uint16_t wRet;
+  bTemp = (uint8_t)(wSwW & 0xff);
+  wRet =  (wSwW >> 8) | ((uint16_t)bTemp << 8);
+  return(wRet);
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm_usb_fs_lib/src/usb_sil.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,126 @@
+/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
+* File Name          : usb_sil.c
+* Author             : MCD Application Team
+* Version            : V3.2.1
+* Date               : 07/05/2010
+* Description        : Simplified Interface Layer for Global Initialization and 
+*                      Endpoint Rea/Write operations.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Init
+* Description    : Initialize the USB Device IP and the Endpoint 0.
+* Input          : None.
+* Output         : None.
+* Return         : Status.
+*******************************************************************************/
+uint32_t USB_SIL_Init(void)
+{
+#ifndef STM32F10X_CL
+  
+  /* USB interrupts initialization */
+  /* clear pending interrupts */
+  _SetISTR(0);
+  wInterrupt_Mask = IMR_MSK;
+  /* set interrupts mask */
+  _SetCNTR(wInterrupt_Mask);
+  
+#else
+  
+  /* Perform OTG Device initialization procedure (including EP0 init) */
+  OTG_DEV_Init();
+  
+#endif /* STM32F10X_CL */
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Write
+* Description    : Write a buffer of data to a selected endpoint.
+* Input          : - bEpAddr: The address of the non control endpoint.
+*                  - pBufferPointer: The pointer to the buffer of data to be written
+*                    to the endpoint.
+*                  - wBufferSize: Number of data to be written (in bytes).
+* Output         : None.
+* Return         : Status.
+*******************************************************************************/
+uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
+{
+#ifndef STM32F10X_CL
+
+  /* Use the memory interface function to write to the selected endpoint */
+  UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);
+
+  /* Update the data length in the control register */
+  SetEPTxCount((bEpAddr & 0x7F), wBufferSize);
+  
+#else
+  
+   /* Use the PCD interface layer function to write to the selected endpoint */
+   PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); 
+   
+#endif /* STM32F10X_CL */
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Read
+* Description    : Write a buffer of data to a selected endpoint.
+* Input          : - bEpAddr: The address of the non control endpoint.
+*                  - pBufferPointer: The pointer to which will be saved the 
+*                     received data buffer.
+* Output         : None.
+* Return         : Number of received data (in Bytes).
+*******************************************************************************/
+uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
+{
+  uint32_t DataLength = 0;
+
+#ifndef STM32F10X_CL
+
+  /* Get the number of received data on the selected Endpoint */
+  DataLength = GetEPRxCount(bEpAddr & 0x7F);
+  
+  /* Use the memory interface function to write to the selected endpoint */
+  PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);
+
+#else
+  
+  USB_OTG_EP *ep;
+
+  /* Get the structure pointer of the selected Endpoint */
+  ep = PCD_GetOutEP(bEpAddr);
+  
+  /* Get the number of received data */
+  DataLength = ep->xfer_len;
+  
+  /* Use the PCD interface layer function to read the selected endpoint */
+  PCD_EP_Read (bEpAddr, pBufferPointer, DataLength);
+  
+#endif /* STM32F10X_CL */
+
+  /* Return the number of received data */
+  return DataLength;
+}
+
+/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Entries	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,15 @@
+/usb_pwr.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_prop.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_istr.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_desc.h/1.1/Fri Mar 30 21:03:34 2012//
+/usb_conf.h/1.1/Sat Mar 19 10:14:24 2011//
+/stm32f10x_it.h/1.1/Sat Mar 19 10:14:24 2011//
+/platform_config.h/1.1/Tue Mar  1 04:44:10 2016//
+/hw_config.h/1.1/Wed Jun  1 01:57:17 2016//
+/usb_pwr.c/1.1/Sat Mar 19 10:14:26 2011//
+/usb_desc.c/1.1/Wed Jun  1 01:53:39 2016//
+/hw_config.c/1.1/Sat Nov 19 06:07:40 2016//
+/usb_istr.c/1.1/Wed Nov 16 07:23:56 2016//
+/usb_endp.c/1.3/Mon Nov 21 06:19:40 2016//
+/usb_prop.c/1.1/Mon Nov 21 07:52:24 2016//
+D
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Entries.Extra	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,14 @@
+/usb_pwr.h///1468199674/
+/usb_prop.h///1468199675/
+/usb_istr.h///1468199675/
+/usb_desc.h///1468199675/
+/usb_conf.h///1468199675/
+/stm32f10x_it.h///1468199675/
+/platform_config.h///1468199675/
+/hw_config.h///1468199675/
+/usb_pwr.c///1468199675/
+/usb_desc.c///1468199675/
+/hw_config.c///1468199675/
+/usb_istr.c///1468199675/
+/usb_endp.c///1471019589/
+/usb_prop.c///1468199675/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Entries.Extra.Old	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,14 @@
+/usb_pwr.h///1468199674/
+/usb_prop.h///1468199675/
+/usb_istr.h///1468199675/
+/usb_desc.h///1468199675/
+/usb_conf.h///1468199675/
+/stm32f10x_it.h///1468199675/
+/platform_config.h///1468199675/
+/hw_config.h///1468199675/
+/usb_pwr.c///1468199675/
+/usb_prop.c///1468199675/
+/usb_desc.c///1468199675/
+/hw_config.c///1468199675/
+/usb_istr.c///1468199675/
+/usb_endp.c///1471019589/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Entries.Old	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,15 @@
+/usb_pwr.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_prop.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_istr.h/1.1/Sat Mar 19 10:14:24 2011//
+/usb_desc.h/1.1/Fri Mar 30 21:03:34 2012//
+/usb_conf.h/1.1/Sat Mar 19 10:14:24 2011//
+/stm32f10x_it.h/1.1/Sat Mar 19 10:14:24 2011//
+/platform_config.h/1.1/Tue Mar  1 04:44:10 2016//
+/hw_config.h/1.1/Wed Jun  1 01:57:17 2016//
+/usb_pwr.c/1.1/Sat Mar 19 10:14:26 2011//
+/usb_prop.c/1.1/Sat Mar 31 16:25:44 2012//
+/usb_desc.c/1.1/Wed Jun  1 01:53:39 2016//
+/hw_config.c/1.1/Sat Nov 19 06:07:40 2016//
+/usb_istr.c/1.1/Wed Nov 16 07:23:56 2016//
+/usb_endp.c/1.3/Mon Nov 21 06:19:40 2016//
+D
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Repository	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1 @@
+Code/grbl1.0d/stm32grbl/usb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/CVS/Root	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1 @@
+:local:E:/CVSRep
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/hw_config.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,143 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+ * File Name          : hw_config.c
+ * Author             : MCD Application Team
+ * Version            : V3.3.0
+ * Date               : 21-March-2011
+ * Description        : Hardware Configuration & Setup
+ ********************************************************************************
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+ * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+ * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+ * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *******************************************************************************/
+
+#include "stm32f10x_it.h"
+
+#include "usb_lib.h"
+#include "usb_prop.h"
+#include "usb_desc.h"
+#include "hw_config.h"
+#include "platform_config.h"
+#include "usb_pwr.h"
+#include "stm32f10x_rcc.h"
+#include "misc.h"
+
+ErrorStatus HSEStartUpStatus;
+
+static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
+
+/*******************************************************************************
+ * Description    : Configures Main system clocks & power
+ *******************************************************************************/
+void Set_System(void)
+{
+}
+
+/*******************************************************************************
+ * Description    : Configures USB Clock input (48MHz)
+ *******************************************************************************/
+void Set_USBClock(void)
+{
+	/* Select USBCLK source */
+	RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
+
+	/* Enable the USB clock */
+	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
+}
+
+/*******************************************************************************
+ * Description    : Power-off system clocks and power while entering suspend mode
+ *******************************************************************************/
+void Enter_LowPowerMode(void)
+{
+	/* Set the device state to suspend */
+	bDeviceState = SUSPENDED;
+}
+
+/*******************************************************************************
+ * Description    : Restores system clocks and power while exiting suspend mode
+ *******************************************************************************/
+void Leave_LowPowerMode(void)
+{
+	DEVICE_INFO *pInfo = &Device_Info;
+
+	/* Set the device state to the correct state */
+	if (pInfo->Current_Configuration != 0)
+	{
+		/* Device configured */
+		bDeviceState = CONFIGURED;
+	}
+	else
+	{
+		bDeviceState = ATTACHED;
+	}
+}
+
+/*******************************************************************************
+ * Description    : Configures the USB interrupts
+ *******************************************************************************/
+void USB_Interrupts_Config(void)
+{
+	NVIC_InitTypeDef NVIC_InitStructure;
+
+	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+
+	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
+	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+	NVIC_Init(&NVIC_InitStructure);
+}
+
+/*******************************************************************************
+ * Description    : Software Connection/Disconnection of USB Cable
+ *******************************************************************************/
+void USB_Cable_Config(FunctionalState NewState)
+{
+}
+
+/*******************************************************************************
+ * Description    : Create the serial number string descriptor.
+ *******************************************************************************/
+void Get_SerialNum(void)
+{
+	uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
+
+	Device_Serial0 = *(__IO uint32_t*) (0x1FFFF7E8);
+	Device_Serial1 = *(__IO uint32_t*) (0x1FFFF7EC);
+	Device_Serial2 = *(__IO uint32_t*) (0x1FFFF7F0);
+
+	Device_Serial0 += Device_Serial2;
+
+	if (Device_Serial0 != 0)
+	{
+		IntToUnicode(Device_Serial0, &Virtual_Com_Port_StringSerial[2], 8);
+		IntToUnicode(Device_Serial1, &Virtual_Com_Port_StringSerial[18], 4);
+	}
+}
+
+/*******************************************************************************
+ * Description    : Convert Hex 32Bits value into char.
+ *******************************************************************************/
+static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
+{
+	uint8_t idx = 0;
+
+	for (idx = 0; idx < len; idx++)
+	{
+		if (((value >> 28)) < 0xA)
+		{
+			pbuf[2 * idx] = (value >> 28) + '0';
+		}
+		else
+		{
+			pbuf[2 * idx] = (value >> 28) + 'A' - 10;
+		}
+
+		value = value << 4;
+
+		pbuf[2 * idx + 1] = 0;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/hw_config.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,48 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+ * File Name          : hw_config.h
+ * Author             : MCD Application Team
+ * Version            : V3.3.0
+ * Date               : 21-March-2011
+ * Description        : Hardware Configuration & Setup
+ ********************************************************************************
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+ * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+ * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+ * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HW_CONFIG_H
+#define __HW_CONFIG_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_type.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+#define MASS_MEMORY_START     0x04002000
+#define BULK_MAX_PACKET_SIZE  0x00000040
+#define LED_ON                0xF0
+#define LED_OFF               0xFF
+
+#define USART_RX_DATA_SIZE   (64)
+/* Exported functions ------------------------------------------------------- */
+void Set_System(void);
+void Set_USBClock(void);
+void Enter_LowPowerMode(void);
+void Leave_LowPowerMode(void);
+void USB_Interrupts_Config(void);
+void USB_Cable_Config(FunctionalState NewState);
+void USART_Config_Default(void);
+bool USART_Config(void);
+void OnUsbDataRx(uint8_t* data_buffer, uint8_t Nb_bytes);
+void Get_SerialNum(void);
+
+/* External variables --------------------------------------------------------*/
+
+#endif  /*__HW_CONFIG_H*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/platform_config.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,7 @@
+#ifndef __PLATFORM_CONFIG_H
+#define __PLATFORM_CONFIG_H
+
+#include "stm32f10x.h"
+
+#endif /* __PLATFORM_CONFIG_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/stm32f10x_it.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,56 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : stm32f10x_it.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : This file contains the headers of the interrupt handlers.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_IT_H
+#define __STM32F10x_IT_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifndef STM32F10X_CL
+void USB_LP_CAN1_RX0_IRQHandler(void);
+#endif /* STM32F10X_CL */
+
+#if defined (USE_STM3210B_EVAL) || defined (USE_STM3210E_EVAL)
+void USART1_IRQHandler(void);
+#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210C_EVAL
+void USART2_IRQHandler(void);
+#endif /* USE_STM3210C_EVAL */
+
+#ifdef STM32F10X_CL
+void OTG_FS_IRQHandler(void);
+#endif /* STM32F10X_CL */
+
+#endif /* __STM32F10x_IT_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_conf.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,197 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_conf.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Virtual COM Port Demo configuration  header
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF_H
+#define __USB_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/* EP_NUM */
+/* defines how many endpoints are used by the device */
+/*-------------------------------------------------------------*/
+
+#define EP_NUM                          (4)
+
+
+#ifndef STM32F10X_CL
+/*-------------------------------------------------------------*/
+/* --------------   Buffer Description Table  -----------------*/
+/*-------------------------------------------------------------*/
+/* buffer table base address */
+/* buffer table base address */
+#define BTABLE_ADDRESS      (0x00)
+
+/* EP0  */
+/* rx/tx buffer base address */
+#define ENDP0_RXADDR        (0x40)
+#define ENDP0_TXADDR        (0x80)
+
+/* EP1  */
+/* tx buffer base address */
+#define ENDP1_TXADDR        (0xC0)
+#define ENDP2_TXADDR        (0x100)
+#define ENDP3_RXADDR        (0x110)
+
+
+/*-------------------------------------------------------------*/
+/* -------------------   ISTR events  -------------------------*/
+/*-------------------------------------------------------------*/
+/* IMR_MSK */
+/* mask defining which events has to be handled */
+/* by the device application software */
+#define IMR_MSK (CNTR_CTRM  | CNTR_SOFM  | CNTR_RESETM )
+
+/*#define CTR_CALLBACK*/
+/*#define DOVR_CALLBACK*/
+/*#define ERR_CALLBACK*/
+/*#define WKUP_CALLBACK*/
+/*#define SUSP_CALLBACK*/
+/*#define RESET_CALLBACK*/
+#define SOF_CALLBACK
+/*#define ESOF_CALLBACK*/
+#endif /* STM32F10X_CL */
+
+#ifdef STM32F10X_CL
+/*******************************************************************************
+*                              FIFO Size Configuration
+*  
+*  (i) Dedicated data FIFO SPRAM of 1.25 Kbytes = 1280 bytes = 320 32-bits words
+*      available for the endpoints IN and OUT.
+*      Device mode features:
+*      -1 bidirectional CTRL EP 0
+*      -3 IN EPs to support any kind of Bulk, Interrupt or Isochronous transfer
+*      -3 OUT EPs to support any kind of Bulk, Interrupt or Isochronous transfer
+*
+*  ii) Receive data FIFO size = RAM for setup packets + 
+*                   OUT endpoint control information +
+*                   data OUT packets + miscellaneous
+*      Space = ONE 32-bits words
+*     --> RAM for setup packets = 4 * n + 6 space
+*        (n is the nbr of CTRL EPs the device core supports) 
+*     --> OUT EP CTRL info      = 1 space
+*        (one space for status information written to the FIFO along with each 
+*        received packet)
+*     --> data OUT packets      = (Largest Packet Size / 4) + 1 spaces 
+*        (MINIMUM to receive packets)
+*     --> OR data OUT packets  = at least 2*(Largest Packet Size / 4) + 1 spaces 
+*        (if high-bandwidth EP is enabled or multiple isochronous EPs)
+*     --> miscellaneous = 1 space per OUT EP
+*        (one space for transfer complete status information also pushed to the 
+*        FIFO with each endpoint's last packet)
+*
+*  (iii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for 
+*       that particular IN EP. More space allocated in the IN EP Tx FIFO results
+*       in a better performance on the USB and can hide latencies on the AHB.
+*
+*  (iv) TXn min size = 16 words. (n  : Transmit FIFO index)
+*   (v) When a TxFIFO is not used, the Configuration should be as follows: 
+*       case 1 :  n > m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txm can use the space allocated for Txn.
+*       case2  :  n < m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txn should be configured with the minimum space of 16 words
+*  (vi) The FIFO is used optimally when used TxFIFOs are allocated in the top 
+*       of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+*******************************************************************************/
+
+#define RX_FIFO_SIZE                          128
+#define TX0_FIFO_SIZE                          64
+#define TX1_FIFO_SIZE                          64
+#define TX2_FIFO_SIZE                          16
+#define TX3_FIFO_SIZE                          16
+
+/* OTGD-FS-DEVICE IP interrupts Enable definitions */
+/* Uncomment the define to enable the selected interrupt */
+//#define INTR_MODEMISMATCH
+#define INTR_SOFINTR
+#define INTR_RXSTSQLVL           /* Mandatory */
+//#define INTR_NPTXFEMPTY
+//#define INTR_GINNAKEFF
+//#define INTR_GOUTNAKEFF
+//#define INTR_ERLYSUSPEND
+#define INTR_USBSUSPEND          /* Mandatory */
+#define INTR_USBRESET            /* Mandatory */
+#define INTR_ENUMDONE            /* Mandatory */
+//#define INTR_ISOOUTDROP
+//#define INTR_EOPFRAME
+//#define INTR_EPMISMATCH
+#define INTR_INEPINTR            /* Mandatory */
+#define INTR_OUTEPINTR           /* Mandatory */
+//#define INTR_INCOMPLISOIN
+//#define INTR_INCOMPLISOOUT
+#define INTR_WKUPINTR            /* Mandatory */
+
+/* OTGD-FS-DEVICE IP interrupts subroutines */
+/* Comment the define to enable the selected interrupt subroutine and replace it
+   by user code */
+#define  INTR_MODEMISMATCH_Callback      NOP_Process
+/* #define  INTR_SOFINTR_Callback           NOP_Process */
+#define  INTR_RXSTSQLVL_Callback         NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_GINNAKEFF_Callback         NOP_Process
+#define  INTR_GOUTNAKEFF_Callback        NOP_Process
+#define  INTR_ERLYSUSPEND_Callback       NOP_Process
+#define  INTR_USBSUSPEND_Callback        NOP_Process
+#define  INTR_USBRESET_Callback          NOP_Process
+#define  INTR_ENUMDONE_Callback          NOP_Process
+#define  INTR_ISOOUTDROP_Callback        NOP_Process
+#define  INTR_EOPFRAME_Callback          NOP_Process
+#define  INTR_EPMISMATCH_Callback        NOP_Process
+#define  INTR_INEPINTR_Callback          NOP_Process
+#define  INTR_OUTEPINTR_Callback         NOP_Process
+#define  INTR_INCOMPLISOIN_Callback      NOP_Process
+#define  INTR_INCOMPLISOOUT_Callback     NOP_Process
+#define  INTR_WKUPINTR_Callback          NOP_Process
+
+/* Isochronous data update */
+#define  INTR_RXSTSQLVL_ISODU_Callback   NOP_Process  
+
+/* Isochronous transfer parameters */
+/* Size of a single Isochronous buffer (size of a single transfer) */
+#define ISOC_BUFFER_SZE                  1
+/* Number of sub-buffers (number of single buffers/transfers), should be even */
+#define NUM_SUB_BUFFERS                  2
+
+#endif /* STM32F10X_CL */
+
+
+/* CTR service routines */
+/* associated to defined endpoints */
+/*#define  EP1_IN_Callback   NOP_Process*/
+#define  EP2_IN_Callback   NOP_Process
+#define  EP3_IN_Callback   NOP_Process
+#define  EP4_IN_Callback   NOP_Process
+#define  EP5_IN_Callback   NOP_Process
+#define  EP6_IN_Callback   NOP_Process
+#define  EP7_IN_Callback   NOP_Process
+
+#define  EP1_OUT_Callback   NOP_Process
+#define  EP2_OUT_Callback   NOP_Process
+/*#define  EP3_OUT_Callback   NOP_Process*/
+#define  EP4_OUT_Callback   NOP_Process
+#define  EP5_OUT_Callback   NOP_Process
+#define  EP6_OUT_Callback   NOP_Process
+#define  EP7_OUT_Callback   NOP_Process
+
+#endif /* __USB_CONF_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_desc.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,172 @@
+/**
+  ******************************************************************************
+  * @file    usb_desc.c
+  * @author  MCD Application Team
+  * @version V4.0.0
+  * @date    21-January-2013
+  * @brief   Descriptors for Virtual Com Port Demo
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  *
+  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/software_license_agreement_liberty_v2
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_desc.h"
+
+/* USB Standard Device Descriptor */
+const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
+  {
+    0x12,   /* bLength */
+    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
+    0x00,
+    0x02,   /* bcdUSB = 2.00 */
+    0x02,   /* bDeviceClass: CDC */
+    0x00,   /* bDeviceSubClass */
+    0x00,   /* bDeviceProtocol */
+    0x40,   /* bMaxPacketSize0 */
+    0x83,
+    0x04,   /* idVendor = 0x0483 */
+    0x40,
+    0x57,   /* idProduct = 0x7540 */
+    0x00,
+    0x02,   /* bcdDevice = 2.00 */
+    1,              /* Index of string descriptor describing manufacturer */
+    2,              /* Index of string descriptor describing product */
+    3,              /* Index of string descriptor describing the device's serial number */
+    0x01    /* bNumConfigurations */
+  };
+
+const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
+  {
+    /*Configuration Descriptor*/
+    0x09,   /* bLength: Configuration Descriptor size */
+    USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
+    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */
+    0x00,
+    0x02,   /* bNumInterfaces: 2 interface */
+    0x01,   /* bConfigurationValue: Configuration value */
+    0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
+    0xC0,   /* bmAttributes: self powered */
+    0x32,   /* MaxPower 0 mA */
+    /*Interface Descriptor*/
+    0x09,   /* bLength: Interface Descriptor size */
+    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
+    /* Interface descriptor type */
+    0x00,   /* bInterfaceNumber: Number of Interface */
+    0x00,   /* bAlternateSetting: Alternate setting */
+    0x01,   /* bNumEndpoints: One endpoints used */
+    0x02,   /* bInterfaceClass: Communication Interface Class */
+    0x02,   /* bInterfaceSubClass: Abstract Control Model */
+    0x01,   /* bInterfaceProtocol: Common AT commands */
+    0x00,   /* iInterface: */
+    /*Header Functional Descriptor*/
+    0x05,   /* bLength: Endpoint Descriptor size */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x00,   /* bDescriptorSubtype: Header Func Desc */
+    0x10,   /* bcdCDC: spec release number */
+    0x01,
+    /*Call Management Functional Descriptor*/
+    0x05,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x01,   /* bDescriptorSubtype: Call Management Func Desc */
+    0x00,   /* bmCapabilities: D0+D1 */
+    0x01,   /* bDataInterface: 1 */
+    /*ACM Functional Descriptor*/
+    0x04,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
+    0x02,   /* bmCapabilities */
+    /*Union Functional Descriptor*/
+    0x05,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x06,   /* bDescriptorSubtype: Union func desc */
+    0x00,   /* bMasterInterface: Communication class interface */
+    0x01,   /* bSlaveInterface0: Data Class Interface */
+    /*Endpoint 2 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x82,   /* bEndpointAddress: (IN2) */
+    0x03,   /* bmAttributes: Interrupt */
+    VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */
+    0x00,
+    0xFF,   /* bInterval: */
+    /*Data class interface descriptor*/
+    0x09,   /* bLength: Endpoint Descriptor size */
+    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
+    0x01,   /* bInterfaceNumber: Number of Interface */
+    0x00,   /* bAlternateSetting: Alternate setting */
+    0x02,   /* bNumEndpoints: Two endpoints used */
+    0x0A,   /* bInterfaceClass: CDC */
+    0x00,   /* bInterfaceSubClass: */
+    0x00,   /* bInterfaceProtocol: */
+    0x00,   /* iInterface: */
+    /*Endpoint 3 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x03,   /* bEndpointAddress: (OUT3) */
+    0x02,   /* bmAttributes: Bulk */
+    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
+    0x00,
+    0x00,   /* bInterval: ignore for Bulk transfer */
+    /*Endpoint 1 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x81,   /* bEndpointAddress: (IN1) */
+    0x02,   /* bmAttributes: Bulk */
+    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
+    0x00,
+    0x00    /* bInterval */
+  };
+
+/* USB String Descriptors */
+const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_LANGID,
+    USB_STRING_DESCRIPTOR_TYPE,
+    0x09,
+    0x04 /* LangID = 0x0409: U.S. English */
+  };
+
+const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_VENDOR,     /* Size of Vendor string */
+    USB_STRING_DESCRIPTOR_TYPE,             /* bDescriptorType*/
+    /* Manufacturer: "tomeko.net" */
+    't', 0, 'o', 0, 'm', 0, 'e', 0, 'k', 0, 'o', 0, ' ', 0, 'n', 0,
+    'e', 0, 't', 0
+  };
+
+const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT,          /* bLength */
+    USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
+    /* Product name: "STM32F103C8T6" */
+    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, 'F', 0, '1', 0, '0', 0,
+    '3', 0, 'C', 0, '8', 0, 'T', 0, '6', 0
+  };
+
+uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */
+    USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */
+    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0
+  };
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_desc.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,159 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_desc.c
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Descriptors for Virtual Com Port Demo
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_desc.h"
+
+/* USB Standard Device Descriptor */
+const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
+  {
+    0x12,   /* bLength */
+    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
+    0x00,
+    0x02,   /* bcdUSB = 2.00 */
+    0x02,   /* bDeviceClass: CDC */
+    0x00,   /* bDeviceSubClass */
+    0x00,   /* bDeviceProtocol */
+    0x40,   /* bMaxPacketSize0 */
+    0x83,
+    0x04,   /* idVendor = 0x0483 */
+    0x40,
+    0x57,   /* idProduct = 0x7540 */
+    0x00,
+    0x02,   /* bcdDevice = 2.00 */
+    1,              /* Index of string descriptor describing manufacturer */
+    2,              /* Index of string descriptor describing product */
+    3,              /* Index of string descriptor describing the device's serial number */
+    0x01    /* bNumConfigurations */
+  };
+
+const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
+  {
+    /*Configuration Descriptor*/
+    0x09,   /* bLength: Configuration Descriptor size */
+    USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
+    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */
+    0x00,
+    0x02,   /* bNumInterfaces: 2 interface */
+    0x01,   /* bConfigurationValue: Configuration value */
+    0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
+    0xC0,   /* bmAttributes: self powered */
+    0x32,   /* MaxPower 0 mA */
+    /*Interface Descriptor*/
+    0x09,   /* bLength: Interface Descriptor size */
+    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
+    /* Interface descriptor type */
+    0x00,   /* bInterfaceNumber: Number of Interface */
+    0x00,   /* bAlternateSetting: Alternate setting */
+    0x01,   /* bNumEndpoints: One endpoints used */
+    0x02,   /* bInterfaceClass: Communication Interface Class */
+    0x02,   /* bInterfaceSubClass: Abstract Control Model */
+    0x01,   /* bInterfaceProtocol: Common AT commands */
+    0x00,   /* iInterface: */
+    /*Header Functional Descriptor*/
+    0x05,   /* bLength: Endpoint Descriptor size */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x00,   /* bDescriptorSubtype: Header Func Desc */
+    0x10,   /* bcdCDC: spec release number */
+    0x01,
+    /*Call Management Functional Descriptor*/
+    0x05,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x01,   /* bDescriptorSubtype: Call Management Func Desc */
+    0x00,   /* bmCapabilities: D0+D1 */
+    0x01,   /* bDataInterface: 1 */
+    /*ACM Functional Descriptor*/
+    0x04,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
+    0x02,   /* bmCapabilities */
+    /*Union Functional Descriptor*/
+    0x05,   /* bFunctionLength */
+    0x24,   /* bDescriptorType: CS_INTERFACE */
+    0x06,   /* bDescriptorSubtype: Union func desc */
+    0x00,   /* bMasterInterface: Communication class interface */
+    0x01,   /* bSlaveInterface0: Data Class Interface */
+    /*Endpoint 2 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x82,   /* bEndpointAddress: (IN2) */
+    0x03,   /* bmAttributes: Interrupt */
+    VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */
+    0x00,
+    0xFF,   /* bInterval: */
+    /*Data class interface descriptor*/
+    0x09,   /* bLength: Endpoint Descriptor size */
+    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
+    0x01,   /* bInterfaceNumber: Number of Interface */
+    0x00,   /* bAlternateSetting: Alternate setting */
+    0x02,   /* bNumEndpoints: Two endpoints used */
+    0x0A,   /* bInterfaceClass: CDC */
+    0x00,   /* bInterfaceSubClass: */
+    0x00,   /* bInterfaceProtocol: */
+    0x00,   /* iInterface: */
+    /*Endpoint 3 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x03,   /* bEndpointAddress: (OUT3) */
+    0x02,   /* bmAttributes: Bulk */
+    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
+    0x00,
+    0x00,   /* bInterval: ignore for Bulk transfer */
+    /*Endpoint 1 Descriptor*/
+    0x07,   /* bLength: Endpoint Descriptor size */
+    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+    0x81,   /* bEndpointAddress: (IN1) */
+    0x02,   /* bmAttributes: Bulk */
+    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
+    0x00,
+    0x00    /* bInterval */
+  };
+
+/* USB String Descriptors */
+const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_LANGID,
+    USB_STRING_DESCRIPTOR_TYPE,
+    0x09,
+    0x04 /* LangID = 0x0409: U.S. English */
+  };
+
+const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_VENDOR,     /* Size of Vendor string */
+    USB_STRING_DESCRIPTOR_TYPE,             /* bDescriptorType*/
+    /* Manufacturer: "tomeko.net" */
+    't', 0, 'o', 0, 'm', 0, 'e', 0, 'k', 0, 'o', 0, ' ', 0, 'n', 0,
+    'e', 0, 't', 0
+  };
+
+const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT,          /* bLength */
+    USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
+    /* Product name: "miniscope v2c" */
+    'm', 0, 'i', 0, 'n', 0, 'i', 0, 's', 0, 'c', 0, 'o', 0, 'p', 0,
+    'e', 0, ' ', 0, 'v', 0, '2', 0, 'c', 0
+  };
+
+uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
+  {
+    VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */
+    USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */
+    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
+  };
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_desc.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,53 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_desc.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Descriptor Header for Virtual COM Port Device
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+#define USB_DEVICE_DESCRIPTOR_TYPE              0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02
+#define USB_STRING_DESCRIPTOR_TYPE              0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05
+
+#define VIRTUAL_COM_PORT_DATA_SIZE              64
+#define VIRTUAL_COM_PORT_INT_SIZE               8
+
+#define VIRTUAL_COM_PORT_SIZ_DEVICE_DESC        18
+#define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC        67
+#define VIRTUAL_COM_PORT_SIZ_STRING_LANGID      4
+#define VIRTUAL_COM_PORT_SIZ_STRING_VENDOR      22
+#define VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT     28
+#define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL      26
+
+#define STANDARD_ENDPOINT_DESC_SIZE             0x09
+
+/* Exported functions ------------------------------------------------------- */
+extern const uint8_t Virtual_Com_Port_DeviceDescriptor[VIRTUAL_COM_PORT_SIZ_DEVICE_DESC];
+extern const uint8_t Virtual_Com_Port_ConfigDescriptor[VIRTUAL_COM_PORT_SIZ_CONFIG_DESC];
+
+extern const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID];
+extern const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR];
+extern const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT];
+extern uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL];
+
+#endif /* __USB_DESC_H */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_endp.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,106 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+ * File Name          : usb_endp.c
+ * Author             : MCD Application Team
+ * Version            : V3.3.0
+ * Date               : 21-March-2011
+ * Description        : Endpoint routines
+ ********************************************************************************
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+ * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+ * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+ * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *******************************************************************************/
+
+#include "usb_lib.h"
+#include "usb_desc.h"
+#include "usb_mem.h"
+#include "hw_config.h"
+#include "usb_istr.h"
+#include "usb_pwr.h"
+#include "serial.h"
+uint8_t USB_Rx_Buffer[VIRTUAL_COM_PORT_DATA_SIZE];
+
+extern uint8_t serial_tx_buffer[];
+extern uint8_t serial_tx_buffer_head;
+extern volatile uint8_t serial_tx_buffer_tail;
+
+void EP3_OUT_Callback(void)
+{
+	uint16_t USB_Rx_Cnt;
+
+	/* Get the received data buffer and update the counter */
+	USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);
+
+	/* USB data will be immediately processed, this allow next USB traffic being
+	NAKed till the end of the USART Xfer */
+
+	OnUsbDataRx(USB_Rx_Buffer, USB_Rx_Cnt);
+
+	/* Enable the receive of data on EP3 */
+	SetEPRxValid(ENDP3);
+}
+void EP1_IN_Callback (void)
+{
+	if (serial_tx_buffer_head != serial_tx_buffer_tail && (_GetEPTxStatus(ENDP1) == EP_TX_NAK))
+    {
+	    uint16_t USB_Tx_length;
+
+        if (serial_tx_buffer_head > serial_tx_buffer_tail)
+		    USB_Tx_length = serial_tx_buffer_head - serial_tx_buffer_tail;
+        else
+        {
+		    USB_Tx_length = TX_BUFFER_SIZE - serial_tx_buffer_tail + serial_tx_buffer_head;
+        }
+
+        if (USB_Tx_length != 0)
+        {
+            if (USB_Tx_length > 64)
+    	        USB_Tx_length = 64;
+
+    //        UserToPMABufferCopy(&serial_tx_buffer[serial_tx_buffer_tail], ENDP1_TXADDR, USB_Tx_length);
+            {
+                uint8_t *pbUsrBuf = serial_tx_buffer + serial_tx_buffer_tail;
+                uint32_t n = (USB_Tx_length + 1) >> 1;   /* n = (wNBytes + 1) / 2 */
+                uint32_t i, temp1;
+                uint16_t *pdwVal;
+                pdwVal = (uint16_t *)(ENDP1_TXADDR * 2 + PMAAddr);
+                for (i = n; i != 0; i--)
+                {
+                    temp1 = (uint16_t) * pbUsrBuf;
+                    pbUsrBuf++;
+                    if (pbUsrBuf - serial_tx_buffer == TX_BUFFER_SIZE)
+                        pbUsrBuf = serial_tx_buffer;
+
+                    *pdwVal++ = temp1 | (uint16_t) * pbUsrBuf << 8;
+                    pdwVal++;
+                    pbUsrBuf++;
+                    if (pbUsrBuf - serial_tx_buffer == TX_BUFFER_SIZE)
+                        pbUsrBuf = serial_tx_buffer;
+                }
+            }
+
+	        SetEPTxCount(ENDP1, USB_Tx_length);
+	        SetEPTxValid(ENDP1);
+
+            serial_tx_buffer_tail += USB_Tx_length;
+            if (serial_tx_buffer_tail >= TX_BUFFER_SIZE)
+                serial_tx_buffer_tail -= TX_BUFFER_SIZE;
+        }
+	}
+}
+
+
+/*	\brief Start Of Frame (SOF) callback
+ */
+void SOF_Callback(void)
+{
+	if(bDeviceState == CONFIGURED)
+	{
+		/* Check the data to be sent through IN pipe */
+		EP1_IN_Callback();
+	}
+}
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_endp.c.bak	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,89 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+ * File Name          : usb_endp.c
+ * Author             : MCD Application Team
+ * Version            : V3.3.0
+ * Date               : 21-March-2011
+ * Description        : Endpoint routines
+ ********************************************************************************
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+ * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+ * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+ * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *******************************************************************************/
+
+#include "usb_lib.h"
+#include "usb_desc.h"
+#include "usb_mem.h"
+#include "hw_config.h"
+#include "usb_istr.h"
+#include "usb_pwr.h"
+#include "serial.h"
+uint8_t USB_Rx_Buffer[VIRTUAL_COM_PORT_DATA_SIZE];
+
+extern uint8_t serial_tx_buffer[];
+extern uint8_t serial_tx_buffer_head;
+extern volatile uint8_t serial_tx_buffer_tail;
+
+void EP3_OUT_Callback(void)
+{
+	uint16_t USB_Rx_Cnt;
+
+	/* Get the received data buffer and update the counter */
+	USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);
+
+	/* USB data will be immediately processed, this allow next USB traffic being
+	NAKed till the end of the USART Xfer */
+
+	OnUsbDataRx(USB_Rx_Buffer, USB_Rx_Cnt);
+
+	/* Enable the receive of data on EP3 */
+	SetEPRxValid(ENDP3);
+}
+
+void EP1_IN_Callback (void)
+{
+	if (serial_tx_buffer_head != serial_tx_buffer_tail)
+    {
+	    uint16_t USB_Tx_length;
+
+        if (serial_tx_buffer_head > serial_tx_buffer_tail)
+		    USB_Tx_length = serial_tx_buffer_head - serial_tx_buffer_tail;
+        else
+        {
+		    USB_Tx_length = TX_BUFFER_SIZE - serial_tx_buffer_tail;
+        }
+
+        if (USB_Tx_length != 0)
+        {
+            if (USB_Tx_length > 64)
+    	        USB_Tx_length = 64;
+
+            UserToPMABufferCopy(serial_tx_buffer + serial_tx_buffer_tail, ENDP1_TXADDR, USB_Tx_length);
+            serial_tx_buffer_tail += USB_Tx_length;
+            if (serial_tx_buffer_tail == TX_BUFFER_SIZE)
+                serial_tx_buffer_tail = 0;
+
+	        SetEPTxCount(ENDP1, USB_Tx_length);
+	        SetEPTxValid(ENDP1);
+        }
+	}
+}
+
+
+/*	\brief Start Of Frame (SOF) callback
+ */
+void SOF_Callback(void)
+{
+	if(bDeviceState == CONFIGURED)
+	{
+		/* Check the data to be sent through IN pipe */
+		if (_GetEPTxStatus(ENDP1) == EP_TX_NAK)
+        {
+			EP1_IN_Callback();
+		}
+	}
+}
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_istr.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,384 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_istr.c
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : ISTR events interrupt service routines
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_prop.h"
+#include "usb_pwr.h"
+#include "usb_istr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint16_t wIstr;  /* ISTR register last read value */
+__IO uint8_t bIntPackSOF = 0;  /* SOFs received between 2 consecutive packets */
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* function pointers to non-control endpoints service routines */
+void (*pEpInt_IN[7])(void) =
+  {
+    EP1_IN_Callback,
+    EP2_IN_Callback,
+    EP3_IN_Callback,
+    EP4_IN_Callback,
+    EP5_IN_Callback,
+    EP6_IN_Callback,
+    EP7_IN_Callback,
+  };
+
+void (*pEpInt_OUT[7])(void) =
+  {
+    EP1_OUT_Callback,
+    EP2_OUT_Callback,
+    EP3_OUT_Callback,
+    EP4_OUT_Callback,
+    EP5_OUT_Callback,
+    EP6_OUT_Callback,
+    EP7_OUT_Callback,
+  };
+
+#ifndef STM32F10X_CL
+
+/*******************************************************************************
+* Function Name  : USB_Istr
+* Description    : STR events interrupt service routine
+* Input          :
+* Output         :
+* Return         :
+*******************************************************************************/
+void USB_Istr(void)
+{
+
+  wIstr = _GetISTR();
+
+#if (IMR_MSK & ISTR_SOF)
+  if (wIstr & ISTR_SOF & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_SOF);
+    bIntPackSOF++;
+
+#ifdef SOF_CALLBACK
+    SOF_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/  
+  
+#if (IMR_MSK & ISTR_CTR)
+  if (wIstr & ISTR_CTR & wInterrupt_Mask)
+  {
+    /* servicing of the endpoint correct transfer interrupt */
+    /* clear of the CTR flag into the sub */
+    CTR_LP();
+#ifdef CTR_CALLBACK
+    CTR_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/  
+#if (IMR_MSK & ISTR_RESET)
+  if (wIstr & ISTR_RESET & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_RESET);
+    Device_Property.Reset();
+#ifdef RESET_CALLBACK
+    RESET_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_DOVR)
+  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_DOVR);
+#ifdef DOVR_CALLBACK
+    DOVR_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_ERR)
+  if (wIstr & ISTR_ERR & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_ERR);
+#ifdef ERR_CALLBACK
+    ERR_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_WKUP)
+  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_WKUP);
+    Resume(RESUME_EXTERNAL);
+#ifdef WKUP_CALLBACK
+    WKUP_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_SUSP)
+  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
+  {
+
+    /* check if SUSPEND is possible */
+    if (fSuspendEnabled)
+    {
+      Suspend();
+    }
+    else
+    {
+      /* if not possible then resume after xx ms */
+      Resume(RESUME_LATER);
+    }
+    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
+    _SetISTR((uint16_t)CLR_SUSP);
+#ifdef SUSP_CALLBACK
+    SUSP_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+#if (IMR_MSK & ISTR_ESOF)
+  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
+  {
+    _SetISTR((uint16_t)CLR_ESOF);
+    /* resume handling timing is made with ESOFs */
+    Resume(RESUME_ESOF); /* request without change of the machine state */
+
+#ifdef ESOF_CALLBACK
+    ESOF_Callback();
+#endif
+  }
+#endif
+} /* USB_Istr */
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#else /* STM32F10X_CL */
+
+
+/*******************************************************************************
+* Function Name  : STM32_PCD_OTG_ISR_Handler
+* Description    : Handles all USB Device Interrupts
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+u32 STM32_PCD_OTG_ISR_Handler (void)
+{
+  USB_OTG_GINTSTS_TypeDef gintr_status;
+  u32 retval = 0;
+
+  if (USBD_FS_IsDeviceMode()) /* ensure that we are in device mode */
+  {
+    gintr_status.d32 = OTGD_FS_ReadCoreItr();
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    
+    /* If there is no interrupt pending exit the interrupt routine */
+    if (!gintr_status.d32)
+    {
+      return 0;
+    }
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Early Suspend interrupt */ 
+#ifdef INTR_ERLYSUSPEND
+    if (gintr_status.b.erlysuspend)
+    {
+      retval |= OTGD_FS_Handle_EarlySuspend_ISR();
+    }
+#endif /* INTR_ERLYSUSPEND */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* End of Periodic Frame interrupt */
+#ifdef INTR_EOPFRAME    
+    if (gintr_status.b.eopframe)
+    {
+      retval |= OTGD_FS_Handle_EOPF_ISR();
+    }
+#endif /* INTR_EOPFRAME */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Non Periodic Tx FIFO Empty interrupt */
+#ifdef INTR_NPTXFEMPTY    
+    if (gintr_status.b.nptxfempty)
+    {
+      retval |= OTGD_FS_Handle_NPTxFE_ISR();
+    }
+#endif /* INTR_NPTXFEMPTY */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Wakeup or RemoteWakeup interrupt */
+#ifdef INTR_WKUPINTR    
+    if (gintr_status.b.wkupintr)
+    {   
+      retval |= OTGD_FS_Handle_Wakeup_ISR();
+    }
+#endif /* INTR_WKUPINTR */   
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Suspend interrupt */
+#ifdef INTR_USBSUSPEND
+    if (gintr_status.b.usbsuspend)
+    { 
+      /* check if SUSPEND is possible */
+      if (fSuspendEnabled)
+      {
+        Suspend();
+      }
+      else
+      {
+        /* if not possible then resume after xx ms */
+        Resume(RESUME_LATER); /* This case shouldn't happen in OTG Device mode because 
+        there's no ESOF interrupt to increment the ResumeS.bESOFcnt in the Resume state machine */
+      }
+            
+      retval |= OTGD_FS_Handle_USBSuspend_ISR();
+    }
+#endif /* INTR_USBSUSPEND */
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Start of Frame interrupt */
+#ifdef INTR_SOFINTR    
+    if (gintr_status.b.sofintr)
+    {
+      /* Update the frame number variable */
+      bIntPackSOF++;
+      
+      retval |= OTGD_FS_Handle_Sof_ISR();
+    }
+#endif /* INTR_SOFINTR */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Receive FIFO Queue Status Level interrupt */
+#ifdef INTR_RXSTSQLVL
+    if (gintr_status.b.rxstsqlvl)
+    {
+      retval |= OTGD_FS_Handle_RxStatusQueueLevel_ISR();
+    }
+#endif /* INTR_RXSTSQLVL */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Enumeration Done interrupt */
+#ifdef INTR_ENUMDONE
+    if (gintr_status.b.enumdone)
+    {
+      retval |= OTGD_FS_Handle_EnumDone_ISR();
+    }
+#endif /* INTR_ENUMDONE */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* Reset interrupt */
+#ifdef INTR_USBRESET
+    if (gintr_status.b.usbreset)
+    {
+      retval |= OTGD_FS_Handle_UsbReset_ISR();
+    }    
+#endif /* INTR_USBRESET */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+    /* IN Endpoint interrupt */
+#ifdef INTR_INEPINTR
+    if (gintr_status.b.inepint)
+    {
+      retval |= OTGD_FS_Handle_InEP_ISR();
+    }
+#endif /* INTR_INEPINTR */
+    
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* OUT Endpoint interrupt */
+#ifdef INTR_OUTEPINTR
+    if (gintr_status.b.outepintr)
+    {
+      retval |= OTGD_FS_Handle_OutEP_ISR();
+    }
+#endif /* INTR_OUTEPINTR */    
+ 
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Mode Mismatch interrupt */
+#ifdef INTR_MODEMISMATCH
+    if (gintr_status.b.modemismatch)
+    {
+      retval |= OTGD_FS_Handle_ModeMismatch_ISR();
+    }
+#endif /* INTR_MODEMISMATCH */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Global IN Endpoints NAK Effective interrupt */
+#ifdef INTR_GINNAKEFF
+    if (gintr_status.b.ginnakeff)
+    {
+      retval |= OTGD_FS_Handle_GInNakEff_ISR();
+    }
+#endif /* INTR_GINNAKEFF */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Global OUT Endpoints NAK effective interrupt */
+#ifdef INTR_GOUTNAKEFF
+    if (gintr_status.b.goutnakeff)
+    {
+      retval |= OTGD_FS_Handle_GOutNakEff_ISR();
+    }
+#endif /* INTR_GOUTNAKEFF */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Isochronous Out packet Dropped interrupt */
+#ifdef INTR_ISOOUTDROP
+    if (gintr_status.b.isooutdrop)
+    {
+      retval |= OTGD_FS_Handle_IsoOutDrop_ISR();
+    }
+#endif /* INTR_ISOOUTDROP */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Endpoint Mismatch error interrupt */
+#ifdef INTR_EPMISMATCH
+    if (gintr_status.b.epmismatch)
+    {
+      retval |= OTGD_FS_Handle_EPMismatch_ISR();
+    }
+#endif /* INTR_EPMISMATCH */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Incomplete Isochronous IN transfer error interrupt */
+#ifdef INTR_INCOMPLISOIN
+    if (gintr_status.b.incomplisoin)
+    {
+      retval |= OTGD_FS_Handle_IncomplIsoIn_ISR();
+    }
+#endif /* INTR_INCOMPLISOIN */  
+
+   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/    
+    /* Incomplete Isochronous OUT transfer error interrupt */
+#ifdef INTR_INCOMPLISOOUT
+    if (gintr_status.b.outepintr)
+    {
+      retval |= OTGD_FS_Handle_IncomplIsoOut_ISR();
+    }
+#endif /* INTR_INCOMPLISOOUT */  
+  
+  }
+  return retval;
+}
+
+#endif /* STM32F10X_CL */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_istr.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,121 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_istr.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : This file includes the peripherals header files in the
+*                      user application.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_ISTR_H
+#define __USB_ISTR_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#ifndef STM32F10X_CL
+ void USB_Istr(void);
+#else /* STM32F10X_CL */
+ u32 STM32_PCD_OTG_ISR_Handler(void);
+#endif /* STM32F10X_CL */
+
+/* function prototypes Automatically built defining related macros */
+
+void EP1_IN_Callback(void);
+void EP2_IN_Callback(void);
+void EP3_IN_Callback(void);
+void EP4_IN_Callback(void);
+void EP5_IN_Callback(void);
+void EP6_IN_Callback(void);
+void EP7_IN_Callback(void);
+
+void EP1_OUT_Callback(void);
+void EP2_OUT_Callback(void);
+void EP3_OUT_Callback(void);
+void EP4_OUT_Callback(void);
+void EP5_OUT_Callback(void);
+void EP6_OUT_Callback(void);
+void EP7_OUT_Callback(void);
+
+#ifndef STM32F10X_CL
+
+#ifdef CTR_CALLBACK
+void CTR_Callback(void);
+#endif
+
+#ifdef DOVR_CALLBACK
+void DOVR_Callback(void);
+#endif
+
+#ifdef ERR_CALLBACK
+void ERR_Callback(void);
+#endif
+
+#ifdef WKUP_CALLBACK
+void WKUP_Callback(void);
+#endif
+
+#ifdef SUSP_CALLBACK
+void SUSP_Callback(void);
+#endif
+
+#ifdef RESET_CALLBACK
+void RESET_Callback(void);
+#endif
+
+#ifdef SOF_CALLBACK
+void SOF_Callback(void);
+#endif
+
+#ifdef ESOF_CALLBACK
+void ESOF_Callback(void);
+#endif
+
+#else /* STM32F10X_CL */
+
+/* Interrupt subroutines user callbacks prototypes.
+   These callbacks are called into the respective interrupt subroutine functions
+   and can be tailored for various user application purposes.
+     Note: Make sure that the correspondent interrupt is enabled through the 
+     definition in usb_conf.h file */ 
+void INTR_MODEMISMATCH_Callback(void);
+void INTR_SOFINTR_Callback(void);
+void INTR_RXSTSQLVL_Callback(void);
+void INTR_NPTXFEMPTY_Callback(void);
+void INTR_GINNAKEFF_Callback(void);
+void INTR_GOUTNAKEFF_Callback(void);
+void INTR_ERLYSUSPEND_Callback(void);
+void INTR_USBSUSPEND_Callback(void);
+void INTR_USBRESET_Callback(void);
+void INTR_ENUMDONE_Callback(void);
+void INTR_ISOOUTDROP_Callback(void);
+void INTR_EOPFRAME_Callback(void);
+void INTR_EPMISMATCH_Callback(void);
+void INTR_INEPINTR_Callback(void);
+void INTR_OUTEPINTR_Callback(void);
+void INTR_INCOMPLISOIN_Callback(void);
+void INTR_INCOMPLISOOUT_Callback(void);
+void INTR_WKUPINTR_Callback(void);
+
+/* Isochronous data update */
+void INTR_RXSTSQLVL_ISODU_Callback(void); 
+
+#endif /* STM32F10X_CL */
+
+
+#endif /*__USB_ISTR_H*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_prop.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,418 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_prop.c
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : All processing related to Virtual Com Port Demo
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_conf.h"
+#include "usb_prop.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+#include "hw_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint8_t Request = 0;
+
+LINE_CODING linecoding =
+  {
+    115200, /* baud rate*/
+    0x00,   /* stop bits-1*/
+    0x00,   /* parity - none*/
+    0x08    /* no. of bits 8*/
+  };
+
+/* -------------------------------------------------------------------------- */
+/*  Structures initializations */
+/* -------------------------------------------------------------------------- */
+
+DEVICE Device_Table =
+  {
+    EP_NUM,
+    1
+  };
+
+DEVICE_PROP Device_Property =
+  {
+    Virtual_Com_Port_init,
+    Virtual_Com_Port_Reset,
+    Virtual_Com_Port_Status_In,
+    Virtual_Com_Port_Status_Out,
+    Virtual_Com_Port_Data_Setup,
+    Virtual_Com_Port_NoData_Setup,
+    Virtual_Com_Port_Get_Interface_Setting,
+    Virtual_Com_Port_GetDeviceDescriptor,
+    Virtual_Com_Port_GetConfigDescriptor,
+    Virtual_Com_Port_GetStringDescriptor,
+    0,
+    0x40 /*MAX PACKET SIZE*/
+  };
+
+USER_STANDARD_REQUESTS User_Standard_Requests =
+  {
+    Virtual_Com_Port_GetConfiguration,
+    Virtual_Com_Port_SetConfiguration,
+    Virtual_Com_Port_GetInterface,
+    Virtual_Com_Port_SetInterface,
+    Virtual_Com_Port_GetStatus,
+    Virtual_Com_Port_ClearFeature,
+    Virtual_Com_Port_SetEndPointFeature,
+    Virtual_Com_Port_SetDeviceFeature,
+    Virtual_Com_Port_SetDeviceAddress
+  };
+
+ONE_DESCRIPTOR Device_Descriptor =
+  {
+    (uint8_t*)Virtual_Com_Port_DeviceDescriptor,
+    VIRTUAL_COM_PORT_SIZ_DEVICE_DESC
+  };
+
+ONE_DESCRIPTOR Config_Descriptor =
+  {
+    (uint8_t*)Virtual_Com_Port_ConfigDescriptor,
+    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC
+  };
+
+ONE_DESCRIPTOR String_Descriptor[4] =
+  {
+    {(uint8_t*)Virtual_Com_Port_StringLangID, VIRTUAL_COM_PORT_SIZ_STRING_LANGID},
+    {(uint8_t*)Virtual_Com_Port_StringVendor, VIRTUAL_COM_PORT_SIZ_STRING_VENDOR},
+    {(uint8_t*)Virtual_Com_Port_StringProduct, VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT},
+    {(uint8_t*)Virtual_Com_Port_StringSerial, VIRTUAL_COM_PORT_SIZ_STRING_SERIAL}
+  };
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_init.
+* Description    : Virtual COM Port Mouse init routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_init(void)
+{
+
+  /* Update the serial number string descriptor with the data from the unique
+  ID*/
+  Get_SerialNum();
+
+  pInformation->Current_Configuration = 0;
+
+  /* Connect the device */
+  PowerOn();
+
+  /* Perform basic device initialization operations */
+  USB_SIL_Init();
+
+  ///* configure the USART to the default settings */
+  //USART_Config_Default();
+
+  bDeviceState = UNCONNECTED;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_Reset
+* Description    : Virtual_Com_Port Mouse reset routine
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_Reset(void)
+{
+  /* Set Virtual_Com_Port DEVICE as not configured */
+  pInformation->Current_Configuration = 0;
+
+  /* Current Feature initialization */
+  pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];
+
+  /* Set Virtual_Com_Port DEVICE with the default Interface*/
+  pInformation->Current_Interface = 0;
+
+#ifdef STM32F10X_CL     
+  /* EP0 is already configured by USB_SIL_Init() function */
+  
+  /* Init EP1 IN as Bulk endpoint */
+  OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_BULK, VIRTUAL_COM_PORT_DATA_SIZE);
+  
+  /* Init EP2 IN as Interrupt endpoint */
+  OTG_DEV_EP_Init(EP2_IN, OTG_DEV_EP_TYPE_INT, VIRTUAL_COM_PORT_INT_SIZE);
+
+  /* Init EP3 OUT as Bulk endpoint */
+  OTG_DEV_EP_Init(EP3_OUT, OTG_DEV_EP_TYPE_BULK, VIRTUAL_COM_PORT_DATA_SIZE);  
+#else 
+
+  SetBTABLE(BTABLE_ADDRESS);
+
+  /* Initialize Endpoint 0 */
+  SetEPType(ENDP0, EP_CONTROL);
+  SetEPTxStatus(ENDP0, EP_TX_STALL);
+  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
+  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
+  Clear_Status_Out(ENDP0);
+  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+  SetEPRxValid(ENDP0);
+
+  /* Initialize Endpoint 1 */
+  SetEPType(ENDP1, EP_BULK);
+  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
+  SetEPTxStatus(ENDP1, EP_TX_NAK);
+  SetEPRxStatus(ENDP1, EP_RX_DIS);
+
+  /* Initialize Endpoint 2 */
+  SetEPType(ENDP2, EP_INTERRUPT);
+  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
+  SetEPRxStatus(ENDP2, EP_RX_DIS);
+  SetEPTxStatus(ENDP2, EP_TX_NAK);
+
+  /* Initialize Endpoint 3 */
+  SetEPType(ENDP3, EP_BULK);
+  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
+  SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE);
+  SetEPRxStatus(ENDP3, EP_RX_VALID);
+  SetEPTxStatus(ENDP3, EP_TX_DIS);
+
+  /* Set this device to response on default address */
+  SetDeviceAddress(0);
+#endif /* STM32F10X_CL */
+
+  bDeviceState = ATTACHED;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_SetConfiguration.
+* Description    : Update the device state to configured.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_SetConfiguration(void)
+{
+  DEVICE_INFO *pInfo = &Device_Info;
+
+  if (pInfo->Current_Configuration != 0)
+  {
+    /* Device configured */
+    bDeviceState = CONFIGURED;
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_SetConfiguration.
+* Description    : Update the device state to addressed.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_SetDeviceAddress (void)
+{
+  bDeviceState = ADDRESSED;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_Status_In.
+* Description    : Virtual COM Port Status In Routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_Status_In(void)
+{
+  if (Request == SET_LINE_CODING)
+  {
+    Request = 0;
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_Status_Out
+* Description    : Virtual COM Port Status OUT Routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Virtual_Com_Port_Status_Out(void)
+{}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_Data_Setup
+* Description    : handle the data class specific requests
+* Input          : Request Nb.
+* Output         : None.
+* Return         : USB_UNSUPPORT or USB_SUCCESS.
+*******************************************************************************/
+RESULT Virtual_Com_Port_Data_Setup(uint8_t RequestNo)
+{
+  uint8_t    *(*CopyRoutine)(uint16_t);
+
+  CopyRoutine = NULL;
+
+  if (RequestNo == GET_LINE_CODING)
+  {
+    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+    {
+      CopyRoutine = Virtual_Com_Port_GetLineCoding;
+    }
+  }
+  else if (RequestNo == SET_LINE_CODING)
+  {
+    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+    {
+      CopyRoutine = Virtual_Com_Port_SetLineCoding;
+    }
+    Request = SET_LINE_CODING;
+  }
+
+  if (CopyRoutine == NULL)
+  {
+    return USB_UNSUPPORT;
+  }
+
+  pInformation->Ctrl_Info.CopyData = CopyRoutine;
+  pInformation->Ctrl_Info.Usb_wOffset = 0;
+  (*CopyRoutine)(0);
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_NoData_Setup.
+* Description    : handle the no data class specific requests.
+* Input          : Request Nb.
+* Output         : None.
+* Return         : USB_UNSUPPORT or USB_SUCCESS.
+*******************************************************************************/
+RESULT Virtual_Com_Port_NoData_Setup(uint8_t RequestNo)
+{
+
+  if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+  {
+    if (RequestNo == SET_COMM_FEATURE)
+    {
+      return USB_SUCCESS;
+    }
+    else if (RequestNo == SET_CONTROL_LINE_STATE)
+    {
+      return USB_SUCCESS;
+    }
+  }
+
+  return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_GetDeviceDescriptor.
+* Description    : Gets the device descriptor.
+* Input          : Length.
+* Output         : None.
+* Return         : The address of the device descriptor.
+*******************************************************************************/
+uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t Length)
+{
+  return Standard_GetDescriptorData(Length, &Device_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_GetConfigDescriptor.
+* Description    : get the configuration descriptor.
+* Input          : Length.
+* Output         : None.
+* Return         : The address of the configuration descriptor.
+*******************************************************************************/
+uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t Length)
+{
+  return Standard_GetDescriptorData(Length, &Config_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_GetStringDescriptor
+* Description    : Gets the string descriptors according to the needed index
+* Input          : Length.
+* Output         : None.
+* Return         : The address of the string descriptors.
+*******************************************************************************/
+uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t Length)
+{
+  uint8_t wValue0 = pInformation->USBwValue0;
+  if (wValue0 > 4)
+  {
+    return NULL;
+  }
+  else
+  {
+    return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_Get_Interface_Setting.
+* Description    : test the interface and the alternate setting according to the
+*                  supported one.
+* Input1         : uint8_t: Interface : interface number.
+* Input2         : uint8_t: AlternateSetting : Alternate Setting number.
+* Output         : None.
+* Return         : The address of the string descriptors.
+*******************************************************************************/
+RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
+{
+  if (AlternateSetting > 0)
+  {
+    return USB_UNSUPPORT;
+  }
+  else if (Interface > 1)
+  {
+    return USB_UNSUPPORT;
+  }
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_GetLineCoding.
+* Description    : send the linecoding structure to the PC host.
+* Input          : Length.
+* Output         : None.
+* Return         : Linecoding structure base address.
+*******************************************************************************/
+uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
+    return NULL;
+  }
+  return(uint8_t *)&linecoding;
+}
+
+/*******************************************************************************
+* Function Name  : Virtual_Com_Port_SetLineCoding.
+* Description    : Set the linecoding structure fields.
+* Input          : Length.
+* Output         : None.
+* Return         : Linecoding structure base address.
+*******************************************************************************/
+uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
+    return NULL;
+  }
+  return(uint8_t *)&linecoding;
+}
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_prop.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,74 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_prop.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : All processing related to Virtual COM Port Demo (Endpoint 0)
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __usb_prop_H
+#define __usb_prop_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+  uint32_t bitrate;
+  uint8_t format;
+  uint8_t paritytype;
+  uint8_t datatype;
+}LINE_CODING;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+
+#define Virtual_Com_Port_GetConfiguration          NOP_Process
+//#define Virtual_Com_Port_SetConfiguration          NOP_Process
+#define Virtual_Com_Port_GetInterface              NOP_Process
+#define Virtual_Com_Port_SetInterface              NOP_Process
+#define Virtual_Com_Port_GetStatus                 NOP_Process
+#define Virtual_Com_Port_ClearFeature              NOP_Process
+#define Virtual_Com_Port_SetEndPointFeature        NOP_Process
+#define Virtual_Com_Port_SetDeviceFeature          NOP_Process
+//#define Virtual_Com_Port_SetDeviceAddress          NOP_Process
+
+#define SEND_ENCAPSULATED_COMMAND   0x00
+#define GET_ENCAPSULATED_RESPONSE   0x01
+#define SET_COMM_FEATURE            0x02
+#define GET_COMM_FEATURE            0x03
+#define CLEAR_COMM_FEATURE          0x04
+#define SET_LINE_CODING             0x20
+#define GET_LINE_CODING             0x21
+#define SET_CONTROL_LINE_STATE      0x22
+#define SEND_BREAK                  0x23
+
+/* Exported functions ------------------------------------------------------- */
+void Virtual_Com_Port_init(void);
+void Virtual_Com_Port_Reset(void);
+void Virtual_Com_Port_SetConfiguration(void);
+void Virtual_Com_Port_SetDeviceAddress (void);
+void Virtual_Com_Port_Status_In (void);
+void Virtual_Com_Port_Status_Out (void);
+RESULT Virtual_Com_Port_Data_Setup(uint8_t);
+RESULT Virtual_Com_Port_NoData_Setup(uint8_t);
+RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
+uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t );
+uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t);
+uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t);
+
+uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length);
+uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length);
+
+#endif /* __usb_prop_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_pwr.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,256 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_pwr.c
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Connection/disconnection & power management
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#ifdef STM32L1XX_MD
+ #include "stm32l1xx.h"
+#else
+ #include "stm32f10x.h"
+#endif /* STM32L1XX_MD */
+ 
+#include "usb_lib.h"
+#include "usb_conf.h"
+#include "usb_pwr.h"
+#include "hw_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
+__IO bool fSuspendEnabled = TRUE;  /* true when suspend is possible */
+
+struct
+{
+  __IO RESUME_STATE eState;
+  __IO uint8_t bESOFcnt;
+}ResumeS;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : PowerOn
+* Description    :
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOn(void)
+{
+#ifndef STM32F10X_CL
+  uint16_t wRegVal;
+
+  /*** cable plugged-in ? ***/
+  USB_Cable_Config(ENABLE);
+
+  /*** CNTR_PWDN = 0 ***/
+  wRegVal = CNTR_FRES;
+  _SetCNTR(wRegVal);
+
+  /*** CNTR_FRES = 0 ***/
+  wInterrupt_Mask = 0;
+  _SetCNTR(wInterrupt_Mask);
+  /*** Clear pending interrupts ***/
+  _SetISTR(0);
+  /*** Set interrupt mask ***/
+  wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
+  _SetCNTR(wInterrupt_Mask);
+#endif /* STM32F10X_CL */
+
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : PowerOff
+* Description    : handles switch-off conditions
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOff()
+{
+#ifndef STM32F10X_CL
+  /* disable all interrupts and force USB reset */
+  _SetCNTR(CNTR_FRES);
+  /* clear interrupt status register */
+  _SetISTR(0);
+  /* Disable the Pull-Up*/
+  USB_Cable_Config(DISABLE);
+  /* switch-off device */
+  _SetCNTR(CNTR_FRES + CNTR_PDWN);
+#endif /* STM32F10X_CL */
+
+  /* sw variables reset */
+  /* ... */
+
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Suspend
+* Description    : sets suspend mode operating conditions
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+void Suspend(void)
+{
+#ifndef STM32F10X_CL
+  uint16_t wCNTR;
+  /* suspend preparation */
+  /* ... */
+
+  /* macrocell enters suspend mode */
+  wCNTR = _GetCNTR();
+  wCNTR |= CNTR_FSUSP;
+  _SetCNTR(wCNTR);
+#endif /* STM32F10X_CL */
+
+  /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
+  /* power reduction */
+  /* ... on connected devices */
+
+#ifndef STM32F10X_CL
+  /* force low-power mode in the macrocell */
+  wCNTR = _GetCNTR();
+  wCNTR |= CNTR_LPMODE;
+  _SetCNTR(wCNTR);
+#endif /* STM32F10X_CL */
+
+  /* switch-off the clocks */
+  /* ... */
+  Enter_LowPowerMode();
+
+}
+
+/*******************************************************************************
+* Function Name  : Resume_Init
+* Description    : Handles wake-up restoring normal operations
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+void Resume_Init(void)
+{
+#ifndef STM32F10X_CL
+  uint16_t wCNTR;
+#endif /* STM32F10X_CL */ 
+
+  /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
+  /* restart the clocks */
+  /* ...  */
+
+#ifndef STM32F10X_CL
+  /* CNTR_LPMODE = 0 */
+  wCNTR = _GetCNTR();
+  wCNTR &= (~CNTR_LPMODE);
+  _SetCNTR(wCNTR);
+#endif /* STM32F10X_CL */ 
+
+  /* restore full power */
+  /* ... on connected devices */
+  Leave_LowPowerMode();
+
+#ifndef STM32F10X_CL
+  /* reset FSUSP bit */
+  _SetCNTR(IMR_MSK);
+#endif /* STM32F10X_CL */
+
+  /* reverse suspend preparation */
+  /* ... */
+
+}
+
+/*******************************************************************************
+* Function Name  : Resume
+* Description    : This is the state machine handling resume operations and
+*                 timing sequence. The control is based on the Resume structure
+*                 variables and on the ESOF interrupt calling this subroutine
+*                 without changing machine state.
+* Input          : a state machine value (RESUME_STATE)
+*                  RESUME_ESOF doesn't change ResumeS.eState allowing
+*                  decrementing of the ESOF counter in different states.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Resume(RESUME_STATE eResumeSetVal)
+{
+#ifndef STM32F10X_CL
+  uint16_t wCNTR;
+#endif /* STM32F10X_CL */
+
+  if (eResumeSetVal != RESUME_ESOF)
+    ResumeS.eState = eResumeSetVal;
+
+  switch (ResumeS.eState)
+  {
+    case RESUME_EXTERNAL:
+      Resume_Init();
+      ResumeS.eState = RESUME_OFF;
+      break;
+    case RESUME_INTERNAL:
+      Resume_Init();
+      ResumeS.eState = RESUME_START;
+      break;
+    case RESUME_LATER:
+      ResumeS.bESOFcnt = 2;
+      ResumeS.eState = RESUME_WAIT;
+      break;
+    case RESUME_WAIT:
+      ResumeS.bESOFcnt--;
+      if (ResumeS.bESOFcnt == 0)
+        ResumeS.eState = RESUME_START;
+      break;
+    case RESUME_START:
+     #ifdef STM32F10X_CL
+      OTGD_FS_SetRemoteWakeup();
+     #else 
+      wCNTR = _GetCNTR();
+      wCNTR |= CNTR_RESUME;
+      _SetCNTR(wCNTR);
+     #endif /* STM32F10X_CL */
+      ResumeS.eState = RESUME_ON;
+      ResumeS.bESOFcnt = 10;
+      break;
+    case RESUME_ON:
+    #ifndef STM32F10X_CL      
+      ResumeS.bESOFcnt--;
+      if (ResumeS.bESOFcnt == 0)
+      {
+     #endif /* STM32F10X_CL */    
+       #ifdef STM32F10X_CL
+        OTGD_FS_ResetRemoteWakeup();
+       #else
+        wCNTR = _GetCNTR();
+        wCNTR &= (~CNTR_RESUME);
+        _SetCNTR(wCNTR);
+       #endif /* STM32F10X_CL */
+        ResumeS.eState = RESUME_OFF;
+     #ifndef STM32F10X_CL
+      }
+     #endif /* STM32F10X_CL */
+      break;
+    case RESUME_OFF:
+    case RESUME_ESOF:
+    default:
+      ResumeS.eState = RESUME_OFF;
+      break;
+  }
+}
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb/usb_pwr.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,59 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : usb_pwr.h
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Connection/disconnection & power management header
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_PWR_H
+#define __USB_PWR_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _RESUME_STATE
+{
+  RESUME_EXTERNAL,
+  RESUME_INTERNAL,
+  RESUME_LATER,
+  RESUME_WAIT,
+  RESUME_START,
+  RESUME_ON,
+  RESUME_OFF,
+  RESUME_ESOF
+} RESUME_STATE;
+
+typedef enum _DEVICE_STATE
+{
+  UNCONNECTED,
+  ATTACHED,
+  POWERED,
+  SUSPENDED,
+  ADDRESSED,
+  CONFIGURED
+} DEVICE_STATE;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void Suspend(void);
+void Resume_Init(void);
+void Resume(RESUME_STATE eResumeSetVal);
+RESULT PowerOn(void);
+RESULT PowerOff(void);
+
+/* External variables --------------------------------------------------------*/
+extern  __IO uint32_t bDeviceState; /* USB device status */
+extern __IO bool fSuspendEnabled;  /* true when suspend is possible */
+
+#endif  /*__USB_PWR_H*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Entries	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,3 @@
+/stm32eeprom.h/1.1/Sun Jul  3 23:54:54 2016//
+/stm32f10x_it.c/1.1/Tue Mar  8 07:10:30 2016//
+D
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Entries.Extra	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2 @@
+/stm32eeprom.h///1470196397/
+/stm32f10x_it.c///1470196397/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Entries.Extra.Old	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,2 @@
+/stm32f10x_it.c////
+/stm32eeprom.h////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Entries.Old	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,3 @@
+/stm32f10x_it.c/0/Initial stm32f10x_it.c//
+/stm32eeprom.h/0/Initial stm32eeprom.h//
+D
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Repository	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1 @@
+Code/grbl1.0d/stm32grbl/util
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/CVS/Root	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,1 @@
+:local:E:/CVSRep
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/stm32eeprom.h	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,43 @@
+/**
+  ******************************************************************************
+  * @file    EEPROM_Emulation/inc/eeprom.h 
+  * @author  MCD Application Team
+  * @version V3.1.0
+  * @date    07/27/2009
+  * @brief   This file contains all the functions prototypes for the EEPROM 
+  *          emulation firmware library.
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __EEPROM_H
+#define __EEPROM_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_flash.h"
+
+/* Exported constants --------------------------------------------------------*/
+/* Define the STM32F10Xxx Flash page size depending on the used STM32 device */
+#if defined (STM32F10X_LD) || defined (STM32F10X_MD)
+  #define PAGE_SIZE  (uint16_t)0x400  /* Page size = 1KByte */
+#elif defined (STM32F10X_HD) || defined (STM32F10X_CL)
+  #define PAGE_SIZE  (uint16_t)0x800  /* Page size = 2KByte */
+#endif
+
+/* EEPROM start address in Flash */
+#define EEPROM_START_ADDRESS    ((uint32_t)0x0801fc00) /* EEPROM emulation start address:
+                                                  after 64KByte of used Flash memory */
+
+#endif /* __EEPROM_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/stm32f10x_it.c	Mon Sep 04 12:05:05 2017 +0000
@@ -0,0 +1,228 @@
+/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
+* File Name          : stm32f10x_it.c
+* Author             : MCD Application Team
+* Version            : V3.3.0
+* Date               : 21-March-2011
+* Description        : Main Interrupt Service Routines.
+*                      This file provides template for all exceptions handler
+*                      and peripherals interrupt service routine.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifdef USEUSB
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_it.h"
+#include "usb_lib.h"
+#include "usb_istr.h"
+#include "hw_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/******************************************************************************/
+/*            Cortex-M3 Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/*******************************************************************************
+* Function Name  : NMI_Handler
+* Description    : This function handles NMI exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void NMI_Handler(void)
+{
+}
+
+/*******************************************************************************
+* Function Name  : HardFault_Handler
+* Description    : This function handles Hard Fault exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/*******************************************************************************
+* Function Name  : MemManage_Handler
+* Description    : This function handles Memory Manage exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void MemManage_Handler(void)
+{
+  /* Go to infinite loop when Memory Manage exception occurs */
+  while (1)
+  {
+  }
+}
+
+/*******************************************************************************
+* Function Name  : BusFault_Handler
+* Description    : This function handles Bus Fault exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void BusFault_Handler(void)
+{
+  /* Go to infinite loop when Bus Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/*******************************************************************************
+* Function Name  : UsageFault_Handler
+* Description    : This function handles Usage Fault exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void UsageFault_Handler(void)
+{
+  /* Go to infinite loop when Usage Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/*******************************************************************************
+* Function Name  : SVC_Handler
+* Description    : This function handles SVCall exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void SVC_Handler(void)
+{
+}
+
+/*******************************************************************************
+* Function Name  : DebugMon_Handler
+* Description    : This function handles Debug Monitor exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void DebugMon_Handler(void)
+{
+}
+
+/*******************************************************************************
+* Function Name  : PendSV_Handler
+* Description    : This function handles PendSVC exception.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void PendSV_Handler(void)
+{
+}
+
+/*******************************************************************************
+* Function Name  : SysTick_Handler
+* Description    : This function handles SysTick Handler.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+#if 0
+void SysTick_Handler(void)
+{
+}
+#endif
+/******************************************************************************/
+/*            STM32F10x Peripherals Interrupt Handlers                        */
+/******************************************************************************/
+
+#ifndef STM32F10X_CL
+/*******************************************************************************
+* Function Name  : USB_LP_CAN1_RX0_IRQHandler
+* Description    : This function handles USB Low Priority or CAN RX0 interrupts
+*                  requests.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void USB_LP_CAN1_RX0_IRQHandler(void)
+{
+  USB_Istr();
+}
+#endif /* STM32F10X_CL */
+
+/*******************************************************************************
+* Function Name  : EVAL_COM1_IRQHandler
+* Description    : This function handles EVAL_COM1 global interrupt request.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void EVAL_COM1_IRQHandler(void)
+{
+#if 0
+if (USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)
+  {
+    /* Send the received data to the PC Host*/
+    USART_To_USB_Send_Data();
+  }
+
+  /* If overrun condition occurs, clear the ORE flag and recover communication */
+  if (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)
+  {
+    (void)USART_ReceiveData(EVAL_COM1);
+  }
+#endif
+}
+
+
+#ifdef STM32F10X_CL
+/*******************************************************************************
+* Function Name  : OTG_FS_IRQHandler
+* Description    : This function handles USB-On-The-Go FS global interrupt request.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void OTG_FS_IRQHandler(void)
+{
+  STM32_PCD_OTG_ISR_Handler(); 
+}
+#endif /* STM32F10X_CL */
+
+/******************************************************************************/
+/*                 STM32F10x Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f10x_xx.s).                                            */
+/******************************************************************************/
+
+/*******************************************************************************
+* Function Name  : PPP_IRQHandler
+* Description    : This function handles PPP interrupt request.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+/*void PPP_IRQHandler(void)
+{
+}*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+#endif