aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/.gitignore2
-rw-r--r--docs/Makefile134
-rw-r--r--docs/README24
-rw-r--r--docs/README-building.txt105
-rw-r--r--docs/README-maintainers.txt215
-rwxr-xr-xdocs/copy-to-ide9
-rw-r--r--docs/make.bat155
-rw-r--r--docs/source/_static/.gitignore0
-rw-r--r--docs/source/_static/breathe.css1
-rw-r--r--docs/source/_static/img/blinky-to-flash.pngbin0 -> 22657 bytes
-rw-r--r--docs/source/_static/img/blinky.pngbin0 -> 21042 bytes
-rw-r--r--docs/source/_static/img/button-new.pngbin0 -> 234 bytes
-rw-r--r--docs/source/_static/img/button-open.pngbin0 -> 259 bytes
-rw-r--r--docs/source/_static/img/button-save.pngbin0 -> 253 bytes
-rw-r--r--docs/source/_static/img/button-serial-monitor.pngbin0 -> 249 bytes
-rw-r--r--docs/source/_static/img/button-stop.pngbin0 -> 294 bytes
-rw-r--r--docs/source/_static/img/button-upload.pngbin0 -> 291 bytes
-rw-r--r--docs/source/_static/img/button-verify.pngbin0 -> 326 bytes
-rw-r--r--docs/source/_static/img/codeblocks_build.pngbin0 -> 112088 bytes
-rw-r--r--docs/source/_static/img/codeblocks_makefile.pngbin0 -> 75653 bytes
-rw-r--r--docs/source/_static/img/codeblocks_maketargets.pngbin0 -> 56250 bytes
-rw-r--r--docs/source/_static/img/codeblocks_newproject.pngbin0 -> 45930 bytes
-rw-r--r--docs/source/_static/img/github-clone-in-windows.pngbin0 -> 3899 bytes
-rw-r--r--docs/source/_static/img/ide-blinky.pngbin0 -> 29213 bytes
-rw-r--r--docs/source/_static/img/jtag-wiring.pngbin0 -> 33637 bytes
-rw-r--r--docs/source/_static/img/osx-network-prefs-unconfigured.pngbin0 -> 81770 bytes
-rw-r--r--docs/source/_static/img/osx-unconfigured-popup.pngbin0 -> 28359 bytes
-rw-r--r--docs/source/_static/img/round_logo_32x32.icobin0 -> 4286 bytes
-rw-r--r--docs/source/_static/img/round_logo_60x60.pngbin0 -> 5552 bytes
-rw-r--r--docs/source/_static/img/serial-monitor.pngbin0 -> 55975 bytes
-rw-r--r--docs/source/_static/img/serial-port-mac.pngbin0 -> 64284 bytes
-rw-r--r--docs/source/_static/img/serial-port-ubuntu.pngbin0 -> 46629 bytes
-rw-r--r--docs/source/_static/img/serial-port-win.pngbin0 -> 15183 bytes
-rw-r--r--docs/source/_static/img/upload-button.pngbin0 -> 9993 bytes
-rw-r--r--docs/source/_static/img/verify-success.pngbin0 -> 26460 bytes
-rw-r--r--docs/source/_static/img/verify_button.pngbin0 -> 1800 bytes
-rw-r--r--docs/source/_static/img/win7-copy-arm-bin-address.pngbin0 -> 31648 bytes
-rw-r--r--docs/source/_static/img/win7-copy-python-address.pngbin0 -> 20500 bytes
-rw-r--r--docs/source/_static/img/win7-github-open-in-explorer.pngbin0 -> 29280 bytes
-rw-r--r--docs/source/_static/img/win7-python-arm-bin-path.pngbin0 -> 8196 bytes
-rw-r--r--docs/source/_static/img/win7-python-path.pngbin0 -> 6912 bytes
-rw-r--r--docs/source/_static/img/win7-python-prompt.pngbin0 -> 9796 bytes
-rw-r--r--docs/source/_static/index-style.css19
-rw-r--r--docs/source/_static/leaflabs-docs.css1
-rw-r--r--docs/source/_templates/.gitignore0
-rw-r--r--docs/source/_templates/indexcontent.html117
-rw-r--r--docs/source/_templates/layout.html11
-rw-r--r--docs/source/adc.rst104
-rw-r--r--docs/source/arduino-cc-attribution.txt9
-rw-r--r--docs/source/arduino-compatibility.rst275
-rw-r--r--docs/source/arm-gcc.rst107
-rw-r--r--docs/source/bootloader.rst750
-rw-r--r--docs/source/conf.py283
-rw-r--r--docs/source/contents.rst73
-rw-r--r--docs/source/epilog.rst14
-rw-r--r--docs/source/external-interrupts.rst68
-rw-r--r--docs/source/faq.rst115
-rw-r--r--docs/source/fsmc.rst33
-rw-r--r--docs/source/gpio.rst106
-rw-r--r--docs/source/hardware/maple-mini.rst402
-rw-r--r--docs/source/hardware/maple-native-beta.rst605
-rw-r--r--docs/source/hardware/maple-native.rst6
-rw-r--r--docs/source/hardware/maple-ret6.rst466
-rw-r--r--docs/source/hardware/maple.rst618
-rw-r--r--docs/source/i2c.rst77
-rw-r--r--docs/source/ide.rst166
-rw-r--r--docs/source/jtag.rst81
-rw-r--r--docs/source/lang/api/abs.rst48
-rw-r--r--docs/source/lang/api/analogread.rst119
-rw-r--r--docs/source/lang/api/analogwrite.rst181
-rw-r--r--docs/source/lang/api/assert.rst30
-rw-r--r--docs/source/lang/api/attachinterrupt.rst114
-rw-r--r--docs/source/lang/api/bit.rst38
-rw-r--r--docs/source/lang/api/bitclear.rst39
-rw-r--r--docs/source/lang/api/bitread.rst39
-rw-r--r--docs/source/lang/api/bitset.rst39
-rw-r--r--docs/source/lang/api/bitwrite.rst45
-rw-r--r--docs/source/lang/api/board-values.rst189
-rw-r--r--docs/source/lang/api/boardusespin.rst27
-rw-r--r--docs/source/lang/api/constants.rst318
-rw-r--r--docs/source/lang/api/constrain.rst68
-rw-r--r--docs/source/lang/api/cos.rst30
-rw-r--r--docs/source/lang/api/delay.rst69
-rw-r--r--docs/source/lang/api/delaymicroseconds.rst62
-rw-r--r--docs/source/lang/api/detachinterrupt.rst43
-rw-r--r--docs/source/lang/api/digitalread.rst51
-rw-r--r--docs/source/lang/api/digitalwrite.rst56
-rw-r--r--docs/source/lang/api/disabledebugports.rst33
-rw-r--r--docs/source/lang/api/enabledebugports.rst31
-rw-r--r--docs/source/lang/api/hardwarespi.rst170
-rw-r--r--docs/source/lang/api/hardwaretimer.rst345
-rw-r--r--docs/source/lang/api/highbyte.rst55
-rw-r--r--docs/source/lang/api/interrupts.rst47
-rw-r--r--docs/source/lang/api/isbuttonpressed.rst20
-rw-r--r--docs/source/lang/api/loop.rst44
-rw-r--r--docs/source/lang/api/lowbyte.rst25
-rw-r--r--docs/source/lang/api/map.rst68
-rw-r--r--docs/source/lang/api/max.rst64
-rw-r--r--docs/source/lang/api/micros.rst46
-rw-r--r--docs/source/lang/api/millis.rst52
-rw-r--r--docs/source/lang/api/min.rst65
-rw-r--r--docs/source/lang/api/nointerrupts.rst47
-rw-r--r--docs/source/lang/api/pinmode.rst80
-rw-r--r--docs/source/lang/api/pow.rst20
-rw-r--r--docs/source/lang/api/pwmwrite.rst61
-rw-r--r--docs/source/lang/api/random.rst71
-rw-r--r--docs/source/lang/api/randomseed.rst60
-rw-r--r--docs/source/lang/api/serial.rst282
-rw-r--r--docs/source/lang/api/serialusb.rst242
-rw-r--r--docs/source/lang/api/setup.rst29
-rw-r--r--docs/source/lang/api/shiftout.rst99
-rw-r--r--docs/source/lang/api/sin.rst31
-rw-r--r--docs/source/lang/api/sq.rst45
-rw-r--r--docs/source/lang/api/tan.rst30
-rw-r--r--docs/source/lang/api/toggleled.rst37
-rw-r--r--docs/source/lang/api/togglepin.rst17
-rw-r--r--docs/source/lang/api/volatile.rst65
-rw-r--r--docs/source/lang/api/waitforbuttonpress.rst43
-rw-r--r--docs/source/lang/cc-attribution.txt10
-rw-r--r--docs/source/lang/cpp/arithmetic.rst124
-rw-r--r--docs/source/lang/cpp/array.rst121
-rw-r--r--docs/source/lang/cpp/assignment.rst60
-rw-r--r--docs/source/lang/cpp/bitshift.rst143
-rw-r--r--docs/source/lang/cpp/bitwisemath.rst185
-rw-r--r--docs/source/lang/cpp/boolean.rst90
-rw-r--r--docs/source/lang/cpp/booleanvariables.rst47
-rw-r--r--docs/source/lang/cpp/break.rst32
-rw-r--r--docs/source/lang/cpp/built-in-types.rst108
-rw-r--r--docs/source/lang/cpp/byte.rst33
-rw-r--r--docs/source/lang/cpp/bytecast.rst44
-rw-r--r--docs/source/lang/cpp/cc-attribution.txt9
-rw-r--r--docs/source/lang/cpp/char.rst44
-rw-r--r--docs/source/lang/cpp/charcast.rst32
-rw-r--r--docs/source/lang/cpp/comments.rst64
-rw-r--r--docs/source/lang/cpp/comparison.rst86
-rw-r--r--docs/source/lang/cpp/compoundarithmetic.rst43
-rw-r--r--docs/source/lang/cpp/compoundbitwise.rst229
-rw-r--r--docs/source/lang/cpp/const.rst50
-rw-r--r--docs/source/lang/cpp/continue.rst30
-rw-r--r--docs/source/lang/cpp/curly-braces.rst106
-rw-r--r--docs/source/lang/cpp/define.rst54
-rw-r--r--docs/source/lang/cpp/double.rst46
-rw-r--r--docs/source/lang/cpp/doublecast.rst27
-rw-r--r--docs/source/lang/cpp/dowhile.rst26
-rw-r--r--docs/source/lang/cpp/enum.rst52
-rw-r--r--docs/source/lang/cpp/float.rst50
-rw-r--r--docs/source/lang/cpp/floatcast.rst28
-rw-r--r--docs/source/lang/cpp/for.rst142
-rw-r--r--docs/source/lang/cpp/goto.rst129
-rw-r--r--docs/source/lang/cpp/if.rst121
-rw-r--r--docs/source/lang/cpp/include.rst70
-rw-r--r--docs/source/lang/cpp/increment.rst37
-rw-r--r--docs/source/lang/cpp/int.rst68
-rw-r--r--docs/source/lang/cpp/intcast.rst26
-rw-r--r--docs/source/lang/cpp/keywords.rst204
-rw-r--r--docs/source/lang/cpp/longcast.rst27
-rw-r--r--docs/source/lang/cpp/longlong.rst56
-rw-r--r--docs/source/lang/cpp/modulo.rst70
-rw-r--r--docs/source/lang/cpp/pointer.rst31
-rw-r--r--docs/source/lang/cpp/return.rst60
-rw-r--r--docs/source/lang/cpp/scope.rst120
-rw-r--r--docs/source/lang/cpp/semicolon.rst22
-rw-r--r--docs/source/lang/cpp/sizeof.rst64
-rw-r--r--docs/source/lang/cpp/sqrt.rst24
-rw-r--r--docs/source/lang/cpp/static.rst56
-rw-r--r--docs/source/lang/cpp/string.rst120
-rw-r--r--docs/source/lang/cpp/switchcase.rst118
-rw-r--r--docs/source/lang/cpp/unsignedchar.rst32
-rw-r--r--docs/source/lang/cpp/unsignedint.rst59
-rw-r--r--docs/source/lang/cpp/unsignedlonglong.rst43
-rw-r--r--docs/source/lang/cpp/variables.rst169
-rw-r--r--docs/source/lang/cpp/void.rst31
-rw-r--r--docs/source/lang/cpp/while.rst38
-rw-r--r--docs/source/lang/unimplemented/notone.rst37
-rw-r--r--docs/source/lang/unimplemented/pulsein.rst82
-rw-r--r--docs/source/lang/unimplemented/stringclass.rst6
-rw-r--r--docs/source/lang/unimplemented/stringobject.rst89
-rw-r--r--docs/source/lang/unimplemented/tone.rst58
-rw-r--r--docs/source/language-index.rst50
-rw-r--r--docs/source/language.rst431
-rw-r--r--docs/source/libmaple.rst48
-rw-r--r--docs/source/libmaple/api/adc.rst231
-rw-r--r--docs/source/libmaple/api/bitband.rst15
-rw-r--r--docs/source/libmaple/api/bkp.rst79
-rw-r--r--docs/source/libmaple/api/dac.rst123
-rw-r--r--docs/source/libmaple/api/delay.rst11
-rw-r--r--docs/source/libmaple/api/dma.rst215
-rw-r--r--docs/source/libmaple/api/exti.rst37
-rw-r--r--docs/source/libmaple/api/flash.rst249
-rw-r--r--docs/source/libmaple/api/fsmc.rst235
-rw-r--r--docs/source/libmaple/api/gpio.rst243
-rw-r--r--docs/source/libmaple/api/i2c.rst124
-rw-r--r--docs/source/libmaple/api/iwdg.rst80
-rw-r--r--docs/source/libmaple/api/libmaple.rst11
-rw-r--r--docs/source/libmaple/api/libmaple_types.rst85
-rw-r--r--docs/source/libmaple/api/nvic.rst67
-rw-r--r--docs/source/libmaple/api/pwr.rst51
-rw-r--r--docs/source/libmaple/api/rcc-reg-bits.txt1017
-rw-r--r--docs/source/libmaple/api/rcc.rst360
-rw-r--r--docs/source/libmaple/api/ring_buffer.rst27
-rw-r--r--docs/source/libmaple/api/scb.rst156
-rw-r--r--docs/source/libmaple/api/spi.rst187
-rw-r--r--docs/source/libmaple/api/stm32.rst121
-rw-r--r--docs/source/libmaple/api/systick.rst62
-rw-r--r--docs/source/libmaple/api/timer.rst453
-rw-r--r--docs/source/libmaple/api/usart.rst197
-rw-r--r--docs/source/libmaple/api/util.rst54
-rw-r--r--docs/source/libmaple/apis.rst14
-rw-r--r--docs/source/libmaple/coding-standard.rst422
-rw-r--r--docs/source/libmaple/contributing.rst176
-rw-r--r--docs/source/libmaple/overview.rst516
-rw-r--r--docs/source/libraries.rst80
-rw-r--r--docs/source/libs/servo.rst92
-rw-r--r--docs/source/libs/wire.rst104
-rw-r--r--docs/source/maple-ide-install.rst176
-rw-r--r--docs/source/maple-quickstart.rst210
-rw-r--r--docs/source/prolog.rst8
-rw-r--r--docs/source/pwm.rst103
-rw-r--r--docs/source/spi.rst30
-rw-r--r--docs/source/stm32.rst87
-rw-r--r--docs/source/systick.rst15
-rw-r--r--docs/source/timers.rst123
-rw-r--r--docs/source/troubleshooting.rst258
-rw-r--r--docs/source/unix-toolchain-linux-setup.rst203
-rw-r--r--docs/source/unix-toolchain-osx-setup.rst132
-rw-r--r--docs/source/unix-toolchain-win-setup.rst163
-rw-r--r--docs/source/unix-toolchain.rst375
-rw-r--r--docs/source/usart.rst62
-rw-r--r--docs/source/usb.rst49
-rw-r--r--docs/source/whats-new.rst81
-rw-r--r--docs/tmpl/libmaple-proper-page.rst.tmpl43
231 files changed, 21803 insertions, 0 deletions
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..0187b3d
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,2 @@
+build/
+*~
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..5255525
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,134 @@
+# Makefile for LeafLabs documentation (automatically generated by
+# Sphinx).
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/libmaple.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/libmaple.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/libmaple"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/libmaple"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+doxygen:
+ @echo "Wrong! You need to run this from within libmaple!"
+ false
diff --git a/docs/README b/docs/README
new file mode 100644
index 0000000..60fb888
--- /dev/null
+++ b/docs/README
@@ -0,0 +1,24 @@
+This repository contains source files used to generate the
+documentation for LeafLabs' libmaple and Maple IDE projects [*]. The
+HTML documentation generated from these sources is available online:
+
+ http://leaflabs.com/docs/
+
+The above URL is the recommended way for users to read the
+documentation. The docs for the latest release are always available
+there.
+
+Older versions are here:
+
+ http://static.leaflabs.com/pub/leaflabs/maple-docs/
+
+The file README-building.txt explains how to build the HTML docs.
+
+The file README-maintainers.txt contains important information for
+maintainers of the documentation (e.g. how to add docs for a new
+board, how to cut a release version of the docs, etc.).
+
+[*] libmaple and Maple IDE themselves are in separate repositories:
+
+ https://github.com/leaflabs/libmaple
+ https://github.com/leaflabs/maple-ide
diff --git a/docs/README-building.txt b/docs/README-building.txt
new file mode 100644
index 0000000..de4a7f7
--- /dev/null
+++ b/docs/README-building.txt
@@ -0,0 +1,105 @@
+This file explains how to build the HTML documentation. As such, it's
+probably only useful to LeafLabs developers. Users can read the HTML
+for the latest release here:
+
+ http://leaflabs.com/docs/
+
+Install Dependencies
+--------------------
+
+First, you will need to install some dependencies (Doxygen, Sphinx,
+and Breathe).
+
+1. Much of the documentation is pulled out of the libmaple source
+ code's Doxygen comments, so you need a recent-ish version of
+ Doxygen in your PATH:
+
+ http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc
+
+2. Documentation not taken from the libmaple sources is written in
+ Sphinx's extensions to the reStructuredText (reST) markup language.
+ (More about Sphinx: http://sphinx.pocoo.org/tutorial.html).
+
+ These are your choices for how to install Sphinx:
+
+ - From source or .egg:
+ http://pypi.python.org/pypi/Sphinx#downloads
+
+ - Via easy_install:
+ $ sudo easy_install -U Sphinx
+
+ You need Sphinx version >= 1.0.6.
+
+3. We use a Sphinx plugin called Breathe to parse Doxygen's XML output
+ into a form usable by Sphinx. (More about Breathe:
+ http://michaeljones.github.com/breathe/).
+
+ LeafLabs sometimes patches Breathe for the purposes of building our
+ docs, so clone the LeafLabs Breathe tree from GitHub (somewhere
+ else on your system, NOT in the leaflabs-docs repo):
+
+ - LeafLabs developers, clone with push permissions:
+ $ git clone git@github.com:leaflabs/breathe.git
+
+ - Everyone else, clone without them:
+ $ git clone git://github.com/leaflabs/breathe.git
+
+4. After that's done, set environment variables LIB_MAPLE_HOME to
+ point to libmaple, and BREATHE_HOME to point to Breathe. Something
+ like this in Bash:
+
+ $ export LIB_MAPLE_HOME=/path/to/libmaple/repo/
+ $ export BREATHE_HOME=/path/to/breathe/repo/
+
+ (You'll want this in your shell startup script.)
+
+Build the Docs
+--------------
+
+You are finally ready to build the documentation. First, you'll
+produce Doxygen XML output, then you can generate the final HTML docs.
+
+1. Before the first time you run Sphinx (and any time the Doxygen
+ comments in the libmaple source code are changed), you'll need to
+ re-run doxygen on libmaple.
+
+ $ cd /path/to/libmaple
+ $ make doxygen
+
+ Doxygen will yell at you a lot; it's generally safe to ignore it.
+
+2. Finally, you can build the HTML (in the leaflabs-docs repository):
+
+ $ cd /path/to/leaflabs-docs
+ $ make html
+
+ On Windows, you can supposedly use the batch file make.bat instead.
+
+ Breathe will yell at you a lot; it's often safe to ignore this,
+ too. C'est la vie.
+
+Read and Modify the Docs
+------------------------
+
+Point your web browser at the file
+
+ build/html/index.html
+
+For the most part, the file build/html/foo.html is built from
+source/foo.rst. (The index is an exception, because we needed to
+hand-hack the HTML to get the "Contents at a Glance" section to look
+nice).
+
+All of the documentation which isn't pulled out of libmaple's Doxygen
+comments lives in source/. The directory source/_static/ is for
+static content (like style sheets); source/_templates/ is meant to
+contain Sphinx templates.
+
+Read more about Sphinx and use the existing leaflabs-docs source for
+examples when writing new docs. The directory tmpl/ contains template
+ReST files you should sometimes use when creating a page that follows
+a pattern (like a libmaple API page), in order to keep the style
+consistent.
+
+The file source/conf.py is the Sphinx configuration file; you can go
+read it for more information about our setup.
diff --git a/docs/README-maintainers.txt b/docs/README-maintainers.txt
new file mode 100644
index 0000000..48e8e5c
--- /dev/null
+++ b/docs/README-maintainers.txt
@@ -0,0 +1,215 @@
+This file contains information useful for the documentation's
+maintainers. As such, it's probably only useful to LeafLabs
+developers. Users can read the HTML for the latest release here:
+
+ http://leaflabs.com/docs/
+
+Things you can learn how to do from this file:
+
+- Cut a release version
+- Fix errors in/otherwise maintain the current docs release
+- Add docs for a new board
+
+Building Documentation for a Release
+------------------------------------
+
+This is the procedure to follow when building the documentation for a
+versioned release.
+
+Read the following "Background" section if you've never done this
+before (or haven't done it in a while; things change). Then do the
+steps in the "Preparation" and "Cutting the Release" sections that
+follow it.
+
+If you're bugfixing the docs for a release that's already been
+shipped, skip to "Maintaining a Release", below.
+
+ ~~~~~~~~~~
+ Background
+ ~~~~~~~~~~
+
+As a lightweight form of issue tracking, the documentation sources are
+sprinkled (not to say "littered") with comments that begin with FIXME
+or TODO, optionally followed by [milestone].
+
+Here's a hypothetical example:
+
+ .. TODO [1.4.0] Replace this section; new API is incompatible with 1.3.7
+
+This means you should replace the docs section following the comment
+before you build the HTML for version 1.4.0.
+
+Here's a command line you can use to list the TODOs in the
+documentation sources (run it from the top-level directory in the
+repository):
+
+ $ git grep -n 'FIXME\|TODO'
+
+You can use the following to temporarily alias the above mouthful to
+'todos':
+
+ $ alias todos="git grep -n 'FIXME\|TODO'"
+
+Then you can just run
+
+ $ todos
+
+to measure the joy that awaits you.
+
+ ~~~~~~~~~~~
+ Preparation
+ ~~~~~~~~~~~
+
+- FINISH THE FIXMEs/TODOs FOR THE CURRENT RELEASE!
+
+ You may violate assumptions made elsewhere in the documentation if
+ you don't. This can lead to incoherent or incorrect documentation,
+ which is usually worse than none at all.
+
+ If the release you're building is vA.B.C, you can see the relevant
+ TODOs with:
+
+ $ todos | grep A\.B\.C
+
+ If you find that you really can't finish the TODO, you should bump
+ the version number in the comment. Don't do this out of laziness.
+ Seriously, don't. We may have made promises to the users about what
+ would happen when, and you might be breaking them.
+
+- Pick the low-hanging fruit on any other FIXMEs/TODOs.
+
+- Ask Git to tell you what's happened since the most recent libmaple
+ release, and make sure that any major, potentially
+ backwards-incompatible, etc. changes are appropriately documented.
+
+ You can use three dots ("...") between the git tags for those
+ releases in concert with "git log --oneline" to do this.
+
+ For instance, from the libmaple repository, you can use the
+ following to tell you what happened in between 0.0.9 and 0.0.10:
+
+ $ git log --oneline 0.0.9...0.0.10
+
+ As an example of what the output might cause you to do, consider the
+ following line (which appears in the output for 0.0.9...0.0.10):
+
+ 4941335 Adding rcc_dev_clk(), an accessor for a peripheral's clock line.
+
+ Did the author of that commit (or some other interested party)
+ remember to pull in the documentation for rcc_dev_clk() into the
+ libmaple API page for rcc.h? Go check!
+
+- Do something similar for Maple IDE. The IDE changes a lot more
+ slowly, so there should be less to do.
+
+ ~~~~~~~~~~~~~~~~~~~
+ Cutting the Release
+ ~~~~~~~~~~~~~~~~~~~
+
+- Make a release branch in Git. For release A.B.C, call it
+ vA.B.C-maintenance. You spell that
+
+ $ git checkout -b vA.B.C-maintenance
+
+ DON'T MAKE A TAG. There are inevitably mistakes in the docs, some
+ of which will be noticed and corrected, making a fixed tag useless.
+ When you correct the errors, you'll need to update this branch,
+ possibly also cherry-picking or otherwise adding into master. See
+ "Maintaining the Release", below.
+
+- Do all the TODOs which must happen for _every_ release. (These are
+ distinct from the ones that must happen for some _particular_
+ release). You can find most of these with
+
+ $ todos | grep RELEASE
+
+ However, you'll also need to check source/conf.py, as e.g. a
+ release's configuration file needs to have a version entered into
+ it.
+
+ DON'T FORGET TO COMMIT YOUR CHANGES.
+
+- Run "$ make mrproper" from the libmaple directory, and "$ make
+ clean" from this directory, in order to wipe out existing old docs.
+
+- Run "$ make doxygen" from the libmaple directory, and copy its
+ doxygen/xml directory to doxygen/xml in this directory, and commit
+ it in the vA.B.C-maintenance branch.
+
+ (This makes later maintenance commits easier, and keeps a single
+
+- Finally, you can actually build the docs. (See README-building.txt
+ for instructions if you've never done this before.)
+
+ DON'T FORGET TO PUSH THE RELEASE BRANCH TO GITHUB.
+
+Maintaining a Release
+---------------------
+
+So a released version's documentation contains unforgivable lies, huh?
+It needs to be updated RIGHT AWAY, you say? Here's what you do:
+
+- Check out the release branch for the version of the docs you care
+ about (see "Cutting the Release", above).
+
+- Make your changes.
+
+- Rebuild the docs (see the last two steps in "Cutting the Release")
+ and look at the changed pages.
+
+- If your changes also need to happen on the master branch, make them
+ appropriately.
+
+ Advice: git cherry-pick is your friend. Let's say you're on branch
+ "vX.Y.Z-maintenance", and you want to get commit C onto master:
+
+ o---C vX.Y.Z-maintenance
+ /
+ -o---o---o---o master
+
+ The recipe is:
+
+ $ git checkout master
+ $ git cherry-pick C
+
+ Which (if there are no conflicts) will result in:
+
+ o---C vX.Y.Z-maintenance
+ /
+ -o---o---o---o---C' master
+
+ Where C' performs the same changes as C.
+
+- Push your fixes to GitHub.
+
+- Distribute the updated docs. These are world-visible here:
+
+ http://static.leaflabs.com/pub/leaflabs/maple-docs/
+
+Adding a New Board
+------------------
+
+Adding documentation for a new board is not just a matter of shoving a
+file for it into source/hardware/!
+
+Other things you must consider:
+
+- Various places in the docs link to particular kinds of pin maps for
+ each board. When you add a new board, you must update these as
+ well. Here's the list; please keep it current (files are relative
+ to the source/ directory):
+
+ * external-interrupts.rst: EXTI line pin maps
+ * timers.rst: timer pin maps
+ * adc.rst: low-noise ADC banks
+ * usart.rst: USART pin maps
+ * gpio.rst: master pin maps
+ * bootloader.rst: flashing a custom bootloader
+
+- The quickstart document may not explain how to use the new board.
+ If the board is different enough, a new, special-purpose quickstart
+ may need to be written for it. Therefore, read the quickstart in
+ its entirety and update it appropriately.
+
+ Take this step seriously. The quickstart is the first thing users
+ read when starting out, and first impressions matter.
diff --git a/docs/copy-to-ide b/docs/copy-to-ide
new file mode 100755
index 0000000..6cd4bdd
--- /dev/null
+++ b/docs/copy-to-ide
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+IDE_DIRECTORY=$1
+
+REFERENCE=$IDE_DIRECTORY/build/shared/reference
+
+echo copying built docs...
+cp -R build/html/* $REFERENCE
+echo done
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..1833a4b
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,155 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libmaple.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libmaple.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/docs/source/_static/.gitignore b/docs/source/_static/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/source/_static/.gitignore
diff --git a/docs/source/_static/breathe.css b/docs/source/_static/breathe.css
new file mode 100644
index 0000000..d86028c
--- /dev/null
+++ b/docs/source/_static/breathe.css
@@ -0,0 +1 @@
+/* This is a dummy css file to prevent 404 errors */
diff --git a/docs/source/_static/img/blinky-to-flash.png b/docs/source/_static/img/blinky-to-flash.png
new file mode 100644
index 0000000..0320c5b
--- /dev/null
+++ b/docs/source/_static/img/blinky-to-flash.png
Binary files differ
diff --git a/docs/source/_static/img/blinky.png b/docs/source/_static/img/blinky.png
new file mode 100644
index 0000000..bda4cee
--- /dev/null
+++ b/docs/source/_static/img/blinky.png
Binary files differ
diff --git a/docs/source/_static/img/button-new.png b/docs/source/_static/img/button-new.png
new file mode 100644
index 0000000..3fd98be
--- /dev/null
+++ b/docs/source/_static/img/button-new.png
Binary files differ
diff --git a/docs/source/_static/img/button-open.png b/docs/source/_static/img/button-open.png
new file mode 100644
index 0000000..466fc10
--- /dev/null
+++ b/docs/source/_static/img/button-open.png
Binary files differ
diff --git a/docs/source/_static/img/button-save.png b/docs/source/_static/img/button-save.png
new file mode 100644
index 0000000..7eba286
--- /dev/null
+++ b/docs/source/_static/img/button-save.png
Binary files differ
diff --git a/docs/source/_static/img/button-serial-monitor.png b/docs/source/_static/img/button-serial-monitor.png
new file mode 100644
index 0000000..aec9741
--- /dev/null
+++ b/docs/source/_static/img/button-serial-monitor.png
Binary files differ
diff --git a/docs/source/_static/img/button-stop.png b/docs/source/_static/img/button-stop.png
new file mode 100644
index 0000000..4812ae9
--- /dev/null
+++ b/docs/source/_static/img/button-stop.png
Binary files differ
diff --git a/docs/source/_static/img/button-upload.png b/docs/source/_static/img/button-upload.png
new file mode 100644
index 0000000..0f41eeb
--- /dev/null
+++ b/docs/source/_static/img/button-upload.png
Binary files differ
diff --git a/docs/source/_static/img/button-verify.png b/docs/source/_static/img/button-verify.png
new file mode 100644
index 0000000..95abeb8
--- /dev/null
+++ b/docs/source/_static/img/button-verify.png
Binary files differ
diff --git a/docs/source/_static/img/codeblocks_build.png b/docs/source/_static/img/codeblocks_build.png
new file mode 100644
index 0000000..c98bcdc
--- /dev/null
+++ b/docs/source/_static/img/codeblocks_build.png
Binary files differ
diff --git a/docs/source/_static/img/codeblocks_makefile.png b/docs/source/_static/img/codeblocks_makefile.png
new file mode 100644
index 0000000..a0ef21f
--- /dev/null
+++ b/docs/source/_static/img/codeblocks_makefile.png
Binary files differ
diff --git a/docs/source/_static/img/codeblocks_maketargets.png b/docs/source/_static/img/codeblocks_maketargets.png
new file mode 100644
index 0000000..bbb68cb
--- /dev/null
+++ b/docs/source/_static/img/codeblocks_maketargets.png
Binary files differ
diff --git a/docs/source/_static/img/codeblocks_newproject.png b/docs/source/_static/img/codeblocks_newproject.png
new file mode 100644
index 0000000..8d08d1f
--- /dev/null
+++ b/docs/source/_static/img/codeblocks_newproject.png
Binary files differ
diff --git a/docs/source/_static/img/github-clone-in-windows.png b/docs/source/_static/img/github-clone-in-windows.png
new file mode 100644
index 0000000..41d76d1
--- /dev/null
+++ b/docs/source/_static/img/github-clone-in-windows.png
Binary files differ
diff --git a/docs/source/_static/img/ide-blinky.png b/docs/source/_static/img/ide-blinky.png
new file mode 100644
index 0000000..3cccdb4
--- /dev/null
+++ b/docs/source/_static/img/ide-blinky.png
Binary files differ
diff --git a/docs/source/_static/img/jtag-wiring.png b/docs/source/_static/img/jtag-wiring.png
new file mode 100644
index 0000000..8f31f99
--- /dev/null
+++ b/docs/source/_static/img/jtag-wiring.png
Binary files differ
diff --git a/docs/source/_static/img/osx-network-prefs-unconfigured.png b/docs/source/_static/img/osx-network-prefs-unconfigured.png
new file mode 100644
index 0000000..70d2fa0
--- /dev/null
+++ b/docs/source/_static/img/osx-network-prefs-unconfigured.png
Binary files differ
diff --git a/docs/source/_static/img/osx-unconfigured-popup.png b/docs/source/_static/img/osx-unconfigured-popup.png
new file mode 100644
index 0000000..a43ad57
--- /dev/null
+++ b/docs/source/_static/img/osx-unconfigured-popup.png
Binary files differ
diff --git a/docs/source/_static/img/round_logo_32x32.ico b/docs/source/_static/img/round_logo_32x32.ico
new file mode 100644
index 0000000..29fb2bf
--- /dev/null
+++ b/docs/source/_static/img/round_logo_32x32.ico
Binary files differ
diff --git a/docs/source/_static/img/round_logo_60x60.png b/docs/source/_static/img/round_logo_60x60.png
new file mode 100644
index 0000000..dacd36a
--- /dev/null
+++ b/docs/source/_static/img/round_logo_60x60.png
Binary files differ
diff --git a/docs/source/_static/img/serial-monitor.png b/docs/source/_static/img/serial-monitor.png
new file mode 100644
index 0000000..6162dab
--- /dev/null
+++ b/docs/source/_static/img/serial-monitor.png
Binary files differ
diff --git a/docs/source/_static/img/serial-port-mac.png b/docs/source/_static/img/serial-port-mac.png
new file mode 100644
index 0000000..b3a1989
--- /dev/null
+++ b/docs/source/_static/img/serial-port-mac.png
Binary files differ
diff --git a/docs/source/_static/img/serial-port-ubuntu.png b/docs/source/_static/img/serial-port-ubuntu.png
new file mode 100644
index 0000000..8038e41
--- /dev/null
+++ b/docs/source/_static/img/serial-port-ubuntu.png
Binary files differ
diff --git a/docs/source/_static/img/serial-port-win.png b/docs/source/_static/img/serial-port-win.png
new file mode 100644
index 0000000..90dc1c4
--- /dev/null
+++ b/docs/source/_static/img/serial-port-win.png
Binary files differ
diff --git a/docs/source/_static/img/upload-button.png b/docs/source/_static/img/upload-button.png
new file mode 100644
index 0000000..20a663f
--- /dev/null
+++ b/docs/source/_static/img/upload-button.png
Binary files differ
diff --git a/docs/source/_static/img/verify-success.png b/docs/source/_static/img/verify-success.png
new file mode 100644
index 0000000..6928674
--- /dev/null
+++ b/docs/source/_static/img/verify-success.png
Binary files differ
diff --git a/docs/source/_static/img/verify_button.png b/docs/source/_static/img/verify_button.png
new file mode 100644
index 0000000..37100db
--- /dev/null
+++ b/docs/source/_static/img/verify_button.png
Binary files differ
diff --git a/docs/source/_static/img/win7-copy-arm-bin-address.png b/docs/source/_static/img/win7-copy-arm-bin-address.png
new file mode 100644
index 0000000..a3886d1
--- /dev/null
+++ b/docs/source/_static/img/win7-copy-arm-bin-address.png
Binary files differ
diff --git a/docs/source/_static/img/win7-copy-python-address.png b/docs/source/_static/img/win7-copy-python-address.png
new file mode 100644
index 0000000..34d3022
--- /dev/null
+++ b/docs/source/_static/img/win7-copy-python-address.png
Binary files differ
diff --git a/docs/source/_static/img/win7-github-open-in-explorer.png b/docs/source/_static/img/win7-github-open-in-explorer.png
new file mode 100644
index 0000000..8320a90
--- /dev/null
+++ b/docs/source/_static/img/win7-github-open-in-explorer.png
Binary files differ
diff --git a/docs/source/_static/img/win7-python-arm-bin-path.png b/docs/source/_static/img/win7-python-arm-bin-path.png
new file mode 100644
index 0000000..8dcc8ed
--- /dev/null
+++ b/docs/source/_static/img/win7-python-arm-bin-path.png
Binary files differ
diff --git a/docs/source/_static/img/win7-python-path.png b/docs/source/_static/img/win7-python-path.png
new file mode 100644
index 0000000..8898a9e
--- /dev/null
+++ b/docs/source/_static/img/win7-python-path.png
Binary files differ
diff --git a/docs/source/_static/img/win7-python-prompt.png b/docs/source/_static/img/win7-python-prompt.png
new file mode 100644
index 0000000..27ae62a
--- /dev/null
+++ b/docs/source/_static/img/win7-python-prompt.png
Binary files differ
diff --git a/docs/source/_static/index-style.css b/docs/source/_static/index-style.css
new file mode 100644
index 0000000..d7c42b3
--- /dev/null
+++ b/docs/source/_static/index-style.css
@@ -0,0 +1,19 @@
+/* Contents style */
+
+.contents-table {
+ font-size: large;
+}
+
+.contents-table ul, .contents-table li {
+ display: inline;
+}
+
+.contents-table td {
+ padding: 0em 1em 0em;
+}
+
+.contents-table ul {
+ list-style-type: none;
+ margin: 0em;
+ padding-left: 0px;
+}
diff --git a/docs/source/_static/leaflabs-docs.css b/docs/source/_static/leaflabs-docs.css
new file mode 100644
index 0000000..18f5bcc
--- /dev/null
+++ b/docs/source/_static/leaflabs-docs.css
@@ -0,0 +1 @@
+/* Any custom CSS you want applied goes here */
diff --git a/docs/source/_templates/.gitignore b/docs/source/_templates/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/source/_templates/.gitignore
diff --git a/docs/source/_templates/indexcontent.html b/docs/source/_templates/indexcontent.html
new file mode 100644
index 0000000..a043f8a
--- /dev/null
+++ b/docs/source/_templates/indexcontent.html
@@ -0,0 +1,117 @@
+{# This file generates the top-level index.html file. We are very
+ obviously stealing from the Python docs' style ;).
+#}
+
+<!-- Extend our layout.html. So inheritance hierarchy is Sphinx's
+ layout, then our layout.html, then this file. -->
+{% extends "layout.html" %}
+
+<!-- Pull in extra index stylesheet -->
+{% set css_files = css_files + ["_static/index-style.css"] %}
+
+<!-- Separator for contents lists -->
+{% set content_sep = "&middot;" %}
+
+<!-- Content -->
+{% block body %}
+<h1>Hi!</h1>
+
+This is the documentation for the LeafLabs Maple boards, version {{
+release }}.
+
+<h2>Read This First</h2>
+
+<p>Just getting started? Try the <a href="{{
+pathto("maple-quickstart") }}">Quickstart</a>. Having problems? Check
+out <a href="{{ pathto("troubleshooting") }}">Troubleshooting</a> and
+the <a href="{{ pathto("faq") }}">FAQ</a>. Can't find what you want
+here? Look on the <a href="http://wiki.leaflabs.com/">LeafLabs
+wiki</a>.
+</p>
+
+<p>See the <a href="{{ pathto("whats-new") }}">What's New</a> page for
+changes that are new in {{ release }}.</p>
+
+<h2>Contents at a Glance</h2>
+
+<table class="contents-table">
+ <tr>
+ <td><p><strong>Getting Started</strong></p>
+ <ul>
+ <li><a href="{{ pathto("maple-quickstart") }}">Quickstart</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("maple-ide-install") }}">Installing Maple&nbsp;IDE</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("ide") }}">Using Maple&nbsp;IDE</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("unix-toolchain") }}">Command-Line
+ Toolchain</a></li>
+ </ul>
+ </td>
+ <td><p><strong>Boards</strong></p>
+ <ul>
+ <li><a href="{{ pathto("hardware/maple") }}">Maple</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("hardware/maple-ret6") }}">Maple RET6&nbsp;Edition</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("hardware/maple-mini") }}">Maple Mini</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("hardware/maple-native-beta") }}">Maple
+ Native β</a></li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td><p><strong>Programming</strong></p>
+ <ul>
+ <li><a href="{{ pathto("language") }}">Language Reference</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("troubleshooting") }}">Troubleshooting</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("faq") }}">FAQ</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("libraries") }}">Libraries</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("libmaple") }}"><tt>libmaple</tt></a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("bootloader") }}">Bootloader</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("arm-gcc") }}">GCC and libc</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("arduino-compatibility") }}">Arduino
+ Compatibility</a></li>
+ </ul>
+ </td>
+ <td><p><strong>Hardware and Peripherals</strong></p>
+ <ul>
+ <li><a href="{{ pathto("stm32") }}">STM32</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("adc") }}">ADC</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("external-interrupts") }}">External
+ Interrupts</a> {{ content_sep }}</li>
+ <li><a href="{{ pathto("fsmc") }}">FSMC</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("gpio") }}">GPIO</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("i2c") }}">I<sup>2</sup>C</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("jtag") }}">JTAG</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("pwm") }}">PWM</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("spi") }}">SPI</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("systick") }}">SysTick</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("timers") }}">Timers</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("usart") }}">USART</a>
+ {{ content_sep }}</li>
+ <li><a href="{{ pathto("usb") }}">USB</a></li>
+ </ul>
+ </td>
+ </tr>
+</table>
+
+{% endblock %}
diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html
new file mode 100644
index 0000000..2fd81ce
--- /dev/null
+++ b/docs/source/_templates/layout.html
@@ -0,0 +1,11 @@
+{% extends "!layout.html" %}
+
+{% set css_files = css_files + ["_static/leaflabs-docs.css"] %}
+
+{% block rootrellink %}
+ <li><a href="http://leaflabs.com/">
+ <img width="16px" src="_static/img/round_logo_32x32.ico"></img>
+ leaflabs.com
+ </a>&middot;</li>
+ <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
+{% endblock %}
diff --git a/docs/source/adc.rst b/docs/source/adc.rst
new file mode 100644
index 0000000..937b178
--- /dev/null
+++ b/docs/source/adc.rst
@@ -0,0 +1,104 @@
+.. _adc:
+
+=====
+ ADC
+=====
+
+Analog to digital conversion is the process of reading a physical
+voltage as a number. Maple can convert voltages between 0 and 3.3V to
+numbers between 0 and 4095.
+
+.. contents:: Contents
+ :local:
+
+ADC On Maple
+------------
+
+Doing analog-to-digital conversion on the Maple is simple.
+:ref:`Maple IDE <ide>` contains a basic example. To see it, choose
+Analog > AnalogInSerial from the :ref:`examples menu <ide-examples>`.
+
+In order to set up your board for conversion, first connect the wire
+(potentiometer, etc.) with the voltage you want to measure to a
+:ref:`pin <gpio>` which can perform ADC. Each pin which can do ADC
+has "AIN" (or "ain") written next to the the pin number. Then, as in
+the example program, set the chosen pin's :ref:`pin mode
+<lang-pinmode>` to ``INPUT_ANALOG`` by calling ``pinMode(<your_pin>,
+INPUT_ANALOG)``. You will usually do this in your :ref:`lang-setup`
+function. Now you can use :ref:`lang-analogread` to perform an ADC
+reading.
+
+.. _adc-function-reference:
+
+Function Reference
+------------------
+
+* :ref:`lang-analogread`
+* :ref:`lang-pinmode`
+* :ref:`libmaple-adc` (low-level ADC support)
+
+.. _adc-noise-bias:
+
+Noise and Bias
+--------------
+
+Maple has a large number of pins which are capable of taking 12-bit
+ADC measurements, which means that voltages from 0 to 3.3V are read as
+numbers from 0 to 4095. In theory, this means that a change in
+voltage of about 1 millivolt should change the numeric voltage reading
+by 1. In reality, however, a number of issues introduce noise and
+bias into this reading, and a number of techniques must be used to get
+good precision and accuracy.
+
+In order to allow for good readings, LeafLabs has tried to isolate at
+least some of each board's ADC pins and traces from strong noise
+sources. However, there are always trade-offs between noise,
+additional functionality, cost, and package size. More information on
+these isolated pins is available in each board's hardware
+documentation:
+
+* :ref:`Maple <maple-adc-bank>`
+* :ref:`Maple RET6 Edition <maple-ret6-adc-bank>`
+* :ref:`Maple Mini <maple-mini-adc-bank>`
+* :ref:`Maple Native Beta <maple-native-b-adc-bank>`
+
+That said, there are a number of more general things you can do to try
+to get good readings. If your input voltage changes relatively
+slowly, a number of samples can be taken in succession and averaged
+together, or the same voltage can even be sampled by multiple ADC pins
+at the same time.
+
+Another important factor when taking a voltage reading is the
+reference voltages that the sample is being compared against. For
+Maple, the high reference is |vdda| and the low reference is ground.
+This means that noise or fluctuations on either |vdda| or ground will
+affect the measurement. It also means that the voltage you are trying
+to sample must be between ground and 3.3 V.
+
+.. _adc-range:
+
+In the case of a variable reading, it is best if the voltage varies
+over the entire range of 0 through 3.3 V; otherwise, only a fraction
+of the sensitivity is being used. Some basic tools to accomplish this
+are `resistor dividers
+<http://en.wikipedia.org/wiki/Voltage_divider>`_ and `Zener diodes
+<http://en.wikipedia.org/wiki/Zener_diode>`_\
+. However, `operational amplifiers
+<http://en.wikipedia.org/wiki/Operational_amplifier>`_ and other
+powered components can also be used if greater precision is required.
+
+.. _adc-recommended-reading:
+
+Recommended Reading
+-------------------
+
+* `Wikipedia: Analog-to-Digital Converter
+ <http://en.wikipedia.org/wiki/Analog-to-digital_converter>`_
+* `Arduino Analog Input Tutorial
+ <http://arduino.cc/en/Tutorial/AnalogInputPins>`_
+* ST documentation:
+
+ * `Application Note on ADC Modes
+ <http://www.st.com/stonline/products/literature/an/16840.pdf>`_ (PDF)
+ * `Application Note on ADC Oversampling
+ <http://www.st.com/stonline/products/literature/an/14183.pdf>`_ (PDF)
diff --git a/docs/source/arduino-cc-attribution.txt b/docs/source/arduino-cc-attribution.txt
new file mode 100644
index 0000000..ad1c1e0
--- /dev/null
+++ b/docs/source/arduino-cc-attribution.txt
@@ -0,0 +1,9 @@
+.. Included in all relevant files in order to satisfy the Arduino
+.. CC Attribution-ShareAlike 3.0 License
+
+.. admonition:: License and Attribution
+
+ Portions of this page were adapted from the `Arduino Reference
+ Documentation <http://arduino.cc/en/Reference/HomePage>`_\ , which
+ is released under a `Creative Commons Attribution-ShareAlike 3.0
+ License <http://creativecommons.org/licenses/by-sa/3.0/>`_.
diff --git a/docs/source/arduino-compatibility.rst b/docs/source/arduino-compatibility.rst
new file mode 100644
index 0000000..f7d3210
--- /dev/null
+++ b/docs/source/arduino-compatibility.rst
@@ -0,0 +1,275 @@
+.. highlight:: cpp
+
+.. _arduino-compatibility:
+
+=============================
+ Maple-Arduino Compatibility
+=============================
+
+.. contents:: Contents
+ :local:
+
+Overview
+--------
+
+The biggest difference between the Maple and most Arduino boards is
+that the Maple uses a 32-bit ARM Cortex-M3 architecture chip, while
+the Arduinos have 8-bit Atmel AVR chips. The different instruction set
+means that machine code (which makes up executable binary programs) is
+incompatible between the two, and a different compiler (actually just
+a different version of `gcc <http://gcc.gnu.org/>`_) is required.
+
+The compiler for the regular Arduino IDE is the popular `avr-gcc
+<http://www.nongnu.org/avr-libc/>`_ package; the compiler for the
+Maple version of the IDE is CodeSourcery's edition of gcc for the ARM
+EABI target (:command:`arm-non-eabi-gcc`). A (preliminary) reference
+on :ref:`using arm-none-eabi-gcc <arm-gcc>` is available.
+
+The bitwidth of the processor means that the Maple can process 32-bit
+operations (like adding or multiplying two 32-bit integers) in a
+single instruction, while an Arduino processor would have to split up
+large operations into several smaller ones. In a lot of cases 8-bit
+operations are plenty (integers 0-255, single characters of text,
+etc.), but if you're dealing with higher resolution data, the speed up
+could be significant.
+
+A trade-off is that code could be larger as well; program instructions
+and memory locations can be up to 32 bits each. However, removal of
+extra instructions and fancy packing together of simple instructions
+means that programs aren't much larger (or are even smaller).
+
+Header Numbering and Incompatibilities
+--------------------------------------
+
+.. FIXME [Maple-specific values]
+
+The numbering of headers is different; on the Maple each GPIO has a
+unique number: 0, 1, 2, all the way up to 37 (actually, there are
+:ref:`a few more <lang-disabledebugports>`...). On the Arduino, the
+analog pins are numbered separately (A0-A5) from the digital pins (D0\
+-D13).
+
+The incompatible hardware differences are:
+
+* :ref:`I2C <i2c>` **port**: on most Arduinos, the |i2c| port is Analog
+ Input 4 (SDA) and Analog Input 5 (SCL); on the Maple, |i2c| port 1
+ is D5 (SCL) and D9 (SDA), and |i2c| port 2 is D29 (SCL) and D30
+ (SDA).
+
+ It should be possible to skywire, sacrificing signal quality (due to
+ increased capacitance). Alternatively, |i2c| can be bit-banged
+ reasonably well in software. This peripheral could potentially be
+ rerouted internally, but we haven't looked into it.
+
+* :ref:`PWM <pwm>` **on D10**: all the other standard Arduino PWM
+ headers have PWM functionality on the Maple (D2,D3,D6,D9,D11), but
+ not D10.
+
+* **No External Voltage Reference**: The Arduino has an AREF pin which
+ allows the use of an external ADC voltage reference; the Maple has
+ an extra GPIO pin (D14) with PWM capability in this spot, and does
+ not allow an external voltage reference to be configured.
+
+* **EEPROM**: the Maple does not have any internal EEPROM. This
+ functionality can be emulated with regular persistent flash memory,
+ or with an external EEPROM chip.
+
+* **ISP Programming**: the Maple does not use an ISP/ICSP bus for
+ debugging; it uses :ref:`JTAG <jtag>`.
+
+
+Software Language/Library Changes
+---------------------------------
+
+With :ref:`a few exceptions <language-missing-features>`, the entire
+Wiring/Arduino language is supported. However, there are some subtle
+differences, most of which are improvements:
+
+* **32-bit integers**: many standard functions either expect or return
+ full 32-bit (4 byte) integer values instead of the regular 16-bit (2
+ byte) Arduino values.
+
+* **64-bit doubles**: The :ref:`double <lang-double>` type is a full
+ double-precision floating point type on the Maple; it is a
+ single-precision floating point value on the Arduino.
+
+* :ref:`pinMode() <lang-pinmode>` **types**: any :ref:`GPIO <gpio>`
+ (including analog pins) can be configured into one of the following
+ modes with a single call to ``pinMode()``: ``OUTPUT``,
+ ``OUTPUT_OPEN_DRAIN``, ``INPUT_FLOATING``, ``INPUT_PULLUP``,
+ ``INPUT_PULLDOWN``. Additionally, the PWM pins (labeled "PWM" on the
+ silkscreen) can be configured in ``PWM`` and ``PWM_OPEN_DRAIN``
+ modes, and the analog input pins (labeled "AIN") can be configured
+ in ``INPUT_ANALOG`` mode. See the :ref:`GPIO documentation <gpio>`
+ for more information.
+
+* :ref:`Serial port <lang-serial>` **syntax**: like the `Arduino Mega
+ <http://arduino.cc/en/Main/ArduinoBoardMega>`_, the Maple has
+ multiple :ref:`USART ports <lang-serial>`. By default, ``Serial``
+ is not mapped to any of them. Use ``Serial1`` through ``Serial3``
+ instead.
+
+* **16-bit** :ref:`PWM <pwm>`: Arduino boards support 8-bit PWM, which
+ means that calls to :ref:`analogWrite() <lang-analogwrite>` take
+ values between 0 (always off) and 255 (always on). The Maple
+ supports 16-bit PWM, so the corresponding values should be between 0
+ (always off) and 65535 (always on).
+
+* **12-bit** :ref:`ADC <adc>`: Arduino boards support 10-bit ADC, which
+ means that calls to :ref:`analogRead() <lang-analogread>` will
+ return values between 0 and 1023. The Maple supports 12-bit ADC, so
+ the same call will instead return values between 0 and 4095.
+
+Shield and Device Compatibility
+-------------------------------
+
+**Can't find your shield?** Check out the `Compatible Shields
+<http://wiki.leaflabs.com/index.php?title=Compatible_Shields>`_ page
+on our wiki.
+
+.. list-table::
+ :header-rows: 1
+
+ * - Shield/Device
+ - Compatible?
+ - Notes
+
+ * - Ethernet shield
+ - Yes!
+ - Tested; no library yet
+
+ * - WiFi Shield
+ - Yes!
+ - Tested; preliminary library support
+
+ * - MIDI shield
+ - Yes!
+ - Tested; no library yet
+
+ * - XBee shield
+ - Unknown
+ -
+
+ * - Bluetooth shield
+ - Unknown
+ - Some Bluetooth <-> UART boards have been tested and are known
+ to work.
+
+ * - Cellular shield
+ - Unknown
+ -
+
+Library Porting Status
+----------------------
+
+The state of currently ported Arduino libraries is the
+:ref:`libraries`.
+
+.. TODO Update as libraries are ported.
+
+.. list-table::
+ :header-rows: 1
+
+
+ * - Library
+ - Ported?
+ - Notes
+
+ * - Wire
+ - Preliminary
+ - In progress; see :ref:`library reference <libraries-wire>`.
+
+ * - LiquidCrystal
+ - **Yes**
+ - :ref:`Included since IDE 0.0.7 <libraries-liquid-crystal>`
+
+ * - Ethernet
+ - Not yet
+ - Planned
+
+ * - EEPROM
+ - (Unsupported) third-party emulation
+ - The Maple doesn't have EEPROM; it uses flash instead. There is
+ an `EEPROM emulation library
+ <http://akb77.com/g/stm32/maple-eeprom-emulation-library/>`_ by
+ `x893 <http://akb77.com/g/>`_, but we haven't tested it.
+
+ * - Firmata
+ - Not yet
+ - Planned
+
+ * - Matrix
+ - Not yet
+ - Planned
+
+ * - Servo
+ - **Yes**
+ - :ref:`Included since IDE 0.0.9 <libraries-servo>`
+
+ * - SoftwareSerial
+ - Not yet
+ - Planned
+
+ * - Sprite
+ - Not yet
+ - Planned
+
+ * - Stepper
+ - Not yet
+ - Planned
+
+Sketch and Library Porting HOWTO
+--------------------------------
+
+In addition to the suggestions in this section, you may find many of
+the individual :ref:`language reference <language>` pages useful. As
+appropriate, these have "Arduino Compatibility" sections; one good
+example is the :ref:`analogWrite() <lang-analogwrite-compatibility>`
+function.
+
+- Check the hardware and header differences above, and see if your
+ project or shield needs to be modified (eg, add 3.3V level
+ converters or reroute PWM to header D10).
+
+- Check for ported library functionality. We intend to port all of the
+ core and popular libraries (like Wire, Ethernet, and the LCD screen
+ driver), but this task is not yet finished. (:ref:`Patches are
+ welcome! <libmaple-contributing>`).
+
+- Check for peripheral conflicts; changing the configuration of timers
+ and bus speeds for a feature on one header may impact all the
+ features on that hardware "port". For example, changing the timer
+ prescaler to do long PWM pulses could impact |i2c| communications on
+ nearby headers.
+
+- Rewrite any low-level code. This could potentially be very
+ difficult, but hopefully you've used the Arduino libraries to
+ abstract away the registers and other hardware-specific
+ details. Your sketch probably doesn't have any low-level code; a
+ library which wraps a particular peripheral very well may. Some
+ help is available in the :ref:`arm-gcc` reference.
+
+- Redeclare variable sizes if necessary: generics like ``int`` will
+ probably work unless you depend on side-effects like rollover.
+
+- Check every ``pinMode()``: the Maple has more modes for GPIO
+ pins. For example, make sure to set analog pins to ``INPUT_ANALOG``
+ before reading and PWM pins to ``PWM`` before writing. The full set
+ of pin modes is documented in the :ref:`lang-pinmode` reference.
+
+- Modify PWM writes: ``pinMode()`` must be set to ``PWM``, the
+ frequency of the PWM pulse configured, and the duty cycle written
+ with up to 16-bit resolution.
+
+- Modify ADC reads: :ref:`lang-analogread` takes the full pin number
+ (not 0-5) and returns a full 12-bit reading. The ADC pin must have
+ its ``pinMode()`` set to ``INPUT_ANALOG``.
+
+- Possibly convert all Serial-over-USB communications to use
+ :ref:`lang-serialusb` instead of a USART :ref:`serial port
+ <lang-serial>`. The Maple has a dedicated USB port which is not
+ connected to the USART TX/RX pins in any way.
+
+- Check timing: Maple clock cycles are just 13.9 nanoseconds, though
+ the peripheral bus speeds (which limit GPIO output) are clocked
+ slower.
diff --git a/docs/source/arm-gcc.rst b/docs/source/arm-gcc.rst
new file mode 100644
index 0000000..30667a2
--- /dev/null
+++ b/docs/source/arm-gcc.rst
@@ -0,0 +1,107 @@
+
+.. _arm-gcc:
+
+GCC and libc
+============
+
+This document provides notes on using ``arm-none-eabi-gcc``, the
+`CodeSourcery <http://www.codesourcery.com/>`_ version of the GNU `GCC
+<http://gcc.gnu.org/>`_ compilers used for the Maple boards. It is
+not intended as a reference manual for GCC; such manuals are available
+`elsewhere <http://gcc.gnu.org/>`_.
+
+.. contents:: Contents
+ :local:
+
+Obtaining ``arm-none-eabi-gcc``
+-------------------------------
+
+Recent versions of ``arm-none-eabi-gcc`` and associated tools are
+included with the :ref:`Maple IDE <ide>`.
+
+Users who wish to use ``arm-none-eabi-gcc`` directly, along with a
+standard Unix Make-based toolchain, should read the
+:ref:`unix-toolchain`, which describes how to set up such an
+environment.
+
+LeafLabs maintains `mirrors
+<http://static.leaflabs.com/pub/codesourcery/>`_ for some of the more
+recent versions of the compiler, including versions for OS X, Win32,
+and 32-bit Linux.
+
+.. _arm-gcc-compiler-flags:
+
+Compiler Flags Used by libmaple
+-------------------------------
+
+This section documents the flags passed to ``arm-none-eabi-gcc`` by
+the :ref:`Maple IDE <ide>` and the default Makefile provided with the
+:ref:`Unix toolchain <unix-toolchain>`. The information in this
+section is subject to change between :ref:`libmaple <libmaple>`
+releases.
+
+.. highlight:: sh
+
+The following flags are among those passed to the C compiler::
+
+ -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib
+ -ffunction-sections -fdata-sections -Wl,--gc-sections
+
+In addition to those flags just given for the C compiler, the
+following flags are among those passed to the C++ compiler::
+
+ -fno-rtti -fno-exceptions -Wall
+
+The following flags are among those passed to the assembler::
+
+ -mcpu=cortex-m3 -march=armv7-m -mthumb
+
+.. highlight:: cpp
+
+.. _arm-gcc-libc:
+
+Using the C Standard Library
+----------------------------
+
+By default (under both the :ref:`Maple IDE <ide>` and the :ref:`Unix
+toolchain <unix-toolchain>`), ``arm-none-eabi-gcc`` is configured to
+link against `newlib <http://sourceware.org/newlib/>`_, a C standard
+library intended for use with embedded applications. You are free to
+include of any of its headers.
+
+Be advised, however, that a variety of syscalls may only be partially
+implemented, if at all. See the :ref:`libmaple` file syscalls.c and
+the newlib documentation for more details.
+
+.. _arm-gcc-avr-gcc:
+
+Switching from AVR-GCC
+----------------------
+
+This section, which is expected to grow over time, describes
+techniques for porting code which uses AVR-GCC features (AVR-GCC is
+the compiler used by many Atmel AVR-based microcontroller boards,
+including Arduino) for use on the Maple.
+
+.. _arm-gcc-attribute-flash:
+
+- Replacing ``PROGMEM``: If you need to store a lot of constant data,
+ you can store variables in Flash (instead of RAM) by using the
+ libmaple macro ``__FLASH__``. Here's an example::
+
+ uint32 array[] __FLASH__ = {0, 1, 2};
+
+ This will help you save RAM when you need to store large amounts of
+ data, like look-up tables.
+
+ You can only store values which are compile-time constants (like
+ numbers and strings, and arrays of numbers and strings) in this way.
+ Also, if you try to change a variable stored in Flash, your program
+ will crash.
+
+ If you need to port over AVR/Arduino code that uses pgmspace.h,
+ these declarations may help you::
+
+ typedef const unsigned char prog_uchar;
+ #define pgm_read_byte_near(x) (*(prog_uchar*)x)
+ #define pgm_read_byte(x) (*(prog_uchar*)x)
diff --git a/docs/source/bootloader.rst b/docs/source/bootloader.rst
new file mode 100644
index 0000000..23b0448
--- /dev/null
+++ b/docs/source/bootloader.rst
@@ -0,0 +1,750 @@
+.. highlight:: sh
+
+.. _bootloader:
+
+Maple Bootloader(s)
+===================
+
+The firmware which allows the Maple to be reprogrammed via a USB
+connection. Every Maple board comes programmed with this by default,
+and it is not overwritten by regular programs (it lives lower in the
+Flash memory and only runs when the chip is reset).
+
+**Check out the latest source code version:** ::
+
+ git clone git://github.com/leaflabs/maple-bootloader.git
+
+**Visit the GitHub development project**: https://github.com/leaflabs/maple-bootloader
+
+.. contents:: Contents
+ :local:
+
+Bootloader Schemes Explained
+----------------------------
+
+Maple Rev 3 and Rev 5 (Rev 5 is the version currently shipping)
+represents a drastic remake of the core library as well as the upload
+process. Thes changes to the bootloader, were implemented to resolve
+platform-specific issues on Windows. Before delving into how the Rev
+1 bootloader worked and how the Rev 5 bootloader works now, we'll
+discuss the features common to each and touch a bit on the Arduino
+setup.
+
+This is a fairly involved explanation, with a lot of details that are
+likely only interesting to a few. If you just want to get the rough
+idea, skim this article. If you want to start hacking on the
+bootloader, get in touch with us to get even more info on how this all
+works. And finally, you can always `check out the code at GitHub
+<https://github.com/leaflabs/libmaple>`_!
+
+Arduino
+-------
+
+Arduino is based off of AVR series microcontrollers, most of which
+lack USB support. Thus, boards like the Duemilanove add USB capability
+via an FTDI USB-to-Serial converter chip. This chip interfaces with
+the AVR over an RS-232 serial interface. When you plug an Arduino into
+a computer, only an FTDI driver is needed. Since the FTDI chip is
+separate from the AVR, you can reset the Arduino without closing this
+USB connection with the FTDI chip.
+
+To program an Arduino, the host machine sends a command over the USB
+pipe (reset DTR) which in turn resets the AVR. The AVR will boot into
+a bootloader, which waits for a second for any upload commands over
+serial. The host machine can either send those commands, or do
+nothing. If it does nothing, the AVR will quickly jump to user code
+and off you go. The whole process is quick, the bootloader doesn’t
+live for very long, and will exit almost immediately if no upload
+commands are received.
+
+Maple Rev 1
+-----------
+
+Maple is based off the STM32 (ARM cortex M3) series chips, which do
+have embedded USB support. Thus, Maple doesn’t need the extra FTDI
+chip. Firmware is uploaded via the standard DFU protocol (also used by
+iPhone and openMoko). Since DFU is a standard, there is no need for
+custom software running on the host to upload the firmware. Any DFU
+compliant program will work. The Maple IDE is based around
+:command:`dfu-util`, openMoko’s DFU utility. Using DFU came at a cost,
+however. The USB port must additionally implement a separate serial
+port at the same time (we use the CDC ACM class for serial
+functionality).
+
+Maple Rev 1 attempted to run both DFU and CDC ACM devices
+simultaneously on the USB peripheral. On Linux, this worked great. The
+OS would service the DFU driver during uploads, and the CDC ACM for
+serial port transactions. There was no reset necessary for uploads. No
+waiting. The bootloader was always running the background, ready to
+receive commands.
+
+The problem was that *only* Linux did this. Windows refused to attach
+more than one driver to a single USB device without repackaging the
+DFU and CDC ACM into a single IAD Compound Device. It's not terribly
+important what this means, except for two things.
+
+1. Four drivers were necessary to make everything work.
+2. IAD is not supported by OS X.
+
+Mac OS X, on the other hand, only supported Compound USB, a different
+trick that is not supported by Windows. While a perpetual background
+bootloader was attractive, it became clear, after much toiling, we
+were going to have to write custom drivers across several platforms to
+make everything work this way.
+
+.. _bootloader-rev3:
+
+Maple Rev3/Rev5 - DFU
+---------------------
+
+Maple Rev 3 takes a completely different tack, more along the lines of
+Arduino. In Rev 3, the device resets into bootloader mode, which
+stays alive for a few moments to receive commands, and then jumps to
+user code. The bootloader is implemented as a DFU device -- just a DFU
+device, no serial port. This requires one driver for Windows
+(:file:`drivers/mapleDrv/dfu` in the Windows IDE directory).
+
+As part of the :ref:`libmaple <libmaple>` library, user code is
+automatically supplied with serial support via some behind the scenes
+work (``setupUSB()`` is called from ``init()``). This user mode code
+only implements a CDC ACM class USB device, giving you functions like
+:ref:`SerialUSB.read() <lang-serialusb-read>`. Separating these two
+modes fixed the driver issues and works well across platforms,
+requiring only two drivers (serial and DFU) on Windows.
+
+However, it is no longer possible to upload code at will, since there
+is no bootloader quietly listening in the background. Instead, you
+must reset the board, then initiate a DFU transaction. The IDE
+performs this reset automatically by performing a special sequence of
+changes on the USB serial port:
+
+1. Pulse DTR (high and then low, so that you've created a negative
+ edge)
+2. Write "1EAF" in ASCII over the serial pipe. This will cause Maple
+ to reset. Only the first 4 bytes after a negative edge of DTR are
+ checked for this command, so it's important you actually create a
+ negative edge, rather than just ensuring DTR is low.
+
+After the reset, the host OS takes a few moments (.5-2 seconds) to
+re-enumerate the device as DFU. This delay is unpredictable, and is
+the reason the bootloader on Maple Rev 3/Rev 5 stays alive for so
+long. (Sometimes, the bootloader was exiting before the OS had even
+enumerated the device.)
+
+Once in bootloader mode, :command:`dfu-util` uploads your sketch into
+either flash or RAM (DFU alternate setting 0 or 1, respectively) and
+resets the board again. This time, however, no DFU transaction is
+initiated, and the bootloader gives way to user code, closing down the
+DFU pipe and bringing up the USB serial port.
+
+.. .. _bootloader-rev6:
+
+.. Maple Rev6 - The Serial Bootloader (Tentative)
+.. ----------------------------------------------
+
+.. .. note:: This section documents an in-progress version of the Maple
+.. bootloader. **No Maples yet sold use this bootloader protocol**.
+.. It has not been yet been publicly released, and its interface is
+.. not stable.
+
+.. The bootloader in Rev3/Rev5 works well on Linux, acceptably on Mac,
+.. but was unsatisfactory on Windows. Unlike the other operating systems,
+.. Windows needed to be manually pointed to both the driver to use for
+.. programming (DFU, via `libusb <http://www.libusb.org/>`_) and the
+.. driver to use for serial communication (usbser.sys, built in to
+.. Windows). Since Maple operates in only one of these modes at a time,
+.. driver installation was unnecessarily complicated. It was necessary to
+.. bring Maple into the correct mode before installing each of the
+.. drivers. Furthermore, because libusb is not bundled with Windows, and
+.. its driver is not signed, Windows 7 users have been forced to
+.. laboriously disable driver signing checks. Finally, Windows hates the
+.. constant switching of the device between Serial and DFU modes (during
+.. programming), and often prompts users to install drivers that are
+.. already installed. We have therefore decided to abandon DFU.
+
+.. In our new bootloader scheme, Maple is simply a serial device.
+.. Windows comes bundled with usbser.sys, so no driver signing is
+.. required. The IDE installation process is greatly simplified, there
+.. is no more switching back and forth between "modes", and we can build
+.. in new functionality outside the DFU spec.
+
+.. The first incarnation of this serial-only bootloader leaves libmaple
+.. and user code untouched. However, during programming, instead of
+.. calling :command:`dfu-util` to upload code we will now call a newly
+.. written utility script similar to `avr-dude
+.. <http://savannah.nongnu.org/projects/avrdude/>`_. The high level
+.. operation of the bootloader will remain the same - come on at startup,
+.. wait for an upload operation or timeout, and jump to user code.
+
+.. The second version of this bootloader will eliminate this dependence
+.. on resetting and timing out by having the bootloader run in the
+.. background. It will additionally own the serial port. In this scheme,
+.. sending data over the COM port while DTR is pulled low results in that
+.. packet being captured by the bootloader and interpreted as a
+.. bootloader command. When the user uploads a new program, the
+.. bootloader will overwrite the old one, reset the various peripheral
+.. registers, and jump to user code. All of this will occur without
+.. resetting the chip and thus causing Maple to connect and disconnect
+.. from your computer (which seems to cause many problems).
+
+.. The final version of this bootloader scheme will involve a separate
+.. microcontroller, whose responsibilities are to drive the USB port,
+.. program the main processor, and offer some amount of debugging
+.. capability. This will allow user sketches to run on the bare metal of
+.. the main processor, without any bootloader hiding underneath. This
+.. approach is similar to the approaches taken by mbed and the Arduino
+.. Uno.
+
+.. Regardless of which generation of the new serial bootloader you are
+.. working with, the command interface is the same. The low level
+.. communication protocol is inspired by STK-500, the protocol used to
+.. program many AVR-based development boards. The protocol is a
+.. packetized query-response scheme. The host PC initiates every
+.. transaction, and for every query sent to the bootloader, a single
+.. response will be returned (or the system times out). Data is
+.. transmitted over 115.2kbps, 8 data bits, 1 stop bit, no parity
+.. bit. Every query or response follows the same packet format that looks
+.. like this:
+
+.. .. _bootloader-packet-structure:
+
+.. Packet Structure
+.. ^^^^^^^^^^^^^^^^
+
+.. A bootloader packet is composed of a sequence of fields, as follows.
+
+.. .. list-table::
+.. :header-rows: 1
+
+.. * - Field
+.. - Length (bytes)
+.. - Value
+.. - Description
+
+.. * - START
+.. - 1
+.. - 0x1B
+.. - Magic constant, indicates bootloader packet
+
+.. * - SEQUENCE_NUM
+.. - 1
+.. - 0--0xFF
+.. - Queries and responses must have the same sequence number; rolls
+.. over to 0 after 0xFF
+
+.. * - MESSAGE_SIZE
+.. - 2
+.. - 0--0xFFFF
+.. - Size of message body, currently limited to a 1024B=1KB maximum
+
+.. * - TOKEN
+.. - 1
+.. - 0x7F
+.. - Differs from STK500 value of 0x0E
+
+.. * - MESSAGE_BODY
+.. - Variable, determined by MESSAGE_SIZE field
+.. - Command query or response
+.. - See :ref:`next section <bootloader-commands>`
+
+.. * - CHECKSUM
+.. - 4
+.. - XOR of all other 32-bit words in packet
+.. - See :ref:`below <bootloader-checksum>`
+
+.. .. _bootloader-checksum:
+
+.. .. highlight:: cpp
+
+.. .. note:: When computing the checksum, the words in a packet are
+.. interpreted big-endian (as if the packet were a sequence of 32-bit,
+.. big-endian unsigned integers). If the end of the MESSAGE_BODY is
+.. not aligned with a four-byte boundary, then the checksum will treat
+.. it as if it was padded with zero bytes to a four-byte boundary.
+
+.. As a concrete example, an entire GET_INFO query (see :ref:`below
+.. <bootloader-get-info>`), including the packet structure, is
+.. comprised of the byte sequence ::
+
+.. {0x1B, 0x7F, 0x00, 0x01, 0x7F, 0x00, 0x64, 0x7F, 0x00, 0x01}
+
+.. The SEQUENCE_NUM of this query is 0x7F.
+
+.. .. highlight:: sh
+
+.. .. _bootloader-commands:
+
+.. Commands
+.. ^^^^^^^^
+
+.. The packet structure overhead is for reliability. The actual queries
+.. and responses are transacted inside of the message body. Following
+.. the STK-500 protocol, each query or response begins with the single
+.. byte command field. For each query, the resultant response must begin
+.. with the same CMD byte. For each type of command, the structure of
+.. queries and responses is of fixed size.
+
+.. Also following STK-500, fields longer than 1 byte are transmitted MSB
+.. first (big-endian). However, READ and WRITE commands operate byte-wise
+.. (not word-wise); it is up to the host PC to ensure that alignment and
+.. ordering issues are handled appropriately.
+
+.. .. _bootloader-get-info:
+
+.. GET_INFO
+.. """"""""
+
+.. Used to query device characteristics.
+
+.. GET_INFO Query:
+
+.. .. list-table::
+.. :header-rows: 1
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - GET_INFO
+.. - 1
+.. - Value 0
+
+.. GET_INFO Response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 4 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - GET_INFO
+.. - 1
+.. - Value 0
+
+.. * - Endianness
+.. - 1
+.. - 0 indicates little-endian, 1 indicates big-endian.
+.. (Currently returns 0; this field allows for future
+.. expansion).
+
+.. * - Available Ram
+.. - 4
+.. - In bytes
+
+.. * - Available Flash
+.. - 4
+.. - In bytes
+
+.. * - Flash Page Size
+.. - 2
+.. - In bytes
+
+.. * - Starting Address (FLASH)
+.. - 4
+.. - Usually 0x08005000
+
+.. * - Starting Address (RAM)
+.. - 4
+.. - Usually 0x200000C0
+
+.. * - Bootloader Version
+.. - 4
+.. - Current version 0x00060000 (MAJ,MIN)
+
+.. .. _bootloader-erase-page:
+
+.. ERASE_PAGE
+.. """"""""""
+
+.. Used to erase flash pages.
+
+.. ERASE_PAGE query:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 4 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - ERASE_PAGE
+.. - 1
+.. - Value 1
+
+.. * - ADDRESS
+.. - 4
+.. - Will erase whichever page contains ADDRESS
+
+.. ERASE_PAGE response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 3 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - ERASE_PAGE
+.. - 1
+.. - Value 1
+
+.. * - SUCCESS
+.. - 1
+.. - Either 0 (failure) or 1 (success)
+
+.. WRITE_BYTES
+.. """""""""""
+
+.. Used to write to RAM or flash.
+
+.. WRITE_BYTES query:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 4 4 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - WRITE_BYTES
+.. - 1
+.. - Value 2
+
+.. * - Starting Address
+.. - 4
+.. - Can address arbitrary RAM, or :ref:`cleared
+.. <bootloader-erase-page>` flash pages.
+
+.. * - DATA
+.. - MESSAGE_SIZE - 5
+.. - See :ref:`Packet Structure <bootloader-packet-structure>`
+
+.. WRITE_BYTES response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - WRITE_BYTES
+.. - 1
+.. - Value 2
+
+.. * - SUCCESS
+.. - 1
+.. - Either 0 (failure) or 1 (success). Will fail if writes were
+.. made to uncleared pages. Does not clean up failed writes
+.. (memory will be left in an undefined state).
+
+.. READ_BYTES
+.. """"""""""
+
+.. Used to read from RAM or flash.
+
+.. READ_BYTES query:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - READ_BYTES
+.. - 1
+.. - Value 3
+
+.. * - ADDRESS
+.. - 4
+.. - Start of block to read. Must be a multiple of 4.
+
+.. * - LENGTH
+.. - 2
+.. - Maximum number of bytes to read (currently, this may be at most
+.. 1024 = 1KB). Must be a multiple of 4.
+
+.. READ_BYTES response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 2 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - READ_BYTES
+.. - 1
+.. - Value 3
+
+.. * - DATA
+.. - MESSAGE_SIZE - 1
+.. - Contains read bytes. The actual number of bytes read may be
+.. less than the LENGTH field of the corresponding READ_BYTES
+.. query. If this section is of length 0, this should be
+.. interpreted as a read failure. See
+.. :ref:`bootloader-packet-structure`.
+
+.. JUMP_TO_USER
+.. """"""""""""
+
+.. Causes the bootloader to jump to user code's starting address.
+
+.. JUMP_TO_USER query:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 1 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - JUMP_TO_USER
+.. - 1
+.. - Value 4
+
+.. * - Location
+.. - 1
+.. - 0 means jump to flash starting address, 1 means jump to RAM
+.. starting address. See the :ref:`bootloader-get-info` command
+.. for more information.
+
+.. JUMP_TO_USER response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 1 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - JUMP_TO_USER
+.. - 1
+.. - Value 4
+
+.. * - SUCCESS
+.. - 1
+.. - Either 0 (failure) or 1 (success). If successful, after the
+.. response is sent, the bootloader ends this session and jumps to
+.. the user code in flash or RAM as specified in the query's
+.. Location field.
+
+
+.. SOFT_RESET
+.. """"""""""
+
+.. Engages a full software reset.
+
+.. SOFT_RESET query:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 1 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - SOFT_RESET
+.. - 1
+.. - Value 5
+
+.. SOFT_RESET response:
+
+.. .. list-table::
+.. :header-rows: 1
+.. :widths: 2 1 10
+
+.. * - Field
+.. - Bytes
+.. - Comments
+
+.. * - SOFT_RESET
+.. - 1
+.. - Value 5
+
+.. * - SUCCESS
+.. - 1
+.. - Either 0 or 1 (FAILED and OK, respectively). Will end this
+.. bootloader session and reset the processor.
+
+.. _bootloader-reflashing:
+
+Flashing A Custom Bootloader
+----------------------------
+
+.. warning:: This section is for users who want to put a fresh or
+ custom bootloader on their board. It's possible to make a mistake
+ in this process and e.g. render your Maple unable to communicate
+ with the IDE. Know what you're doing, and proceed with caution.
+
+The STM32 microprocessor on the Maple comes with a built-in serial
+bootloader that can be used to flash a new (software) bootloader onto
+the chip. While the Maple bootloader is just a program, the built-in
+serial bootloader is part of the STM32 hardware, so it's always
+available.
+
+This means that you can **always** follow these instructions to put a
+new bootloader program on your board; it **doesn't matter** if there's
+already a copy of the Maple bootloader on it or not.
+
+If you have a Maple Rev 1; you don't have a BUT button, and won't be
+able to follow these directions. A workaround is detailed in `this
+forum posting <http://forums.leaflabs.com/topic.php?id=32#post-126>`_.
+
+.. highlight:: sh
+
+Setup
+^^^^^
+
+In order to follow these instructions, you will need:
+
+- A binary of the bootloader you want to upload (see below).
+- Hardware for communicating between the Maple and your computer over
+ serial.
+- `Python <http://python.org>`_, version 2.5 or higher.
+- The `PySerial <http://pyserial.sourceforge.net/>`_ library (this
+ must be installed separately; it is not part of the Python standard
+ library).
+
+**Step 1: Obtain a bootloader binary**. If you want to re-flash the
+"factory-default" bootloader, LeafLabs hosts pre-compiled copies:
+
+- `Maple <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_boot.bin>`_
+- `Maple Mini <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_mini_boot.bin>`_
+- `Maple RET6 Edition <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_RET6_boot.bin>`_
+- `Maple Native <http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_native_boot.bin>`_
+
+To flash a customized version of a LeafLabs bootloader, you can run
+(on a :ref:`suitably configured system <unix-toolchain>`) the
+following to obtain a bootloader binary::
+
+ $ git clone git://github.com/leaflabs/maple-bootloader.git
+ $ cd maple-bootloader
+ $ make
+ $ ls -lh build/maple_boot.bin # this is the compiled bootloader binary
+
+.. note:: If you plan to write a totally custom bootloader, you'll
+ need an actual binary to use these instructions. An ASCII
+ representation of the binary, such as the Intel .hex format, won't
+ work.
+
+**Step 2: Connect Maple Serial1 to your computer**.
+There are a variety of ways of doing this. We use Sparkfun's `FTDI
+breakout boards <http://www.sparkfun.com/products/718>`_, but you
+could use another Maple, an Arduino, etc. -- anything that allows your
+computer to communicate with the Maple you want to reprogram over a
+serial interface.
+
+If you do use an FTDI breakout board, first make sure your Maple is
+disconnected from an external power source, be it battery, USB, or
+barrel jack. Then, connect the FTDI board's TX pin to ``Serial1``\ 's
+RX pin (labeled "RX1" on the silkscreen), FTDI RX to ``Serial1`` TX
+(labeled "TX1"), FTDI ground to ground (labeled GND), and its 3.3V pin
+to Vin. On Maple Mini, you will also need to tie BOOT1 (pin 2) to
+ground.
+
+More information on ``Serial1`` is available :ref:`here
+<lang-serial>`.
+
+At this point, you're ready to plug the FTDI board into your computer
+(via USB).
+
+**Step 3: Run the built-in hardware serial bootloader**\
+[#fserbootmode]_. Accomplish this using the following steps:
+
+1. Press and hold the reset and BUT buttons.
+2. Release the reset button *without releasing BUT*.
+3. Release BUT.
+
+At this point, if you followed the instructions correctly, the board
+will appear unresponsive -- the LED won't blink, etc. Don't worry.
+This is the expected behavior for the serial bootloader.
+
+Do not confuse the above steps, which run the built-in serial
+bootloader, with the steps for :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>`.
+
+**Step 4: Get stm32loader.py**. You can download it directly from
+`libmaple's GitHub page
+<https://github.com/leaflabs/libmaple/raw/master/support/stm32loader.py>`_
+(click the link, then save the file somewhere on your system). If you
+have set up the :ref:`Unix toolchain <unix-toolchain>`, it's the file
+libmaple/support/stm32loader.py.
+
+Flashing the new Bootloader
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We'll use ``maple_boot.bin`` as the path to the bootloader binary from
+Step 1, and ``ser-port`` as the Maple's serial port device file or COM
+port.
+
+* On **Linux**, ``ser-port`` will probably be something like
+ ``/dev/ttyUSB0``, although the exact number could be different (it
+ could be ``/dev/ttyUSB1``, ``/dev/ttyUSB2``, etc.).
+
+* On **OS X**, ``ser-port`` will probably look like
+ ``/dev/tty.usbserialXXXX``, where ``XXXX`` is some random string of
+ characters.
+
+* On **Windows**, ``ser-port`` will be something like ``COM1``, ``COM2``, etc.
+
+.. highlight:: sh
+
+To upload a bootloader binary, run this command from the Unix shell::
+
+ python stm32loader.py -p ser-port -evw maple_boot.bin
+
+Or this command from the Windows command prompt::
+
+ python.exe stm32loader.py -p ser-port -evw maple_boot.bin
+
+You can also run the following to get usage information::
+
+ # Unix:
+ python stm32loader.py -h
+
+ # Windows:
+ python.exe stm32loader.py -h
+
+If all goes well, you'll see a bunch of output, then "Verification
+OK". Your board now has a fresh bootloader installed.
+
+The first time you upload a program after installing a new bootloader,
+there is no need to select a serial port in the :ref:`IDE <ide>`
+[#fbootser]_. Perform this first upload with no serial port selected.
+The IDE will emit a warning about not finding a serial port, but the
+upload will still succeed. In subsequent uploads, select a serial
+port as you normally would.
+
+If something goes wrong, the `forum`_ is probably your best bet for
+obtaining help, with IRC (server irc.freenode.net, channel
+#leafblowers) being another option. If all else fails, you can always
+`contact us directly`_!
+
+.. rubric:: Footnotes
+
+.. [#fbootser] This is because immediately after installing a new
+ bootloader, the only program on your board is the
+ bootloader itself. Unlike a normal sketch, the
+ bootloader is not enumerated as a virtual serial port
+ (it uses DFU instead; see :ref:`above
+ <bootloader-rev3>` for more details).
+
+.. [#fserbootmode] Resetting your board in this way runs a special
+ bootloader that ST builds into their chips'
+ hardware, which communicates over :ref:`usart`.
+ This is different from the LeafLabs bootloader,
+ which is a normal program that runs on your board,
+ and communicates over :ref:`usb`.
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..f4a9bbb
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,283 @@
+# -*- coding: utf-8 -*-
+#
+# libmaple documentation build configuration file, created by
+# sphinx-quickstart on Thu Oct 7 06:42:30 2010.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+import os.path
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# We rely on Michael Jones's breathe as a Doxygen-to-Sphinx bridge.
+# See the README for information on obtaining it and letting Sphinx
+# know where it is.
+sys.path.append(os.environ['BREATHE_HOME'])
+
+# -- General configuration ----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest',
+ 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
+ 'sphinx.ext.coverage', 'breathe']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'contents'
+
+# General information about the project.
+project = u'Maple'
+copyright = u'2010, 2011, LeafLabs, LLC'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.0'
+# The full version, including alpha/beta/rc tags.
+# FIXME [RELEASE] update this for the release
+release = 'custom-build'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['epilog.rst', 'prolog.rst']
+
+# Included at the end of every source file that is read.
+with open('epilog.rst', 'r') as ep:
+ rst_epilog = ep.read()
+
+# Included at the beginning of every source file that is read.
+with open('prolog.rst', 'r') as pr:
+ rst_prolog = pr.read()
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# Warn about all references where the target cannot be found.
+nitpicky = True
+
+# -- Options for HTML output --------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+html_theme_options = {
+ ## Sidebar placement options
+ #'stickysidebar' : 'true',
+ 'rightsidebar' : 'true',
+ #'collapsiblesidebar' : 'true',
+
+ ## Color
+ 'sidebarbgcolor' : '#C8C8C8',
+ 'sidebarlinkcolor' : 'green',
+ 'sidebartextcolor' : 'black',
+ #'sidebarbtncolor' : 'black',
+ 'footerbgcolor' : 'green',
+ 'relbarbgcolor' : 'green',
+ 'headlinkcolor' : '#000000',
+ 'linkcolor' : 'green',
+ #'visitedlinkcolor' : 'green',
+
+ ## Font
+ 'headfont' : 'Georgia',
+ 'bodyfont' : 'Lucida'
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = ['_static']
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+html_title = project + ' v' + release
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+html_short_title = 'Index'
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = '_static/img/round_logo_60x60.png'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = '_static/img/round_logo_32x32.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+ '**': ['globaltoc.html', 'searchbox.html'],
+}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+html_additional_pages = {
+ 'index': 'indexcontent.html'
+}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+html_use_index = False
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'mapledoc'
+
+
+# -- Options for LaTeX output -------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target file, title, author, documentclass [howto/manual])
+latex_documents = [
+ ('index', 'maple.tex', u'Maple Documentation',
+ u'LeafLabs, LLC', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output -------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'maple', u'Maple Documentation',
+ [u'LeafLabs, LLC'], 1)
+]
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+#intersphinx_mapping = {'http://docs.python.org/': None}
+
+
+# -- Options for breathe integration ------------------------------------------
+
+# We allow people to check in Doxygen XML into maintenance branches.
+doxygen_xml_maybe = os.path.join(os.path.dirname(os.path.dirname(__file__)),
+ 'doxygen', 'xml')
+if os.path.isdir(doxygen_xml_maybe):
+ # There's a doxygen/xml/ directory in this repository root, use that.
+ doxygen_xml_dir = doxygen_xml_maybe
+else:
+ # Nothing there, assume it's in LIB_MAPLE_HOME.
+ doxygen_xml_dir = os.path.join(os.environ['LIB_MAPLE_HOME'],
+ 'doxygen', 'xml')
+
+breathe_projects = {'libmaple' : doxygen_xml_dir}
+
+breathe_default_project = 'libmaple'
diff --git a/docs/source/contents.rst b/docs/source/contents.rst
new file mode 100644
index 0000000..7be7aec
--- /dev/null
+++ b/docs/source/contents.rst
@@ -0,0 +1,73 @@
+.. _index:
+
+Contents in Full
+================
+
+.. _index-usage:
+
+**Getting Started**
+
+.. toctree::
+ :maxdepth: 2
+
+ maple-quickstart
+ maple-ide-install
+ ide
+ unix-toolchain
+ unix-toolchain-linux-setup
+ unix-toolchain-osx-setup
+ unix-toolchain-win-setup
+ whats-new
+
+.. _index-maple-programming:
+
+**Programming**
+
+.. toctree::
+ :maxdepth: 2
+
+ language
+ libraries
+ arduino-compatibility
+ libmaple
+ bootloader
+ troubleshooting
+ FAQ <faq>
+ arm-gcc
+ language-index
+
+.. _index-hardware:
+
+**Hardware and Peripherals**
+
+.. toctree::
+ :maxdepth: 2
+
+ stm32
+ adc
+ external-interrupts
+ fsmc
+ gpio
+ i2c
+ jtag
+ pwm
+ spi
+ timers
+ systick
+ usb
+ usart
+
+.. _index-boards:
+
+**Boards**
+
+.. toctree::
+ :maxdepth: 2
+
+ hardware/maple.rst
+ hardware/maple-ret6.rst
+ hardware/maple-mini.rst
+ hardware/maple-native-beta.rst
+
+.. TODO [Maple Native] write/include upon finished Native release
+.. hardware/maple-native.rst
diff --git a/docs/source/epilog.rst b/docs/source/epilog.rst
new file mode 100644
index 0000000..b548001
--- /dev/null
+++ b/docs/source/epilog.rst
@@ -0,0 +1,14 @@
+.. This file automatically gets included at the end of every file, so
+.. it's useful for common references, etc.
+
+.. Common URL references
+
+.. _forum: http://forums.leaflabs.com
+.. _contact: http://leaflabs.com/contact/
+.. _contact us directly: http://leaflabs.com/contact/
+.. _Python: http://python.org/download/
+.. _PySerial: http://pyserial.sourceforge.net/
+.. _OpenMoko: http://openmoko.com/
+.. _Git: http://git-scm.com/
+.. _dfu-util: http://wiki.openmoko.org/wiki/Dfu-util
+.. _easy_install: http://packages.python.org/distribute/easy_install.html
diff --git a/docs/source/external-interrupts.rst b/docs/source/external-interrupts.rst
new file mode 100644
index 0000000..209d5af
--- /dev/null
+++ b/docs/source/external-interrupts.rst
@@ -0,0 +1,68 @@
+.. highlight:: cpp
+
+.. _external-interrupts:
+
+External Interrupts
+===================
+
+External interrupts can be used to make a voltage change on a
+:ref:`pin <gpio>` (the pin going from :ref:`LOW <lang-constants-low>`
+to :ref:`HIGH <lang-constants-high>`, or vice-versa) to cause a
+function to be called. This can be used to avoid checking for changes
+on a pin "manually" by waiting in a loop until the pin changes.
+
+.. _contents: Contents
+ :local:
+
+Overview
+--------
+
+External interrupts are often used to detect when events happen
+outside of the Maple. Example events include when a sensor has data
+ready to be read, or when a button has been pushed. When such an
+event happens, an interrupt is raised, and the Maple stops whatever it
+was doing (it is "interrupted"), and reacts to the event by calling a
+function (called an *interrupt handler*) which you specify using
+:ref:`lang-attachinterrupt`.
+
+.. _external-interrupts-exti-line:
+
+Any pin can be used for external interrupts, but there are some
+restrictions. At most 16 different external interrupts can be used at
+one time. Further, you can't just pick any 16 pins to use. This is
+because every pin on the Maple connects to what is called an *EXTI
+line*, and only one pin per EXTI line can be used for external
+interrupts at a time [#fextisports]_.
+
+The EXTI Line Pin Map for your board lists which pins connect to which
+EXTI lines:
+
+* :ref:`Maple <maple-exti-map>`
+* :ref:`Maple RET6 Edition <maple-ret6-exti-map>`
+* :ref:`Maple Mini <maple-mini-exti-map>`
+* :ref:`Maple Native Beta <maple-native-b-exti-map>`
+
+Function Reference
+------------------
+
+- :ref:`attachInterrupt() <lang-attachinterrupt>`
+- :ref:`detachInterrupt() <lang-detachinterrupt>`
+- :ref:`libmaple-exti`
+
+Recommended Reading
+-------------------
+
+* ST manual `RM0008
+ <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_
+ (PDF), Chapter 9, "General-purpose and alternate-function I/Os", and
+ Chapter 10, "Interrupts and Events".
+
+.. rubric:: Footnotes
+
+.. [#fextisports] The underlying reason for this restriction is that
+ the external interrupt lines on the STM32 are shared between
+ :ref:`GPIO ports <gpio-ports>`. There can be only one external
+ interrupt on each GPIO bit, out of all of the ports. That is, if
+ PA4 has an external interrupt on it, then PB4 can't have one, too.
+ Since the GPIO bit numbers only go from 0 to 15, there can only be
+ 16 external interrupts at a time.
diff --git a/docs/source/faq.rst b/docs/source/faq.rst
new file mode 100644
index 0000000..bd155ae
--- /dev/null
+++ b/docs/source/faq.rst
@@ -0,0 +1,115 @@
+.. highlight:: cpp
+
+.. _faq:
+
+==================================
+ Frequently Asked Questions (FAQ)
+==================================
+
+.. contents:: Contents
+ :local:
+
+.. _faq-atoi:
+
+Can I use ``atoi()``, ``strol()``, etc.?
+----------------------------------------
+
+Just ``#include <stdlib.h>``. See :ref:`arm-gcc-libc` for more
+information.
+
+.. _faq-dynamic-memory:
+
+Can I use ``malloc()``/``new``?
+-------------------------------
+
+For ``malloc()``, just ``#include <stdlib.h>``, and everything should
+work fine. Be careful, though! This isn't like C programming on a
+PC. You're on the bare metal, and probably shouldn't be using dynamic
+memory unless you know what you're doing.
+
+``new`` should work out of the box (the warning about knowing what
+you're doing applies here as well). If you find that ``new`` (or
+``new[]``, ``delete``, etc.) is broken in some way, that's a bug;
+please let us know in the `forum`_.
+
+Some information on the heap: on boards with an external SRAM chip
+(like Maple Native), the heap is located on external SRAM by default.
+For other boards, the heap is located immediately after ``.bss``, and
+grows towards the stack. (In all cases, statically allocated
+variables and the stack are located on internal SRAM, for performance
+reasons).
+
+.. _faq-flash-tables:
+
+How do I replace ``PROGMEM``/put data into Flash?
+-------------------------------------------------
+
+See :ref:`this note <arm-gcc-attribute-flash>`.
+
+How do I write to a pin at high speed?
+--------------------------------------
+
+Sometimes, :ref:`lang-digitalwrite` just isn't fast enough. If that's
+your situation, you should first try using fast GPIO writes using the
+low-level :ref:`libmaple-gpio` interface. This FAQ entry explains
+how.
+
+You'll need to look up the :ref:`GPIO port and bit <gpio-ports>` which
+correspond to the pin you want to write to. If you don't know what
+that means, don't worry. We'll go through an example here.
+
+Let's say you want to write to pin 4 on the Maple. In order to find
+out the port and bit number, take look at the Maple's :ref:`master pin
+map <maple-pin-map-master>` next to "D4". You'll see that in the
+"GPIO" column, there's "PB5". That's short for "**P**\ ort **B**, bit
+**5**". So the GPIO port is "B", and the bit is "5". (If you're not
+on the Maple, you can find your board's pin map :ref:`from here
+<gpio-pin-maps>`).
+
+That's all you need to know. Now you can use the function
+``gpio_write_bit()`` to quickly write to the pin. The way you call it
+is by writing ``gpio_write_bit(GPIO<port>, <bit>, HIGH/LOW)``, where
+``<port>`` is the GPIO port, ``<bit>`` is the bit, and ``HIGH`` or
+``LOW`` is the level you want to write to the pin. Here's an example
+program which writes pin 4 (GPIOB, bit 5) ``HIGH`` and then ``LOW``
+several times in a row each time it :ref:`lang-loop`\ s::
+
+ /*
+ Fast pin writing example, for Maple.
+
+ This example works for pin 4 (PB5 on Maple). If you want to
+ use another pin (or are on another board), just change PIN,
+ PIN_PORT, and PIN_BIT as described above.
+ */
+
+ #define PIN 4
+ #define PIN_PORT GPIOB
+ #define PIN_BIT 5
+
+ void setup() {
+ pinMode(PIN, OUTPUT);
+ }
+
+ void loop() {
+ gpio_write_bit(PIN_PORT, PIN_BIT, HIGH);
+ gpio_write_bit(PIN_PORT, PIN_BIT, LOW);
+ gpio_write_bit(PIN_PORT, PIN_BIT, HIGH);
+ gpio_write_bit(PIN_PORT, PIN_BIT, LOW);
+ }
+
+Now, if you've already tried this and you still can't get enough
+speed, there are some threads on the `forum`_ which might help you
+squeeze a little extra out of your board. First, a `general summary
+<http://forums.leaflabs.com/topic.php?id=860>`_ of other things to
+try, with measurements of the speed you'll get. Next, a thread
+featuring a `detailed discussion on pin capability
+<http://forums.leaflabs.com/topic.php?id=774>`_, with a focus on
+writes. And finally, `another thread
+<http://forums.leaflabs.com/topic.php?id=895>`_ on the subject which
+summarizes a variety of other threads on doing I/O quickly.
+
+Can I use Maple without Maple IDE?
+----------------------------------
+
+Yes. See :ref:`unix-toolchain` for the details.
+
diff --git a/docs/source/fsmc.rst b/docs/source/fsmc.rst
new file mode 100644
index 0000000..c8f0125
--- /dev/null
+++ b/docs/source/fsmc.rst
@@ -0,0 +1,33 @@
+.. _fsmc:
+
+FSMC
+====
+
+The Flexible Static Memory Controller (FSMC) is a peripheral which an
+be configured to control a variety of external memory chips.
+
+Normally, any variables in your program will be allocated space in RAM
+(notable exceptions are variables marked with ``const`` or
+:ref:`__FLASH__ <arm-gcc-attribute-flash>`). Without the FSMC, this
+space is limited to the amount that comes built-in to the chip's
+*internal* SRAM.
+
+The addition of the FSMC peripheral allows addtional memory to be
+used. For example, it is used on the Maple Native to interface with
+the board's built-in external SRAM chip. However, this extra memory
+comes at a cost: the FSMC uses a fairly large number of GPIOs.
+
+The FSMC peripheral is currently only available on the Maple Native.
+On that board, we have broken out a wide variety of the FSMC lines, so
+that experienced users can add additional external memory chips to
+suit their own applications' purposes.
+
+.. TODO Find some tutorials on SRAM or write one on FSMC, specifically
+.. ones that cover: address, data, chip-select etc. pins, memory bank
+.. organization
+
+Recommended Reading
+-------------------
+
+- Wikipedia article on `SRAM <http://en.wikipedia.org/wiki/Static_random-access_memory>`_
+- :ref:`ST RM0008 <maple-native-b-stdocs>` chapter on FSMC.
diff --git a/docs/source/gpio.rst b/docs/source/gpio.rst
new file mode 100644
index 0000000..caaae3d
--- /dev/null
+++ b/docs/source/gpio.rst
@@ -0,0 +1,106 @@
+.. _gpio:
+
+GPIO
+====
+
+Each LeafLabs board comes with ready-to-use General Purpose
+Input/Output (GPIO) pins, which are numbered starting from zero.
+These numbers are listed on your board's silkscreen, next to where the
+pin is broken out to a header. Many pins may additionally be used for
+special features or interfacing with other hardware.
+
+.. contents:: Contents
+ :local:
+
+.. _gpio-modes:
+
+GPIO Modes
+----------
+
+Each GPIO pin can be configured using :ref:`lang-pinmode` to behave in
+a number of ways: as a digital output pin, as an analog input pin,
+etc.
+
+A :ref:`WiringPinMode <lang-pinmode-wiringpinmode>` value specifies
+the complete set of possible configurations; not every pin can have
+all of these modes. For example, on the Maple, pin 15 may have mode
+``INPUT_ANALOG``, but not ``PWM``. See your board's :ref:`pin maps
+<gpio-pin-maps>` and its silkscreen for more information on what
+functionality is available on each pin.
+
+Function Reference
+------------------
+
+- :ref:`lang-pinmode`
+
+- :ref:`lang-digitalread`
+
+- :ref:`lang-digitalwrite`
+
+- :ref:`lang-analogread`
+
+- :ref:`lang-pwmwrite` (Maple's equivalent to ``analogWrite()``; see
+ :ref:`lang-analogwrite` for differences from the Arduino version).
+
+.. _gpio-ports:
+
+GPIO Ports
+----------
+
+Normally, you'll interact with pins using just their number (or a
+constant like :ref:`BOARD_LED_PIN <lang-board-values-led>` which
+stands for a number). However, behind the scenes, the STM32
+microcontroller on your board separates the pins into groups called
+*GPIO ports*. Each GPIO port is given a letter, so for example,
+there's GPIO port A, port B, and so on\ [#fnumports]_. The pins on a
+GPIO port are given *bit numbers*, which go from 0 to 15. In ST's
+documentation, a pin is given by the letter "P", followed by its port
+letter and bit number. For instance, "PA4" is GPIO port A, bit 4.
+
+.. _gpio-pin-maps:
+
+Pin Maps
+--------
+
+Part of :ref:`Maple IDE's <ide>` job is to convert normal pin numbers
+into the corresponding GPIO port and bit when you call functions like
+:ref:`lang-pinmode`. It does this using a *pin map*, which lists the
+GPIO port and bit for each pin number. The GPIO documentation for
+your board includes its pin map, which also lists the other
+peripherals by pin number:
+
+* :ref:`Maple <maple-gpios>`
+* :ref:`Maple RET6 Edition <maple-ret6-gpios>`
+* :ref:`Maple Mini <maple-mini-gpios>`
+* :ref:`Maple Native (Beta) <maple-native-b>`
+
+.. * :ref:`Maple Native <maple-native-gpios>`
+
+.. _gpio-5v-tolerant:
+
+The current and voltage limitations were determined using the STM32
+datasheets. In particular, only some GPIO pins are **5V tolerant**,
+which means that applying 5 volts to a pin and reading it as input or
+allowing it to drain to ground will not damage that pin. Connecting a
+voltage higher than 3.3V to a non-5V tolerant pin may damage your
+board.
+
+.. _gpio-recommended-reading:
+
+Recommended Reading
+-------------------
+
+* ST Documentation for the STM32F103 series of microcontrollers:
+
+ * `Reference Manual RM0008
+ <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_
+ (PDF); general, definitive resource for STM32F1 line.
+ * `Programming Manual PM0056
+ <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_
+ (PDF); assembly language and register reference.
+
+.. rubric:: Footnotes
+
+.. [#fnumports] The total number of GPIO ports depends on what board
+ you have. For example, Maple Mini has three: ports A, B, and C.
+ Maple Native has seven: ports A through G.
diff --git a/docs/source/hardware/maple-mini.rst b/docs/source/hardware/maple-mini.rst
new file mode 100644
index 0000000..c28211d
--- /dev/null
+++ b/docs/source/hardware/maple-mini.rst
@@ -0,0 +1,402 @@
+.. _maple-mini:
+
+Maple Mini
+==========
+
+This page is a general resource for information specific to the Maple
+Mini. The Maple Mini is a smaller version of the Maple that fits on a
+breadboard.
+
+.. contents:: Contents
+ :local:
+
+.. TODO [dma.rst] Ref to dma.rst in sequel instead of libmaple-dma
+
+Technical Specifications
+------------------------
+
+* MCU: :ref:`STM32F103CBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex
+ M3 microprocessor
+* Clock Speed: **72 MHz**
+* **128 KB Flash** and **20 KB SRAM**
+* 34 :ref:`digital I/ pins (GPIOs) <gpio>`
+* 12 :ref:`PWM <pwm>` pins at 16 bit resolution
+* 9 :ref:`analog input (ADC) <adc>` pins at 12 bit resolution
+* 2 :ref:`SPI <spi>` peripherals
+* 2 :ref:`I2C <i2c>` peripherals
+* 7 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`)
+* 3 :ref:`USART (serial port) <usart>` peripherals
+* 1 advanced and 3 general-purpose :ref:`timers <timers>`
+* Dedicated :ref:`USB <usb>` port for programming and communications
+* :ref:`jtag`
+* Nested Vectored Interrupt Controller (NVIC) (including
+ :ref:`external interrupt <external-interrupts>` on GPIOs)
+* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital
+ and analog regulators <maple-mini-adc-bank>` for low-noise analog
+ performance
+* :ref:`Open source, four layer design <maple-mini-hardware>`
+* Support for low power, sleep, and standby modes (<500 μA)
+* Operating Voltage: 3.3 V
+* Input Voltage (recommended): 3 V — 12 V
+* Dimensions: 2.02″ × 0.72″
+
+.. _maple-mini-powering:
+
+Powering the Maple Mini
+-----------------------
+
+You can power the Maple Mini via the USB plug or by powering Vin
+directly.
+
+.. warning:: The silkscreen on the Maple Mini suggests it will accept
+ an input voltage up to 16 V. We recommend applying **no greater
+ than 12 V**, and potentially even lower depending upon the current
+ draw requirements of the application. Please see :ref:`Power
+ Regulation on the Maple Mini <maple-mini-power-regulation>` for
+ more information.
+
+.. _maple-mini-power-regulation:
+
+Power Regulation on the Maple Mini
+----------------------------------
+
+Power regulation on the Maple is provided by two low dropout linear
+voltage regulators. (The part is the MCP1703 from Microchip, in the
+SOT-23A package. You can download the datasheet `here
+<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One
+of the regulators supplies power to the digital voltage plane; the
+other supplies power to the analog voltage plane.
+
+These voltage regulators nominally take an input of up to 16V. In
+addition, while the maximum continuous output current for the board is
+250mA, if you are powering the board off higher voltages the amount
+current it can supply goes down, due to the regulators needing to
+dissipate the extra power. So if you are powering the board off 12V,
+the max current is about 40mA at room temperature. In general (again,
+at room temperature) the max power dissipation (PD) for the chip is
+about .37W, and output current = PD/(Vin-Vout). For exact max current
+calculations, please refer to the datasheet linked above.
+
+If you are planning to draw a lot of current from the Maple board, it
+is necessary to provide input power as close to 3.3V as
+possible. Powering the microcontroller circuitry and LEDs on the board
+alone takes approximately 30mA, so if you are powering the board with
+12V that leaves only 10mA (at best) available for powering any user
+circuitry. Attempting to draw more than 10mA runs the risk of shorting
+out the power regulators and bricking your board.
+
+.. _maple-mini-gpios:
+
+GPIO Information
+----------------
+
+The Maple Mini features 34 total input/output pins, numbered ``D0``
+through ``D33``. These numbers correspond to the numeric values next
+to each header on the Maple Mini's silkscreen. However, some of them
+have special uses by default [#fusedpins]_.
+
+.. _maple-mini-usb-pins:
+
+Pin ``D23`` is the :ref:`USB <usb>` D+ line, and ``D24`` is the USB D-
+line. To use them as GPIOs, your program will need to :ref:`disable
+SerialUSB <lang-serialusb-end>` first. Be aware, however, that
+disabling SerialUSB means that the :ref:`bootloader <bootloader>`
+won't work properly, and you'll need to use
+:ref:`troubleshooting-perpetual-bootloader` to make your next upload.
+
+.. _maple-mini-but:
+
+Pin ``D32`` is the Mini's :ref:`button pin <lang-board-values-but>`.
+It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The
+pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button
+is pressed <lang-isbuttonpressed>`.
+
+.. _maple-mini-led:
+
+Pin ``D33`` is the Mini's :ref:`LED pin <lang-board-values-led>`. It
+is thus mainly useful as an :ref:`output <lang-pin-levels>`. The LED
+will glow when ``HIGH`` is :ref:`written <lang-digitalwrite>` to it.
+(It also supports :ref:`pwm`, for finer-grained brightness control).
+
+.. TODO [0.1.0] silkscreen pictures which expand abbreviations
+
+.. _maple-mini-pin-map-master:
+
+Master Pin Map
+^^^^^^^^^^^^^^
+
+This table shows a summary the available functionality on every GPIO
+pin, by peripheral type. The "5 V?" column documents whether or not
+the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`.
+
+Note that this table is not exhaustive; on some pins, more peripherals
+are available than are listed here.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V?
+
+ D0, PB11, -, -, 2_SDA, 3_RX, -, Yes
+ D1, PB10, -, -, 2_SCL, 3_TX, -, Yes
+ D2, PB2, -, -, -, -, -, Yes
+ D3, PB0, CH8, 3_CH3, -, -, -, -
+ D4, PA7, CH7, 3_CH2, -, -, 1_MOSI, -
+ D5, PA6, CH6, 3_CH1, -, -, 1_MISO, -
+ D6, PA5, CH5, -, -, -, 1_SCK, -
+ D7, PA4, CH4, -, -, 2_CK, 1_NSS, -
+ D8, PA3, CH3, 2_CH4, -, 2_RX, -, -
+ D9, PA2, CH2, 2_CH3, -, 2_TX, -, -
+ D10, PA1, CH1, 2_CH2, -, 2_RTS, -, -
+ D11, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, -
+ D12, PC15, -, -, -, -, -, -
+ D13, PC14, -, -, -, -, -, -
+ D14, PC13, -, -, -, -, -, -
+ D15, PB7, -, 4_CH2, 1_SDA, -, -, Yes
+ D16, PB6, -, 4_CH1, 2_SCL, -, -, Yes
+ D17, PB5, -, -, 1_SMBA, -, -, -
+ D18, PB4, -, -, -, -, -, Yes
+ D19, PB3, -, -, -, -, -, Yes
+ D20, PA15, -, -, -, -, -, Yes
+ D21, PA14, -, -, -, -, -, Yes
+ D22, PA13, -, -, -, -, -, Yes
+ D23, PA12, -, 1_ETR, -, 1_RTS, -, Yes
+ D24, PA11, -, 1_CH4, -, 1_CTS, -, Yes
+ D25, PA10, -, 1_CH3, -, 1_RX, -, Yes
+ D26, PA9, -, 1_CH2, -, 1_TX, -, Yes
+ D27, PA8, -, 1_CH1, -, 1_CK, -, Yes
+ D28, PB15, -, -, -, -, 2_MOSI, Yes
+ D29, PB14, -, -, -, 3_RTS, 2_MISO, Yes
+ D30, PB13, -, -, -, 3_CTS, 2_SCK, Yes
+ D31, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes
+ D32, PB8, -, 4_CH3, -, -, -, Yes
+ D33, PB1, CH9, 3_CH4, -, -, -, -
+
+.. _maple-mini-gpio-port-map:
+
+GPIO Port Pin Map
+^^^^^^^^^^^^^^^^^
+The following table shows what pins are associated with each
+:ref:`GPIO port <gpio-ports>`.
+
+.. csv-table::
+ :header: GPIOA, GPIOB, GPIOC
+
+ PA0: D11, PB0: D3, PC0: -
+ PA1: D10, PB1: D33, PC1: -
+ PA2: D9, PB2: D2, PC2: -
+ PA3: D8, PB3: D19, PC3: -
+ PA4: D7, PB4: D18, PC4: -
+ PA5: D6, PB5: D17, PC5: -
+ PA6: D5, PB6: D16, PC6: -
+ PA7: D4, PB7: D15, PC7: -
+ PA8: D27, PB8: D32, PC8: -
+ PA9: D26, PB9: -, PC9: -
+ PA10: D25, PB10: D1, PC10: -
+ PA11: D24, PB11: D0, PC11: -
+ PA12: D23, PB12: D31, PC12: -
+ PA13: D22, PB13: D30, PC13: D14
+ PA14: D21, PB14: D29, PC14: D13
+ PA15: D20, PB15: D28, PC15: D12
+
+.. _maple-mini-timer-map:
+
+Timer Pin Map
+^^^^^^^^^^^^^
+
+The following table shows what pins are associated with a particular
+timer's capture/compare channels.
+
+.. csv-table::
+ :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4
+ :delim: |
+
+ 1 | D27 | D26 | D25 | D24
+ 2 | D11 | D10 | D9 | D8
+ 3 | D5 | D4 | D3 | :ref:`D33 <maple-mini-led>`
+ 4 | D16 | D15 | :ref:`D32 <maple-mini-but>` |
+
+.. _maple-mini-exti-map:
+
+EXTI Line Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows which pins connect to which :ref:`EXTI lines
+<external-interrupts-exti-line>`.
+
+.. list-table::
+ :widths: 1 1
+ :header-rows: 1
+
+ * - EXTI Line
+ - Pins
+ * - EXTI0
+ - D3, D11
+ * - EXTI1
+ - D10, D33
+ * - EXTI2
+ - D2, D9
+ * - EXTI3
+ - D8, D19
+ * - EXTI4
+ - D7, D18
+ * - EXTI5
+ - D6, D17
+ * - EXTI6
+ - D5, D16
+ * - EXTI7
+ - D4, D15
+ * - EXTI8
+ - D27, D32
+ * - EXTI9
+ - D26
+ * - EXTI10
+ - D1, D25
+ * - EXTI11
+ - D0, D24
+ * - EXTI12
+ - D23, D31
+ * - EXTI13
+ - D14, D22, D30
+ * - EXTI14
+ - D13, D21, D29
+ * - EXTI15
+ - D12, D20, D28
+
+.. _maple-mini-usart-map:
+
+USART Pin Map
+^^^^^^^^^^^^^
+
+The Maple Mini has three serial ports (also known as :ref:`USARTs
+<usart>`). They communicate using the pins given in the following
+table.
+
+.. csv-table::
+ :header: Serial Port, TX, RX, CK, CTS, RTS
+ :delim: |
+
+ ``Serial1`` | D26 | D25 | D27 | D24 | D23
+ ``Serial2`` | D9 | D8 | D7 | D11 | D10
+ ``Serial3`` | D1 | D0 | D31 | D30 | D29
+
+.. _maple-mini-adc-bank:
+
+Low-Noise ADC Pins
+^^^^^^^^^^^^^^^^^^
+
+Maple Mini has an electrically isolated analog power plane with its
+own regulator, and a geometrically isolated ground plane, connected to
+the digital plane by an inductor. Its analog input pins, D3 — D11,
+are laid out to correspond with these analog planes, and our
+measurements indicate that they generally offer low noise ADC
+performance. However, analog performance may vary depending upon the
+activity of the other GPIOs. Consult the :ref:`Maple Mini hardware
+design files <maple-mini-hardware>` for more details.
+
+.. _maple-mini-board-values:
+
+Board-Specific Values
+---------------------
+
+This section lists the Maple Mini's :ref:`board-specific values
+<lang-board-values>`.
+
+- ``CYCLES_PER_MICROSECOND``: 72
+- ``BOARD_BUTTON_PIN``: 32
+- ``BOARD_LED_PIN``: 33
+- ``BOARD_NR_GPIO_PINS``: 34
+- ``BOARD_NR_PWM_PINS``: 12
+- ``boardPWMPins``: 3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27
+- ``BOARD_NR_ADC_PINS``: 9
+- ``boardADCPins``: 3, 4, 5, 6, 7, 8, 9, 10, 11
+- ``BOARD_NR_USED_PINS``: 4
+- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``, 23, 24
+ (23 and 24 are used by :ref:`USB <maple-mini-usb-pins>`)
+- ``BOARD_NR_USARTS``: 3
+- ``BOARD_USART1_TX_PIN``: 26
+- ``BOARD_USART1_RX_PIN``: 25
+- ``BOARD_USART2_TX_PIN``: 9
+- ``BOARD_USART2_RX_PIN``: 8
+- ``BOARD_USART3_TX_PIN``: 1
+- ``BOARD_USART3_RX_PIN``: 0
+- ``BOARD_NR_SPI``: 2
+- ``BOARD_SPI1_NSS_PIN``: 7
+- ``BOARD_SPI1_MOSI_PIN``: 4
+- ``BOARD_SPI1_MISO_PIN``: 5
+- ``BOARD_SPI1_SCK_PIN``: 6
+- ``BOARD_SPI2_NSS_PIN``: 31
+- ``BOARD_SPI2_MOSI_PIN``: 28
+- ``BOARD_SPI2_MISO_PIN``: 29
+- ``BOARD_SPI2_SCK_PIN``: 30
+- ``BOARD_JTMS_SWDIO_PIN``: 22
+- ``BOARD_JTCK_SWCLK_PIN``: 21
+- ``BOARD_JTDI_PIN``: 20
+- ``BOARD_JTDO_PIN``: 19
+- ``BOARD_NJTRST_PIN``: 18
+
+.. _maple-mini-hardware:
+
+Hardware Design Files
+---------------------
+
+The hardware schematics and board layout files are available in the
+`Maple Mini GitHub repository <https://github.com/leaflabs/maplemini>`_.
+
+From the GitHub repository main page, you can download the entire
+repository by clicking the "Download" button. If you are familiar
+with `Git <http://git-scm.com/>`_, you can also clone the repository
+at the command line with ::
+
+ $ git clone git://github.com/leaflabs/maplemini.git
+
+Failure Modes
+-------------
+
+The following known failure modes apply to all Maple boards. The
+failure modes aren't design errors, but are easy ways to break or
+damage your board permanently.
+
+* **High voltage on non-tolerant pins**: not all header pins are 5 V
+ compatible; so e.g. connecting certain serial devices in the wrong
+ way could over-voltage the pins. The :ref:`pin-mapping master table
+ <maple-mini-pin-map-master>` details which pins are :ref:`5
+ V-tolerant <gpio-5v-tolerant>`.
+
+Errata
+------
+
+This section lists known issues and warnings for the Maple Mini Rev 2
+(the first Rev sold to the public).
+
+.. _maple-mini-vin:
+
+* **Silkscreen Vin voltage mistake**: The silkscreen on the Maple Mini
+ falsely indicates that Vin may be supplied with up to 16V. We
+ recommend an input voltage **no greater than 12V**, and potentially
+ even lower depending upon the current draw requirements of the
+ application. Please see :ref:`Power Regulation on the Maple Mini
+ <maple-mini-power-regulation>` for more information.
+
+
+Recommended Reading
+-------------------
+
+.. _maple-mini-stdocs:
+
+STMicro documentation for STM32F103CB microcontroller:
+
+* `Datasheet
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00161566.pdf>`_
+ (PDF); covers STM32F103x8, STM32F103xB.
+* `Reference Manual RM0008
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_
+ (PDF); definitive resource for peripherals on the STM32F1 line.
+* `Programming Manual PM0056
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_
+ (PDF); assembly language and register reference.
+* `STM32F103CB <http://www.st.com/internet/mcu/product/189782.jsp>`_
+ overview page with links to further references.
+
+.. rubric:: Footnotes
+
+.. [#fusedpins] See :ref:`boardUsedPins <lang-board-values-used-pins>`
+ for more information.
diff --git a/docs/source/hardware/maple-native-beta.rst b/docs/source/hardware/maple-native-beta.rst
new file mode 100644
index 0000000..bdfd216
--- /dev/null
+++ b/docs/source/hardware/maple-native-beta.rst
@@ -0,0 +1,605 @@
+.. highlight:: sh
+
+.. _maple-native-b:
+
+Maple Native β
+==============
+
+This page is a general resource for information specific to the Maple
+Native Beta. Since this is a beta release, the information here may
+change slightly between now and the final Maple Native release.
+
+.. contents:: Contents
+ :local:
+
+Technical Specifications
+------------------------
+
+* MCU: `STM32F103ZET6 <maple-native-b-stdocs>`, a 32-bit ARM Cortex M3
+ microprocessor.
+* Clock Speed: **72 MHz**
+* **512 KB Flash**, **64 KB SRAM** (on-chip), **1 MB SRAM** (external)
+* 106 :ref:`digital I/O pins <gpio>`
+* 17 :ref:`PWM <pwm>` pins at 16 bit resolution
+* 21 :ref:`analog input (ADC) <adc>` pins at 12-bit resolution
+* 3 :ref:`SPI <spi>` peripherals
+* 2 :ref:`I2C <i2c>` peripherals
+* 12 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`)
+ with 2 DMA controllers
+* 3 :ref:`USART (serial port) <usart>` peripherals, 2 **UART** peripherals
+* 2 advanced, 4 general-purpose, and 2 basic :ref:`timers <timers>`
+* Dedicated :ref:`USB <usb>` port for programming and communications
+* :ref:`JTAG <jtag>`
+* Nested Vectored Interrupt Controller (NVIC) (including
+ :ref:`external interrupt <lang-attachinterrupt>` on GPIOs)
+* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital
+ and analog regulators <maple-native-b-adc-bank>` for low-noise analog
+ performance
+* :ref:`Open-source, four layer design <maple-native-b-hardware>`
+* Support for low power, sleep, and standby modes (<500 μA)
+* Operating Voltage: 3.3 V
+* Input Voltage (recommended): 3 V — 12 V
+* Dimensions: 4″ × 2.1″
+
+.. _maple-native-b-powering:
+
+Powering the Maple Native
+-------------------------
+
+The power source is determined by the header labeled "PWRSEL" on the
+silkscreen. The Maple Native may be powered from USB (marked "USB" on
+the PWRSEL header), a LiPo battery (marked "BAT"), or one of the two
+"Vin" pins (marked "EXT"). Boards are shipped with a jumper on the
+USB selector. In order to power it off of an alternative source,
+unplug the Maple Native, then move the jumper to the desired selector
+before reconnecting power.
+
+The "Vin" line is available on the pin labeled "Vin" on the vertical
+header to the right of the PWRSEL header, as well as on the
+unpopulated two-pin connector on the upper left corner of the
+board. On this latter connector, polarity was accidentally left
+unmarked: the leftmost, round pin should be power, while the square
+pin should be ground.
+
+When powering the Maple Native board from a battery or the Vin lines,
+care must be taken not to over-voltage the board. In general, an upper
+limit of 12V input is acceptable, but this may vary depending upon the
+current draw requirements of the application. Please see :ref:`Power
+Regulation on the Maple Native <maple-native-b-power-regulation>` for
+more information.
+
+.. _maple-native-b-power-regulation:
+
+Power Regulation on the Maple Native
+------------------------------------
+
+Power regulation on the Maple Native is provided by two low dropout
+linear voltage regulators. (The part is the MCP1703 from Microchip, in
+the SOT-23A package. You can download the datasheet `here
+<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_). One
+of the regulators supplies power to the digital voltage plane; the
+other supplies power to the analog voltage plane.
+
+These voltage regulators nominally take an input of up to 16V. In
+addition, while the maximum continuous output current for the board is
+250mA, if you are powering the board off higher voltages the current
+it can supply goes down, due to the regulators needing to dissipate
+the extra power. So if you are powering the board off 12V, the max
+current is about 40mA at room temperature. In general (again, at room
+temperature) the max power dissipation (PD) for the chip is about
+.37W, and output current = PD/(Vin-Vout). For exact max current
+calculations, please refer to the datasheet linked above.
+
+If you are planning to draw a lot of current from the Maple Native
+board, it is necessary to provide input power as close to 3.3V as
+possible. Powering the microcontroller circuitry and LEDs on the board
+alone takes approximately 30mA, so if you are powering the board with
+12V that leaves only 10mA (at best) available for powering any user
+circuitry. Attempting to draw more than 10mA runs the risk of shorting
+out the power regulators and bricking your board.
+
+Using the Built-in Battery Charger
+----------------------------------
+
+Maple Native includes a built-in LiPo battery charger. In order to
+use it, put a jumper across the CHRG selector on the PWRSEL header and
+across the USB, or EXT selectors, depending on whether you're charging
+the battery via USB cable or Vin, respectively. The LED labeled CHRG
+will light up while the battery is being charged. When the battery is
+finished charging, the LED labeled DONE will light up.
+
+.. _maple-native-b-gpios:
+
+GPIO Information
+----------------
+
+The Maple Native features 106 total input/output pins, numbered ``D0``
+through ``D105``. In most cases, these numbers correspond to the
+numeric values next to each header on the Maple Native's silkscreen.
+However, pins ``D101`` through ``D105`` are broken out to the
+:ref:`JTAG <jtag>` header, and are not numbered on the silkscreen. In
+addition, some other pins have other uses by default [#fusedpins]_.
+
+.. _maple-native-b-but:
+
+Pin ``D6`` is the Native's :ref:`button pin <lang-board-values-but>`.
+It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The
+pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button
+is pressed <lang-isbuttonpressed>`.
+
+.. _maple-native-b-led:
+
+Pin ``D22`` is the Native's :ref:`LED pin <lang-board-values-led>`.
+It is thus mainly useful as an :ref:`output <lang-pin-levels>`. The
+LED will glow when ``HIGH`` is :ref:`written <lang-digitalwrite>` to
+it.
+
+.. _maple-native-b-fsmc:
+
+Many of the pins on the right header (pins ``D56`` through ``D100``,
+the header is labeled :ref:`"FSMC" <fsmc>` on the silkscreen) are
+connected to the SRAM chip. Using these pins as GPIOs may render the
+memory chip useless, which can cause your program to crash. For this
+reason, we don't recommend that you use these pins unless you know
+what you are doing. The following pins on the right header are not
+connected to the SRAM and may be used with impunity: ``D57``, ``D60``,
+``D63``, ``D66``, ``D69``, ``D72``, ``D75``, ``D80``, ``D83``.
+
+.. _maple-native-b-jtag:
+
+Pins ``D101`` through ``D105`` are connected to the pads on the
+:ref:`JTAG <jtag>` header. In order to use them as GPIOs, you must
+first disable the Maple Native's debug ports. You can do this by
+calling :ref:`lang-disabledebugports`. (Note that this means you
+won't be able to use JTAG or SW-Debug to debug your program).
+
+.. TODO [0.1.0] silkscreen pictures
+
+.. _maple-native-b-pin-map-master:
+
+Master Pin Map
+^^^^^^^^^^^^^^
+
+This table shows a summary the available functionality on every GPIO
+pin, by peripheral type. The "5 V?" column documents whether or not
+the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`.
+
+Note that this table is not exhaustive; on some pins, more peripherals
+are available than are listed here.
+
+**Top header:**
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V?
+
+ D0, PB10, -, -, 2_SCL, 3_TX, -, Yes
+ D1, PB11, -, -, 2_SDA, 3_RX, -, Yes
+ D2, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes
+ D3, PB13, -, -, -, 3_CTS, 2_SCK, Yes
+ D4, PB14, -, -, -, 3_RTS, 2_MISO, Yes
+ D5, PB15, -, -, -, -, 2_MOSI, Yes
+ D6, PG15, -, -, -, -, -, Yes
+ D7, PC0, 1_CH10, -, -, -, -, -
+ D8, PC1, 1_CH11, -, -, -, -, -
+ D9, PC2, 1_CH12, -, -, -, -, -
+ D10, PC3, 1_CH13, -, -, -, -, -
+ D11, PC4, 1_CH14, -, -, -, -, -
+ D12, PC5, 1_CH15, -, -, -, -, -
+ D13, PC6, -, 8_CH1, -, -, -, Yes
+ D14, PC7, -, 8_CH2, -, -, -, Yes
+ D15, PC8, -, 8_CH3, -, -, -, Yes
+ D16, PC9, -, 8_CH4, -, -, -, Yes
+ D17, PC10, -, -, -, 4_TX, -, Yes
+ D18, PC11, -, -, -, 4_RX, -, Yes
+ D19, PC12, -, -, -, 5_TX, -, Yes
+ D20, PC13, -, -, -, -, -, -
+ D21, PC14, -, -, -, -, -, -
+ D22, PC15, -, -, -, -, -, -
+ D23, PA8, -, 1_CH1, -, 1_CK, -, Yes
+ D24, PA9, -, 1_CH2, -, 1_TX, -, Yes
+ D25, PA10, -, 1_CH3, -, 1_RX, -, Yes
+ D26, PB9, -, 4_CH4, -, -, -, Yes
+
+**Bottom header:**
+
+.. note:: ``D48``, ``D49``, ``D50``, ``D51`` are also connected to
+ Timer 2 channels 1, 2, 3, and 4, respectively.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V?
+
+ D27, PD2, -, 3_ETR, -, 5_RX, -, Yes
+ D28, PD3, -, -, -, -, -, Yes
+ D29, PD6, -, -, -, -, -, Yes
+ D30, PG11, -, -, -, -, -, Yes
+ D31, PG12, -, -, -, -, -, Yes
+ D32, PG13, -, -, -, -, -, Yes
+ D33, PG14, -, -, -, -, -, Yes
+ D34, PG8, -, -, -, -, -, Yes
+ D35, PG7, -, -, -, -, -, Yes
+ D36, PG6, -, -, -, -, -, Yes
+ D37, PB5, -, -, 1_SMBA, -, 3_MOSI, -
+ D38, PB6, -, 4_CH1, 1_SCL, -, -, Yes
+ D39, PB7, -, 4_CH2, 1_SDA, -, -, Yes
+ D40, PF11, -, -, -, -, -, Yes
+ D41, PF6, 3_CH4, -, -, -, -, -
+ D42, PF7, 3_CH5, -, -, -, -, -
+ D43, PF8, 3_CH6, -, -, -, -, -
+ D44, PF9, 3_CH7, -, -, -, -, -
+ D45, PF10, 3_CH8, -, -, -, -, -
+ D46, PB1, 1_CH9, 3_CH4, -, -, -, -
+ D47, PB0, 1_CH8, 3_CH3, -, -, -, -
+ D48, PA0, 1_CH0, 5_CH1, -, 2_CTS, -, -
+ D49, PA1, 1_CH1, 5_CH2, -, 2_RTS, -, -
+ D50, PA2, 1_CH2, 5_CH3, -, 2_TX, -, -
+ D51, PA3, 1_CH3, 5_CH4, -, 2_RX, -, -
+ D52, PA4, 1_CH4, -, -, 2_CK, 1_NSS, -
+ D53, PA5, 1_CH5, -, -, -, 1_SCK, -
+ D54, PA6, 1_CH6, 3_CH1, -, -, 1_MISO, -
+ D55, PA7, 1_CH7, 3_CH2, -, -, 1_MOSI, -
+
+.. _maple-native-b-fsmc-map:
+
+**Right (FSMC) header**
+
+All of the following pins are 5V-tolerant. Note that in the "FSMC"
+column below, entries with a "Dn" value (D0, D1, etc.) don't refer to
+pins; they refer to FSMC data lines. See :ref:`RM0008
+<maple-native-b-stdocs>` for more information.
+
+.. warning:: Many of the pins on this header are used by the Maple
+ Native's SRAM chip. Don't use them as GPIOs unless you know what
+ you're doing, or your program may crash. :ref:`See above
+ <maple-native-b-fsmc>` for more information.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`FSMC <fsmc>`
+
+ D56, PF0, A0
+ D57, PD11, A16
+ D58, P14, D0
+ D59, PF1, A1
+ D60, PD12, A17
+ D61, PD15, D1
+ D62, PF2, A2
+ D63, PD13, A18
+ D64, PD0, D2
+ D65, PF3, A3
+ D66, PE3, A19
+ D67, PD1, D3
+ D68, PF4, A4
+ D69, PE4, A20
+ D70, PE7, D4
+ D71, PF5, A5
+ D72, PE5, A21
+ D73, PE8, D8
+ D74, PF12, A6
+ D75, PE6, A22
+ D76, PE9, D6
+ D77, PF13, A7
+ D78, PE10, D7
+ D79, PF14, A8
+ D80, PG9, NE2/NCE3
+ D81, PE11, D8
+ D82, PF15, A9
+ D83, PG10, NCE4_1/NE3/NCE4_2
+ D84, PE12, D9
+ D85, PG0, A10
+ D86, PD5, NWE
+ D87, PE13, D10
+ D88, PG1, A11
+ D89, PD4, NOE
+ D90, PE14, D11
+ D91, PG2, A12
+ D92, PE1, NBL1
+ D93, PE15, D12
+ D94, PG3, A13
+ D95, PE0, NBL0
+ D96, PD8, D13
+ D97, PG4, A14
+ D98, PD9, D14
+ D99, PG5, A15
+ D100, PD10, D15
+
+**JTAG header pins**
+
+.. note:: See :ref:`above <maple-native-b-jtag>` for more information on
+ these pins.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`SPI <spi>`, 5 V?
+
+ D101, PA13, -, Yes
+ D102, PA14, -, Yes
+ D103, PA15, 3_NSS, Yes
+ D104, PB3, 3_SCK, Yes
+ D105, PB4, 3_MISO, Yes
+
+.. _maple-native-b-gpio-port-map:
+
+GPIO Port Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following tables show what pins are associated with each
+:ref:`GPIO port <gpio-ports>`.
+
+.. csv-table::
+ :header: GPIOA, GPIOB, GPIOC, GPIOD
+
+ PA0: D48, PB0: D47, PC0: D7, PD0: D64
+ PA1: D49, PB1: D46, PC1: D8, PD1: D67
+ PA2: D50, PB2: -, PC2: D9, PD2: D27
+ PA3: D51, PB3: D104, PC3: D10, PD3: D28
+ PA4: D52, PB4: D105, PC4: D11, PD4: D89
+ PA5: D53, PB5: D37, PC5: D12, PD5: D86
+ PA6: D54, PB6: D38, PC6: D13, PD6: D29
+ PA7: D55, PB7: D39, PC7: D14, PD7: -
+ PA8: D23, PB8: -, PC8: D15, PD8: D96
+ PA9: D24, PB9: D26, PC9: D16, PD9: D98
+ PA10: D25, PB10: D0, PC10: D17, PD10: D100
+ PA11: -, PB11: D1, PC11: D18, PD11: D57
+ PA12: -, PB12: D2, PC12: D19, PD12: D60
+ PA13: D101, PB13: D3, PC13: D20, PD13: D63
+ PA14: D102, PB14: D4, PC14: D21, PD14: D58
+
+.. csv-table::
+ :header: GPIOE, GPIOF, GPIOG
+
+ PE0: D95, PF0: D56, PG0: D85
+ PE1: D92, PF1: D59, PG1: D88
+ PE2: - PF2: D62, PG2: D91,
+ PE3: D66, PF3: D65, PG3: D94
+ PE4: D69, PF4: D68, PG4: D97
+ PE5: D72, PF5: D71, PG5: D99
+ PE6: D75, PF6: D41, PG6: D36
+ PE7: D70, PF7: D42, PG7: D35
+ PE8: D73, PF8: D43, PG8: D34
+ PE9: D76, PF9: D44, PG9: D80
+ PE10: D78, PF10: D45, PG10: D83
+ PE11: D81, PF11: D40, PG11: D30
+ PE12: D84, PF12: D74, PG12: D31
+ PE13: D87, PF13: D77, PG13: D32
+ PE14: D90, PF14: D79, PG14: D33
+
+.. _maple-native-b-timer-map:
+
+Timer Pin Map
+^^^^^^^^^^^^^
+
+The following table shows what pins are associated with a particular
+timer's capture/compare channels.
+
+There is no mistake between timers 2 and 5. They really do share
+those pins. If you like, you can remap some of the timer 2 channels
+to get extra PWM pins; see :ref:`afio_remap() (in gpio.h)
+<gpio-h-afio-remap>`.
+
+.. csv-table::
+ :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4
+ :delim: |
+
+ 1 | D23 | D24 | D25 |
+ 2 | D48 | D49 | D50 | D51
+ 3 | D54 | D55 | D47 | D46
+ 4 | D38 | D39 | | D26
+ 5 | D48 | D49 | D50 | D51
+ 8 | D13 | D14 | D15 | D16
+
+.. _maple-native-b-exti-map:
+
+EXTI Line Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows which pins connect to which :ref:`EXTI lines
+<external-interrupts-exti-line>`.
+
+.. list-table::
+ :widths: 1 3
+ :header-rows: 1
+
+ * - EXTI Line
+ - Pins
+ * - EXTI0
+ - D7, D47, D48, D56, D64, D85, D95
+ * - EXTI1
+ - D8, D46, D49, D59, D67, D88, D92
+ * - EXTI2
+ - D9, D27, D50, D62, D91
+ * - EXTI3
+ - D10, D28, D51, D65, D66, D94, D104
+ * - EXTI4
+ - D11, D52, D68, D69, D89, D97, D105
+ * - EXTI5
+ - D12, D37, D53, D71, D72, D86, D99
+ * - EXTI6
+ - D13, D29, D36, D38, D41, D54, D75
+ * - EXTI7
+ - D14, D35, D39, D42, D55, D70
+ * - EXTI8
+ - D15, D23, D34, D43, D73, D96
+ * - EXTI9
+ - D16, D24, D26, D44, D76, D80, D98
+ * - EXTI10
+ - D0, D17, D25, D45, D78, D83, D100
+ * - EXTI11
+ - D1, D18, D30, D40, D57, D81
+ * - EXTI12
+ - D2, D19, D31, D60, D74, D84
+ * - EXTI13
+ - D3, D20, D32, D63, D77, D87, D101
+ * - EXTI14
+ - D4, D21, D33, D58, D79, D90, D102
+ * - EXTI15
+ - D5, D6, D22, D61, D82, D93, D103
+
+.. _maple-native-b-usart-map:
+
+USART Pin Map
+^^^^^^^^^^^^^
+
+The Maple Native has 3 :ref:`USART <usart>` serial ports. They
+communicate using the pins given in the following table.
+
+.. csv-table::
+ :header: Serial port, TX, RX, CK, CTS, RTS
+ :delim: |
+
+ ``Serial1`` | D24 | D25 | D23 | |
+ ``Serial2`` | D50 | D51 | D52 | D48 | D49
+ ``Serial3`` | D0 | D1 | D2 | D3 | D4
+
+The Maple Native also has 2 UART serial ports. Unlike USARTS, these
+only communicate asynchronously, and thus only have TX and RX pins.
+These are given in the following table.
+
+.. csv-table::
+ :header: Serial port, TX, RX
+ :delim: |
+
+ ``Serial4`` | D17 | D18
+ ``Serial5`` | D19 | D27
+
+.. _maple-native-b-adc-bank:
+
+Low-Noise ADC Pins
+^^^^^^^^^^^^^^^^^^
+
+There are fifteen pins at the bottom right of the board (``D41`` —
+``D55``) that generally offer lower-noise ADC performance than other
+pins on the board. If you're concerned about getting good ADC
+readings, we recommend using one of these pins to take your
+measurements.
+
+Maple Native has an electrically isolated analog power plane with its
+own regulator, and a geometrically isolated ground plane. Analog input
+pins D41 — D55 are laid out to correspond with these analog planes,
+and our measurements indicate that they generally ofer low noise ADC
+performance. However, analog performance may vary depending upon the
+activity of other GPIOs. In particular, using PWM on any of pins
+``D46`` — ``D51``, ``D54``, and ``D55`` may cause digital noise.
+Consult the :ref:`Maple Native beta hardware design files
+<maple-native-b-hardware>` for more details.
+
+.. _maple-native-b-board-values:
+
+Board-Specific Values
+---------------------
+
+This section lists the Maple Native's :ref:`board-specific values
+<lang-board-values>`.
+
+- ``CYCLES_PER_MICROSECOND``: 72
+- ``BOARD_BUTTON_PIN``: 6
+- ``BOARD_LED_PIN``: 22
+- ``BOARD_NR_GPIO_PINS``: 106
+- ``BOARD_NR_PWM_PINS``: 18
+- ``boardPWMPins``: 13, 14, 15, 16, 23, 24, 25, 26, 38, 39, 46, 47,
+ 48, 49, 50, 51, 54, 55
+- ``BOARD_NR_ADC_PINS``: 21
+- ``boardADCPins``: 7, 8, 9, 10, 11, 12, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55
+- ``BOARD_NR_USED_PINS``: 43
+- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``,
+ ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``,
+ ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN``, and
+ all pins on FSMC header except those mentioned :ref:`above
+ <maple-native-b-fsmc>`.
+- ``BOARD_NR_USARTS``: 5
+- ``BOARD_USART1_TX_PIN``: 24
+- ``BOARD_USART1_RX_PIN``: 25
+- ``BOARD_USART2_TX_PIN``: 50
+- ``BOARD_USART2_RX_PIN``: 51
+- ``BOARD_USART3_TX_PIN``: 0
+- ``BOARD_USART3_RX_PIN``: 1
+- ``BOARD_UART4_TX_PIN``: 17
+- ``BOARD_UART4_RX_PIN``: 18
+- ``BOARD_UART5_TX_PIN``: 19
+- ``BOARD_UART5_RX_PIN``: 27
+- ``BOARD_NR_SPI``: 3
+- ``BOARD_SPI1_NSS_PIN``: 52
+- ``BOARD_SPI1_MOSI_PIN``: 55
+- ``BOARD_SPI1_MISO_PIN``: 54
+- ``BOARD_SPI1_SCK_PIN``: 53
+- ``BOARD_SPI2_NSS_PIN``: 2
+- ``BOARD_SPI2_MOSI_PIN``: 5
+- ``BOARD_SPI2_MISO_PIN``: 4
+- ``BOARD_SPI2_SCK_PIN``: 3
+- ``BOARD_SPI3_NSS_PIN``: 103 (on :ref:`JTAG header <maple-native-b-jtag>`)
+- ``BOARD_SPI3_MOSI_PIN``: 37
+- ``BOARD_SPI3_MISO_PIN``: 105 (JTAG header)
+- ``BOARD_SPI3_SCK_PIN``: 104 (JTAG header)
+- ``BOARD_JTMS_SWDIO_PIN``: :ref:`103 <maple-native-b-jtag>`
+- ``BOARD_JTCK_SWCLK_PIN``: 102
+- ``BOARD_JTDI_PIN``: 103
+- ``BOARD_JTDO_PIN``: 104
+- ``BOARD_NJTRST_PIN``: 105
+
+.. _maple-native-b-hardware:
+
+Hardware Design Files
+^^^^^^^^^^^^^^^^^^^^^
+
+The hardware schematics and board layout files are available in the
+`Maple Native GitHub repository
+<https://github.com/leaflabs/maplenative/>`_. Download the `beta
+version's hardware design files
+<https://github.com/leaflabs/maplenative/tree/beta>`_ (ZIP format).
+
+If you're familiar with Git, you can clone the entire repository and
+checkout the commit tagged "beta" using the following::
+
+ $ git clone git://github.com/leaflabs/maplenative.git
+ $ git checkout beta
+
+Failure Modes
+-------------
+
+The following known failure modes apply to the Maple Native Beta. The
+failure modes aren't design errors, but are easy ways to break or
+damage your board permanently.
+
+* **Reversing Vin and GND**: when powering the Maple Native Beta via
+ the Vin and ground (GND) pins at the top left of the board, it is
+ possible to carelessly cause a short or switch the connections,
+ applying the high voltage to GND and ground to Vin.
+
+ If this happens, you will reverse bias the diode beneath these pins,
+ most likely damaging it. This may cause excess voltage to
+ subsequently be delivered to the board once the reversed pins are
+ connected properly.
+
+Errata
+------
+
+This section lists known issues and warnings for the Maple Native
+Beta.
+
+* **PWM on pin 39**: PWM on pin 39 appears to be nonfunctional. We
+ are looking into this issue.
+
+* **VREF is nonfunctional**: Due to a routing error, VREF is
+ permanently tied to 3.3V at VAA.
+
+Recommended Reading
+-------------------
+
+.. _maple-native-b-stdocs:
+
+STMicro documentation for STM32F103ZE microcontroller:
+
+* `Datasheet
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf>`_
+ (PDF); covers STM32F103xC, STM3F103xD, STM32F103xE.
+* `Reference Manual RM0008
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_
+ (PDF); definitive resource for peripherals on the STM32F1 line.
+* `Programming Manual PM0056
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_
+ (PDF); assembly language and register reference.
+* `STM32F103RE <http://www.st.com/internet/mcu/product/164485.jsp>`_
+ overview page with links to further references.
+
+.. rubric:: Footnotes
+
+.. [#fusedpins] See :ref:`boardUsedPins <lang-board-values-used-pins>`
+ for more information.
diff --git a/docs/source/hardware/maple-native.rst b/docs/source/hardware/maple-native.rst
new file mode 100644
index 0000000..79115fc
--- /dev/null
+++ b/docs/source/hardware/maple-native.rst
@@ -0,0 +1,6 @@
+.. _hardware-maple-native:
+
+Maple Native
+============
+
+Stub.
diff --git a/docs/source/hardware/maple-ret6.rst b/docs/source/hardware/maple-ret6.rst
new file mode 100644
index 0000000..3d2d037
--- /dev/null
+++ b/docs/source/hardware/maple-ret6.rst
@@ -0,0 +1,466 @@
+.. highlight:: sh
+
+.. _maple-ret6:
+
+Maple RET6 Edition
+==================
+
+This page is a general resource for information specific to the Maple
+RET6 Edition. The Maple RET6 Edition is a "beta" board released as a
+simple way to get a more powerful chip (the STM32F103\ **RET6**, hence
+the name) than the one on the base Maple (the STM32F103\ **RBT6**) in
+the hands of Maple developers.
+
+.. contents:: Contents
+ :local:
+
+.. TODO [dma.rst] Ref to source/dma.rst in sequel instead of libmaple-dma
+.. TODO [dac.rst] Ref to source/dac.rst in sequel instead of libmaple-dac
+.. TODO [nvic.rst] Ref to source/nvic.rst in sequel
+
+Technical Specifications
+------------------------
+
+* MCU: :ref:`STM32F103RET6 <maple-ret6-stdocs>`, a 32-bit ARM Cortex
+ M3 microprocessor
+* Clock Speed: **72 MHz**
+* **512 KB Flash** and **64 KB SRAM**
+* 43 :ref:`digital I/O pins (GPIOs) <gpio>`
+* 18 :ref:`PWM <pwm>` pins at 16 bit resolution
+* 15 :ref:`analog input (ADC) <adc>` pins at 12 bit resolution
+* Built-in, 2 channel **DAC** at 12 bit resolution (:ref:`libmaple-dac`).
+* 2 :ref:`SPI <spi>` peripherals with **I2S** support
+* 2 :ref:`I2C <i2c>` peripherals
+* 12 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`)
+ with 2 DMA controllers
+* 3 :ref:`USART (serial port) <usart>` peripherals
+* 2 advanced, 4 general-purpose, and 2 basic :ref:`timers <timers>`
+* Dedicated :ref:`USB <usb>` port for programming and communications
+* :ref:`JTAG <jtag>`
+* Nested Vectored Interrupt Controller (NVIC) (including
+ :ref:`external interrupt <lang-attachinterrupt>` on GPIOs)
+* Supplies up to 500 mA at 3.3 V, with :ref:`separate 250 mA digital
+ and analog regulators <maple-ret6-adc-bank>` for low-noise analog
+ performance
+* :ref:`Open-source, four layer design <maple-ret6-hardware>`
+* Support for low power, sleep, and standby modes (<500 μA)
+* Operating Voltage: 3.3 V
+* Input Voltage (recommended): 4 V — 12 V
+* Dimensions are 2.05″ × 2.1″
+
+.. _maple-ret6-powering:
+
+Powering the Maple RET6 Edition
+-------------------------------
+
+The Maple RET6 Edition is powered in the :ref:`same way as the
+standard Maple <maple-powering>`.
+
+.. warning:: The RET6 Edition silkscreen falsely indicates that the
+ barrel jack accepts up to 18 V. We recommend a barrel jack input
+ voltage **no greater than 12V**, and potentially even lower
+ depending upon the current draw requirements of the
+ application. The same goes for powering off LiPo batteries.
+
+ Please see :ref:`Power Regulation on the Maple
+ <maple-power-regulation>` for more information.
+
+.. _maple-ret6power-regulation:
+
+Power Regulation on the Maple RET6
+----------------------------------
+
+Power regulation on the Maple RET6 works in the :ref:`same way as the
+standard Maple <maple-power-regulation>`.
+
+Using the Built-in Battery Charger
+----------------------------------
+
+The RET6 Edition has a built-in LiPo battery charger. In order to use
+it, put a jumper across the CHRG header on the power selection header
+and across the USB, or EXT selectors, depending on whether you're
+charging the battery via USB cable or barrel jack connector. The LED
+labeled CHRG will light up while the battery is being charged. When
+the battery is finished charging, the LED labeled DONE will light up.
+
+.. _maple-ret6-gpios:
+
+GPIO Information
+----------------
+
+The RET6 Edition features 38 ready-to-use general purpose input/output
+(see :ref:`gpio`) pins for digital input/output, numbered ``D0``
+through ``D37``. These numbers correspond to the numeric values next
+to each header on the Maple silkscreen.
+
+.. _maple-ret6-but:
+
+Pin ``D38`` is the board's :ref:`button pin <lang-board-values-but>`.
+It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The
+pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button
+is pressed <lang-isbuttonpressed>`.
+
+More GPIOs (numbered ``D39``\ --``D42`` on the back of the RET6
+Edition's silkscreen) are available if you use the
+:ref:`lang-disabledebugports` function; see the :ref:`board-specific
+debug pin constants <lang-board-values-debug>` for more information.
+(See :ref:`this erratum <maple-ret6-nrst-pb4>` for information about
+the pin numbered ``43`` on the silkscreen).
+
+.. TODO [0.1.0] silkscreen pictures which expand abbreviations
+
+.. _maple-ret6-pin-map-master:
+
+Master Pin Map
+^^^^^^^^^^^^^^
+
+This table shows a summary of the available functionality on every
+GPIO pin, by peripheral type. The "5 V?" column documents whether or
+not the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`.
+
+Note that this table is not exhaustive; on some pins, more peripherals
+are available than are listed here.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART/USART <usart>`, :ref:`SPI <spi>`, 5 V?
+
+ D0, PA3, CH3, 2_CH4, -, 2_RX, -, -
+ D1, PA2, CH2, 2_CH3, -, 2_TX, -, -
+ D2, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, -
+ D3, PA1, CH1, 2_CH2, -, 2_RTS, -, -
+ D4, PB5, -, -, 1_SMBA, -, 3_MOSI, -
+ D5, PB6, -, 4_CH1, 1_SCL, -, -, Yes
+ D6, PA8, -, 1_CH1, -, 1_CK, -, Yes
+ D7, PA9, -, 1_CH2, -, 1_TX, -, Yes
+ D8, PA10, -, 1_CH3, -, 1_RX, -, Yes
+ D9, PB7, -, 4_CH2, 1_SDA, -, -, Yes
+ D10, PA4, CH4, -, -, 2_CK, 1_NSS, -
+ D11, PA7, CH7, 3_CH2, -, -, 1_MOSI, -
+ D12, PA6, CH6, 3_CH1, -, -, 1_MISO, -
+ D13, PA5, CH5, -, -, -, 1_SCK, -
+ D14, PB8, -, 4_CH3, -, -, -, Yes
+ D15, PC0, CH10, -, -, -, -, -
+ D16, PC1, CH11, -, -, -, -, -
+ D17, PC2, CH12, -, -, -, -, -
+ D18, PC3, CH13, -, -, -, -, -
+ D19, PC4, CH14, -, -, -, -, -
+ D20, PC5, CH15, -, -, -, -, -
+ D21, PC13, -, -, -, -, -, -
+ D22, PC14, -, -, -, -, -, -
+ D23, PC15, -, -, -, -, -, -
+ D24, PB9, -, 4_CH4, -, -, -, Yes
+ D25, PD2, -, 3_ETR, -, -, 5_RX, Yes
+ D26, PC10, -, -, -, -, 4_TX, Yes
+ D27, PB0, CH8, 3_CH3, -, -, -, -
+ D28, PB1, CH9, 3_CH4, -, -, -, -
+ D29, PB10, -, -, 2_SCL, 3_TX, -, Yes
+ D30, PB11, -, -, 2_SDA, 3_RX, -, Yes
+ D31, PB12, -, 1_BKIN, 2_SMBA, 3_CK, 2_NSS, Yes
+ D32, PB13, -, 1_CH1N, -, 3_CTS, 2_SCK, Yes
+ D33, PB14, -, 1_CH2N, -, 3_RTS, 2_MISO, Yes
+ D34, PB15, -, 1_CH3N, -, -, 2_MOSI, Yes
+ D35, PC6, -, 8_CH1, -, -, -, Yes
+ D36, PC7, -, 8_CH2, -, -, -, Yes
+ D37, PC8, -, 8_CH3, -, -, -, Yes
+ D38, PC9, -, 8_CH4, -, -, -, Yes
+ D39, PA13, -, -, -, -, -, Yes
+ D40, PA14, -, -, -, -, -, Yes
+ D41, PA15, -, -, -, -, 3_NSS, Yes
+ D42, PB3, -, -, -, -, 3_SCK, Yes
+
+.. _maple-ret6-gpio-port-map:
+
+GPIO Port Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows what pins are associated with each
+:ref:`GPIO port <gpio-ports>`.
+
+.. csv-table::
+ :header: GPIOA, GPIOB, GPIOC
+
+ PA0: D2, PB0: D27, PC0: D15
+ PA1: D3, PB1: D28, PC1: D16
+ PA2: D1, PB2: -, PC2: D17
+ PA3: D0, PB3: D42, PC3: D18
+ PA4: D10, PB4: D43, PC4: D19
+ PA5: D13, PB5: D4, PC5: D20
+ PA6: D12, PB6: D5, PC6: D35
+ PA7: D11, PB7: D9, PC7: D36
+ PA8: D6, PB8: D14, PC8: D37
+ PA9: D7, PB9: D24, PC9: D38
+ PA10: D8, PB10: D29, PC10: D26
+ PA11: -, PB11: D30, PC11: -
+ PA12: -, PB12: D31, PC12: -
+ PA13: D39, PB13: D32, PC13: D21
+ PA14: D40, PB14: D33, PC14: D22
+ PA15: D41, PB15: D34, PC15: D23
+
+.. _maple-ret6-timer-map:
+
+Timer Pin Map
+^^^^^^^^^^^^^
+
+The following table shows what pins are associated with a particular
+timer's capture/compare channels. Note that timer 5's channels share
+pins with timer 2 (e.g., timer 5 channel 1 is also available on D2,
+channel 2 on D3, etc.).
+
+.. csv-table::
+ :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4
+ :delim: |
+
+ 1 | D6 | D7 | D8 | -
+ 2 | D2 | D3 | D1 | D0
+ 3 | D12 | D11 | D27 | D28
+ 4 | D5 | D9 | D14 | D24
+ 8 | D35 | D36 | D37 | :ref:`D38 <maple-ret6-but>`
+
+.. _maple-ret6-exti-map:
+
+EXTI Line Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows which pins connect to which :ref:`EXTI lines
+<external-interrupts-exti-line>` on the Maple RET6 Edition.
+
+.. list-table::
+ :widths: 1 1
+ :header-rows: 1
+
+ * - EXTI Line
+ - Pins
+ * - EXTI0
+ - D2, D15, D27
+ * - EXTI1
+ - D3, D16, D28
+ * - EXTI2
+ - D1, D17, D25
+ * - EXTI3
+ - D0, D18, D42
+ * - EXTI4
+ - D10, D19
+ * - EXTI5
+ - D4, D13, D20
+ * - EXTI6
+ - D5, D12, D35
+ * - EXTI7
+ - D9, D11, D36
+ * - EXTI8
+ - D6, D14, D37
+ * - EXTI9
+ - D7, D24, D38
+ * - EXTI10
+ - D8, D26, D29
+ * - EXTI11
+ - D30
+ * - EXTI12
+ - D31
+ * - EXTI13
+ - D21, D32, D39
+ * - EXTI14
+ - D22, D33, D40
+ * - EXTI15
+ - D23, D34, D41
+
+.. _maple-ret6-usart-map:
+
+USART Pin Map
+^^^^^^^^^^^^^
+
+The Maple RET6 Edition has three serial ports whose pins are broken
+out to headers (also known as :ref:`USARTs <usart>`). They communicate
+using the pins given in the following table.
+
+.. csv-table::
+ :header: Serial Port, TX, RX, CK, CTS, RTS
+ :delim: |
+
+ ``Serial1`` | D7 | D8 | D6 | |
+ ``Serial2`` | D1 | D0 | D10 | D2 | D3
+ ``Serial3`` | D29 | D30 | D31 | D32 | D33
+
+Unfortunately, :ref:`UART4 and UART5 aren't completely available
+<maple-ret6-uarts>`.
+
+.. _maple-ret6-adc-bank:
+
+Low-Noise ADC Pins
+^^^^^^^^^^^^^^^^^^
+
+The six pins at the bottom right of the board (D15—D20) generally
+offer lower-noise ADC performance than other pins on the board. If
+you’re concerned about getting good ADC readings, we recommend using
+one of these pins to take your measurements. More details in the
+:ref:`Maple hardware documentation <maple-adc-bank>`.
+
+Board-Specific Values
+---------------------
+
+This section lists the Maple RET6 Edition's :ref:`board-specific
+values <lang-board-values>`.
+
+- ``CYCLES_PER_MICROSECOND``: 72
+- ``BOARD_BUTTON_PIN``: 38
+- ``BOARD_LED_PIN``: 13
+- ``BOARD_NR_GPIO_PINS``: 44 (however, :ref:`pin D43 is not usable
+ <maple-nrst-pb4>`)
+- ``BOARD_NR_PWM_PINS``: 18
+- ``boardPWMPins``: 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28,
+ 35, 36, 37
+- ``BOARD_NR_ADC_PINS``: 15
+- ``boardADCPins``: 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28
+- ``BOARD_NR_USED_PINS``: 7
+- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``,
+ ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``,
+ ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN``
+- ``BOARD_NR_USARTS``: 3 (unfortunately, :ref:`due to the Maple Rev 5
+ design <maple-ret6-uarts>`, UARTs 4 and 5 have pins which are not
+ broken out).
+- ``BOARD_USART1_TX_PIN``: 7
+- ``BOARD_USART1_RX_PIN``: 8
+- ``BOARD_USART2_TX_PIN``: 1
+- ``BOARD_USART2_RX_PIN``: 0
+- ``BOARD_USART3_TX_PIN``: 29
+- ``BOARD_USART3_RX_PIN``: 30
+- ``BOARD_NR_SPI``: 2 (unfortunately, :ref:`due to the Maple Rev 5
+ design <maple-ret6-nrst-pb4>`, SPI3 is unavailable).
+- ``BOARD_SPI1_NSS_PIN``: 10
+- ``BOARD_SPI1_MOSI_PIN``: 11
+- ``BOARD_SPI1_MISO_PIN``: 12
+- ``BOARD_SPI1_SCK_PIN``: 13
+- ``BOARD_SPI2_NSS_PIN``: 31
+- ``BOARD_SPI2_MOSI_PIN``: 34
+- ``BOARD_SPI2_MISO_PIN``: 33
+- ``BOARD_SPI2_SCK_PIN``: 32
+- ``BOARD_JTMS_SWDIO_PIN``: 39
+- ``BOARD_JTCK_SWCLK_PIN``: 40
+- ``BOARD_JTDI_PIN``: 41
+- ``BOARD_JTDO_PIN``: 42
+- ``BOARD_NJTRST_PIN``: :ref:`43 <maple-ret6-nrst-pb4>`
+
+.. _maple-ret6-hardware:
+
+Hardware Design Files
+---------------------
+
+The hardware schematics and board layout files are available in the
+`Maple GitHub repository <https://github.com/leaflabs/maple>`_. Other
+than the processor used, the design files for the Maple RET6 edition
+are identical to the Maple Rev 5, which are in the ``maple-r5``
+subdirectory of the Maple repository. A schematic for a JTAG adapter
+suitable for use with Maple is available in the ``jtagadapter``
+directory.
+
+From the GitHub repository main page, you can download the entire
+repository by clicking the "Download" button. If you are familiar
+with `Git <http://git-scm.com/>`_, you can also clone the repository
+at the command line with ::
+
+ $ git clone git://github.com/leaflabs/maple.git
+
+.. _maple-ret6-failure-modes:
+
+Failure Modes
+-------------
+
+The following known failure modes apply to all Maple boards. The
+failure modes aren't design errors, but are easy ways to break or
+damage your board permanently.
+
+* **High voltage on non-tolerant pins**: not all header pins are 5V
+ compatible; so e.g. connecting certain serial devices in the wrong
+ way could over-voltage the pins. The :ref:`pin-mapping master table
+ <maple-ret6-pin-map-master>` details which pins are
+ :ref:`5V-tolerant <gpio-5v-tolerant>`.
+
+Errata
+------
+
+This section lists known issues and warnings for the Maple RET6
+Edition. Some of these are simply due to the RET6 Edition using the
+Maple's circuit board, which was not designed to accomodate extra
+features only available on the STM32F103RET6.
+
+.. _maple-ret6-barrel-jack:
+
+* **Barrel jack power supply voltage mistake**: The acceptable voltage
+ range given next to the barrel jack on the Maple RET6 is
+ **incorrect**. The given range is 7V — 18V. In fact, **18V is too
+ high** and should not be supplied to your board. The original
+ voltage regulators used on the Maple were rated up to 18V. However,
+ the voltage regulators on current Maple Revs are rated up to only
+ 16V, and due to the current draw requirements of the board, operate
+ properly only up to 12V. The recommended maximum voltage you should
+ apply is **12V**, and potentially even lower depending upon the
+ current draw requirements of the application. Please see :ref:`Power
+ Regulation on the Maple <maple-power-regulation>` for more
+ information.
+
+* **Power supply marketing mistake**: We originally sold the Maple
+ RET6 Edition advertising that it was capable of supplying up to 800
+ mA; the correct value is 500 mA.
+
+.. _maple-ret6-uarts:
+
+* **UART4, UART5 GPIOs unavailable**: Pins related to UARTs 4 and 5
+ are not broken out to headers (specifically, PC11/UART4_RX and
+ PC12/UART5_TX). This is due to the RET6 Edition's board layout
+ being that of the Maple Rev 5, which was not designed with these
+ RET6-specific features in mind.
+
+.. _maple-ret6-dac-ch2:
+
+* **DAC channel 2 on BOARD_LED_PIN**: The Maple Rev 5 connects PA5 to
+ the board's built-in LED; this is the same GPIO bit which is
+ connected to the DAC's channel 2 output. This is also due to the
+ RET6 Edition's board layout being that of the Maple Rev 5. The DAC
+ output channel is still available, and (if you use the
+ :ref:`standard libmaple DAC interface <libmaple-dac>`) its output is
+ buffered by default, so this may not significantly interfere with
+ its functionality.
+
+.. _maple-ret6-nrst-pb4:
+
+* **Reset and PB4 tied together**: The RET6 Edition's reset line is
+ also connected to PB4, which is labeled on the silkscreen as pin 43.
+ Thus, attempting to use pin 43 as a GPIO can reset your board. This
+ has other implications. Since PB4 is also the JTAG NJTRST line,
+ this prevents the :ref:`JTAG <jtag>` "reset halt" command from
+ working properly. Also, since PB4 is SPI3_MISO, the SPI3 peripheral
+ is not fully usable.
+
+.. _maple-ret6-sdio:
+
+* **SDIO lines not broken out**: The RET6 Edition's SDIO peripheral is
+ not usable, as some of its data lines are either not broken out or
+ used for other purposes. This is also due to the RET6 Edition's
+ board layout being that of the Maple Rev 5.
+
+.. _maple-ret6-adc-led:
+
+* **ADC on BOARD_LED_PIN**: We originally sold the Maple RET6 Edition
+ advertising 16 analog input lines. However, one of them (the one on
+ pin 13) is also connected to the built-in LED. The voltage drop
+ across the LED means that the analog to digital converter on that
+ pin is not really useful. While it is still usable, its readings
+ will be incorrect.
+
+Recommended Reading
+-------------------
+
+.. _maple-ret6-stdocs:
+
+STMicro documentation for STM32F103RE microcontroller:
+
+* `Datasheet
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf>`_
+ (PDF); covers STM32F103xC, STM32F103xD, STM32F103xE.
+* `Reference Manual RM0008
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_
+ (PDF); definitive resource for peripherals on the STM32F1 line.
+* `Programming Manual PM0056
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_
+ (PDF); assembly language and register reference.
+* `STM32F103RE <http://www.st.com/internet/mcu/product/164485.jsp>`_
+ overview page with links to further references.
diff --git a/docs/source/hardware/maple.rst b/docs/source/hardware/maple.rst
new file mode 100644
index 0000000..b187115
--- /dev/null
+++ b/docs/source/hardware/maple.rst
@@ -0,0 +1,618 @@
+.. highlight:: sh
+
+.. _maple:
+
+Maple
+=====
+
+This page is a general resource for information specific to the Maple.
+
+.. contents:: Contents
+ :local:
+
+.. TODO [dma.rst] Ref to dma.rst in sequel instead of libmaple-dma
+.. TODO [nvic.rst] Ref to nvic.rst in sequel
+
+Technical Specifications
+------------------------
+
+* MCU: :ref:`STM32F103RBT6 <maple-stdocs>`, a 32-bit ARM Cortex M3
+ microprocessor
+* Clock Speed: **72 MHz**
+* **128 KB Flash** and **20 KB SRAM**
+* 43 :ref:`digital I/O pins (GPIOs) <gpio>`
+* 15 :ref:`PWM <pwm>` pins at 16 bit resolution
+* 15 :ref:`analog input (ADC) <adc>` pins at 12-bit resolution
+* 2 :ref:`SPI <spi>` peripherals
+* 2 :ref:`I2C <i2c>` peripherals
+* 7 Channels of Direct Memory Access (**DMA**) (:ref:`libmaple-dma`)
+* 3 :ref:`USART (serial port) <usart>` peripherals
+* One advanced and three general-purpose :ref:`timers <timers>`
+* Dedicated :ref:`USB <usb>` port for programming and communications
+* :ref:`JTAG <jtag>`
+* Nested Vectored Interrupt Controller (NVIC) (including
+ :ref:`external interrupt <external-interrupts>` on GPIOs)
+* Supplies up to 500 mA at 3.3 V, with separate 250 mA digital and
+ analog regulators for low-noise analog performance
+* :ref:`Open source, four layer design <maple-hardware>`
+* Support for low power, sleep, and standby modes (<500 μA)
+* Operating Voltage: 3.3 V
+* Input Voltage (recommended): 4 V — 12 V
+* Dimensions: 2.05″ × 2.1″
+
+.. _maple-identify-rev:
+
+Identifying your Rev
+--------------------
+
+We went through three versions ("Revs") of the Maple hardware: Rev 1,
+Rev 3, and Rev 5 [#frev2_4]_; Rev 5, the final design, is currently on
+sale. The following sections will help you to help you identify your
+Rev.
+
+Rev 5
+^^^^^
+
+These boards went on sale in November 2010. They have white buttons
+and "r5" in small print near the "LeafLabs Maple" text next to the
+"infinity leaf" logo. The Maple Rev 5 repositioned the double header
+on the right hand side to better fit 0.1 inch pitch breadboard. This
+necessitated the removal of pins 21 and 22 from the double header;
+they are still available, but don't have any headers installed on
+them.
+
+.. figure:: /_static/img/maple_rev5.png
+ :align: center
+ :alt: Maple Rev 5
+
+Rev 3
+^^^^^
+
+This batch of boards went on sale beginning in May 2010. They have a
+darker red silkscreen and the "infinity leaf" logo. The Maple Rev 3
+was the first version which includes the built-in button, labeled BUT.
+
+.. figure:: /_static/img/maple_rev3.png
+ :align: center
+ :alt: Maple Rev 3
+
+Rev 1
+^^^^^
+
+A small number of Maple Rev 1 boards went on sale in late 2009. They
+have a light red silkscreen and a single pixelated leaf as a logo.
+
+.. figure:: /_static/img/maple_rev1.png
+ :align: center
+ :alt: Maple Rev 1
+
+.. _maple-powering:
+
+Powering the Maple
+------------------
+
+The Maple's power source is determined by the header to the left of
+the "LeafLabs" label on the silkscreen. All versions of the Maple can
+be powered from the barrel jack connector, USB, or a LiPo battery. We
+ship the Maple with a jumper on the USB selector. In order to power
+it off of an alternative source, unplug the Maple, then move the
+jumper to the desired selector before reconnecting power.
+
+You can also power the Maple via the pin labeled "Vin" on the lower
+header. This pin feeds into both the digital and analog voltage
+regulators. However, don't do this while simultaneously powering the
+board from another source, or you could damage it.
+
+When powering the board from a barrel jack, **double check the
+polarity of the barrel.** The appropriate polarity is noted on the
+silkscreen right next to the connector.
+
+.. warning:: Silkscreens on Maples up through Rev 5s manufactured in
+ Spring 2011 falsely indicated that the barrel jack could be
+ supplied by up to 18V. (Rev5s manufactured after Spring 2011 may
+ still have this error on the silk, but it has been marked over.) We
+ recommend a barrel jack input voltage **no greater than 12V**, and
+ potentially even lower depending upon the current draw requirements
+ of the application. The same goes for powering off LiPo batteries.
+
+ Please see :ref:`Power Regulation on the Maple
+ <maple-power-regulation>` for more information.
+
+.. _maple-power-regulation:
+
+Power Regulation on the Maple
+-----------------------------
+
+Power regulation on the Maple is provided by two low dropout linear
+voltage regulators. (The part is the MCP1703 from Microchip, in the
+SOT-23A package. You can download the datasheet `here
+<http://ww1.microchip.com/downloads/en/DeviceDoc/22049a.pdf>`_ ). One
+of the regulators supplies power to the digital voltage plane; the
+other supplies power to the analog voltage plane.
+
+These voltage regulators nominally take an input of up to 16V. In
+addition, while the maximum continuous output current for the board is
+250mA, if you are powering the board off higher voltages the current
+it can supply goes down, due to the regulators needing to dissipate
+the extra power. So if you are powering the board off 12V, the max
+current is about 40mA at room temperature. In general (again, at room
+temperature) the max power dissipation (PD) for the chip is about
+.37W, and output current = PD/(Vin-Vout). For exact max current
+calculations, please refer to the datasheet linked above.
+
+If you are planning to draw a lot of current from the Maple board, it
+is necessary to provide input power as close to 3.3V as
+possible. Powering the microcontroller circuitry and LEDs on the board
+alone takes approximately 30mA, so if you are powering the board with
+12V that leaves only 10mA (at best) available for powering any user
+circuitry. Attempting to draw more than 10mA runs the risk of shorting
+out the power regulators and bricking your board.
+
+Using the Built-in Battery Charger
+----------------------------------
+
+Maples Rev 3 and Rev 5 also have a built-in LiPo battery charger. In
+order to use it, put a jumper across the CHRG header on the power
+selection header and across the USB, or EXT selectors, depending on
+whether you're charging the battery via USB cable or barrel jack
+connector. The LED labeled CHRG will light up while the battery is
+being charged. When the battery is finished charging, the LED labeled
+DONE will light up.
+
+.. _maple-gpios:
+
+GPIO Information
+----------------
+
+The Maple features 38 ready-to-use general purpose input/output (see
+:ref:`gpio`) pins for digital input/output, numbered ``D0`` through
+``D37``. These numbers correspond to the numeric values next to each
+header on the Maple silkscreen.
+
+.. _maple-ret6-but:
+
+Pin ``D38`` is the board's :ref:`button pin <lang-board-values-but>`.
+It is thus mainly useful as an :ref:`input <lang-pin-levels>`. The
+pin will :ref:`read <lang-digitalread>` ``HIGH`` when the :ref:`button
+is pressed <lang-isbuttonpressed>`.
+
+More GPIOs (numbered ``D39``\ --``D42`` on the back of the Maple's
+silkscreen) are available if you use the :ref:`lang-disabledebugports`
+function; see the :ref:`board-specific debug pin constants
+<lang-board-values-debug>` for more information. (See :ref:`this
+erratum <maple-nrst-pb4>` for information about the pin numbered
+``43`` on the silkscreen).
+
+.. TODO [0.1.0] silkscreen pictures which expand abbreviations
+
+.. _maple-pin-map-master:
+
+Master Pin Map
+^^^^^^^^^^^^^^
+
+This table shows a summary of the available functionality on every
+GPIO pin, by peripheral type. The "5 V?" column documents whether or
+not the pin is :ref:`5 volt tolerant <gpio-5v-tolerant>`.
+
+Note that this table is not exhaustive; on some pins, more peripherals
+are available than are listed here.
+
+.. csv-table::
+ :header: Pin, :ref:`GPIO <gpio>`, :ref:`ADC <adc>`, :ref:`Timer <timers>`, :ref:`I2C <i2c>`, :ref:`UART <usart>`, :ref:`SPI <spi>`, 5 V?
+
+ D0, PA3, CH3, 2_CH4, -, 2_RX, -, -
+ D1, PA2, CH2, 2_CH3, -, 2_TX, -, -
+ D2, PA0, CH0, 2_CH1_ETR, -, 2_CTS, -, -
+ D3, PA1, CH1, 2_CH2, -, 2_RTS, -, -
+ D4, PB5, -, -, 1_SMBA, -, -, -
+ D5, PB6, -, 4_CH1, 1_SCL, -, -, Yes
+ D6, PA8, -, 1_CH1, -, 1_CK, -, Yes
+ D7, PA9, -, 1_CH2, -, 1_TX, -, Yes
+ D8, PA10, -, 1_CH3, -, 1_RX, -, Yes
+ D9, PB7, -, 4_CH2, 1_SDA, -, -, Yes
+ D10, PA4, CH4, -, -, 2_CK, 1_NSS, -
+ D11, PA7, CH7, 3_CH2, -, -, 1_MOSI, -
+ D12, PA6, CH6, 3_CH1, -, -, 1_MISO, -
+ D13, PA5, CH5, -, -, -, 1_SCK, -
+ D14, PB8, -, 4_CH3, -, -, -, Yes
+ D15, PC0, CH10, -, -, -, -, -
+ D16, PC1, CH11, -, -, -, -, -
+ D17, PC2, CH12, -, -, -, -, -
+ D18, PC3, CH13, -, -, -, -, -
+ D19, PC4, CH14, -, -, -, -, -
+ D20, PC5, CH15, -, -, -, -, -
+ D21, PC13, -, -, -, -, -, -
+ D22, PC14, -, -, -, -, -, -
+ D23, PC15, -, -, -, -, -, -
+ D24, PB9, -, 4_CH4, -, -, -, Yes
+ D25, PD2, -, 3_ETR, -, -, -, Yes
+ D26, PC10, -, -, -, -, -, Yes
+ D27, PB0, CH8, 3_CH3, -, -, -, -
+ D28, PB1, CH9, 3_CH4, -, -, -, -
+ D29, PB10, -, -, 2_SCL, 3_TX, -, Yes
+ D30, PB11, -, -, 2_SDA, 3_RX, -, Yes
+ D31, PB12, -, -, 2_SMBA, 3_CK, 2_NSS, Yes
+ D32, PB13, -, -, -, 3_CTS, 2_SCK, Yes
+ D33, PB14, -, -, -, 3_RTS, 2_MISO, Yes
+ D34, PB15, -, -, -, -, 2_MOSI, Yes
+ D35, PC6, -, -, -, -, -, Yes
+ D36, PC7, -, -, -, -, -, Yes
+ D37, PC8, -, -, -, -, -, Yes
+ D38, PC9, -, -, -, -, -, Yes
+ D39, PA13, -, -, -, -, -, Yes
+ D40, PA14, -, -, -, -, -, Yes
+ D41, PA15, -, -, -, -, -, Yes
+ D42, PB3, -, -, -, -, -, Yes
+
+.. _maple-gpio-port-map:
+
+GPIO Port Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows what pins are associated with each
+:ref:`GPIO port <gpio-ports>`.
+
+.. csv-table::
+ :header: GPIOA, GPIOB, GPIOC
+
+ PA0: D2, PB0: D27, PC0: D15
+ PA1: D3, PB1: D28, PC1: D16
+ PA2: D1, PB2: -, PC2: D17
+ PA3: D0, PB3: D42, PC3: D18
+ PA4: D10, PB4: D43, PC4: D19
+ PA5: D13, PB5: D4, PC5: D20
+ PA6: D12, PB6: D5, PC6: D35
+ PA7: D11, PB7: D9, PC7: D36
+ PA8: D6, PB8: D14, PC8: D37
+ PA9: D7, PB9: D24, PC9: D38
+ PA10: D8, PB10: D29, PC10: D26
+ PA11: -, PB11: D30, PC11: -
+ PA12: -, PB12: D31, PC12: -
+ PA13: D39, PB13: D32, PC13: D21
+ PA14: D40, PB14: D33, PC14: D22
+ PA15: D41, PB15: D34, PC15: D23
+
+.. _maple-timer-map:
+
+Timer Pin Map
+^^^^^^^^^^^^^
+
+The following table shows what pins are associated with a particular
+timer's capture/compare channels.
+
+.. csv-table::
+ :header: Timer, Ch. 1, Ch. 2, Ch. 3, Ch. 4
+ :delim: |
+
+ 1 | D6 | D7 | D8 | -
+ 2 | D2 | D3 | D1 | D0
+ 3 | D12 | D11 | D27 | D28
+ 4 | D5 | D9 | D14 | D24
+
+.. _maple-exti-map:
+
+EXTI Line Pin Map
+^^^^^^^^^^^^^^^^^
+
+The following table shows which pins connect to which :ref:`EXTI lines
+<external-interrupts-exti-line>` on the Maple.
+
+.. list-table::
+ :widths: 1 1
+ :header-rows: 1
+
+ * - EXTI Line
+ - Pins
+ * - EXTI0
+ - D2, D15, D27
+ * - EXTI1
+ - D3, D16, D28
+ * - EXTI2
+ - D1, D17, D25
+ * - EXTI3
+ - D0, D18, D42
+ * - EXTI4
+ - D10, D19
+ * - EXTI5
+ - D4, D13, D20
+ * - EXTI6
+ - D5, D12, D35
+ * - EXTI7
+ - D9, D11, D36
+ * - EXTI8
+ - D6, D14, D37
+ * - EXTI9
+ - D7, D24, D38
+ * - EXTI10
+ - D8, D26, D29
+ * - EXTI11
+ - D30
+ * - EXTI12
+ - D31
+ * - EXTI13
+ - D21, D32, D39
+ * - EXTI14
+ - D22, D33, D40
+ * - EXTI15
+ - D23, D34, D41
+
+.. _maple-usart-map:
+
+USART Pin Map
+^^^^^^^^^^^^^
+
+The Maple has three serial ports (also known as :ref:`USARTs
+<usart>`): ``Serial1``, ``Serial2``, and ``Serial3``. They communicate
+using the pins given in the following table.
+
+.. csv-table::
+ :header: Serial Port, TX, RX, CK, CTS, RTS
+ :delim: |
+
+ ``Serial1`` | D7 | D8 | D6 | |
+ ``Serial2`` | D1 | D0 | D10 | D2 | D3
+ ``Serial3`` | D29 | D30 | D31 | D32 | D33
+
+.. _maple-adc-bank:
+
+Low-Noise ADC Pins
+^^^^^^^^^^^^^^^^^^
+
+The six pins at the bottom right of the board (D15—D20) generally
+offer lower-noise ADC performance than other pins on the board. If
+you’re concerned about getting good ADC readings, we recommend using
+one of these pins to take your measurements.
+
+Maple has an electrically isolated analog power plane with its own
+regulator, and a geometrically isolated ground plane. Pins D15—D20 are
+laid out to correspond with these analog planes, and our measurements
+indicate that they generally have the lowest noise of all the analog
+lines. However, analog performance may vary depending upon the
+activity of the other GPIOs. Consult the :ref:`Maple hardware design
+files <maple-hardware>` for more details.
+
+Board-Specific Values
+---------------------
+
+This section lists the Maple's :ref:`board-specific values
+<lang-board-values>`.
+
+- ``CYCLES_PER_MICROSECOND``: 72
+- ``BOARD_BUTTON_PIN``: 38
+- ``BOARD_LED_PIN``: 13
+- ``BOARD_NR_GPIO_PINS``: 44 (however, :ref:`pin D43 is not usable
+ <maple-nrst-pb4>`)
+- ``BOARD_NR_PWM_PINS``: 15
+- ``boardPWMPins``: 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28
+- ``BOARD_NR_ADC_PINS``: 15
+- ``boardADCPins``: 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28
+- ``BOARD_NR_USED_PINS``: 7
+- ``boardUsedPins``: ``BOARD_LED_PIN``, ``BOARD_BUTTON_PIN``,
+ ``BOARD_JTMS_SWDIO_PIN``, ``BOARD_JTCK_SWCLK_PIN``,
+ ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``, ``BOARD_NJTRST_PIN``
+- ``BOARD_NR_USARTS``: 3
+- ``BOARD_USART1_TX_PIN``: 7
+- ``BOARD_USART1_RX_PIN``: 8
+- ``BOARD_USART2_TX_PIN``: 1
+- ``BOARD_USART2_RX_PIN``: 0
+- ``BOARD_USART3_TX_PIN``: 29
+- ``BOARD_USART3_RX_PIN``: 30
+- ``BOARD_NR_SPI``: 2
+- ``BOARD_SPI1_NSS_PIN``: 10
+- ``BOARD_SPI1_MOSI_PIN``: 11
+- ``BOARD_SPI1_MISO_PIN``: 12
+- ``BOARD_SPI1_SCK_PIN``: 13
+- ``BOARD_SPI2_NSS_PIN``: 31
+- ``BOARD_SPI2_MOSI_PIN``: 34
+- ``BOARD_SPI2_MISO_PIN``: 33
+- ``BOARD_SPI2_SCK_PIN``: 32
+- ``BOARD_JTMS_SWDIO_PIN``: 39
+- ``BOARD_JTCK_SWCLK_PIN``: 40
+- ``BOARD_JTDI_PIN``: 41
+- ``BOARD_JTDO_PIN``: 42
+- ``BOARD_NJTRST_PIN``: :ref:`43 <maple-nrst-pb4>`
+
+.. _maple-hardware:
+
+Hardware Design Files
+---------------------
+
+The hardware schematics and board layout files are available in the
+`Maple GitHub repository <https://github.com/leaflabs/maple>`_. The
+design files for Rev 1, Rev 3, and Rev 5 are respectively in the
+``maple-r1``, ``maple-r3``, and ``maple-r5`` subdirectories. A
+schematic for a JTAG adapter suitable for use with Maple is available
+in the ``jtagadapter`` directory.
+
+From the GitHub repository main page, you can download the entire
+repository by clicking the "Download" button. If you are familiar
+with `Git <http://git-scm.com/>`_, you can also clone the repository
+at the command line with ::
+
+ $ git clone git://github.com/leaflabs/maple.git
+
+.. _maple-failure-modes:
+
+Failure Modes
+-------------
+
+The following are known failure modes. The failure modes aren't
+design errors, but are easy ways to break or damage your board
+permanently.
+
+* **High voltage on non-tolerant pins**: not all header pins are 5V
+ compatible; so e.g. connecting certain serial devices in the wrong
+ way could over-voltage the pins. The :ref:`pin-mapping master table
+ <maple-pin-map-master>` details which pins are :ref:`5 V tolerant
+ <gpio-5v-tolerant>`.
+
+Errata
+------
+
+This section documents design flaws and other errors.
+
+General
+^^^^^^^
+
+.. _maple-barrel-jack:
+
+* **Barrel jack power supply voltage mistake**: The acceptable voltage
+ range given next to the barrel jack on the Maple through Rev 5s
+ manufactured in Spring 2011 is **incorrect**. The given range is 7V
+ — 18V. In fact, **18V is too high** and should not be supplied to
+ your board. The original voltage regulators used on the Maple were
+ rated up to 18V. However, the voltage regulators on current Maple
+ Revs are rated up to only 16V, and due to the current draw
+ requirements of the board, operate properly only up to 12V. The
+ recommended maximum voltage you should apply is **12V**, and
+ potentially even lower depending upon the current draw requirements
+ of the application. Please see :ref:`Power Regulation on the Maple
+ <maple-power-regulation>` for more information.
+
+.. _maple-nrst-pb4:
+
+* **Reset and PB4 tied together**: The Maple's reset line is also
+ connected to PB4, which is labeled on the silkscreen as pin 43.
+ Thus, attempting to use pin 43 as a GPIO can reset your board. This
+ has other implications. Since PB4 is also the JTAG NJTRST line,
+ this prevents the :ref:`JTAG <jtag>` "reset halt" command from
+ working properly.
+
+.. _maple-power-supply:
+
+* **Power supply marketing mistake**: We originally sold the Maple
+ advertising that it was capable of supplying up to 800 mA; the
+ correct value is 500 mA.
+
+.. _maple-pwm-marketing:
+
+* **PWM marketing mistake**: We originally advertised the Maple as
+ having 22 PWM-capable pins; the correct number is 15.
+
+.. _maple-adc-marketing:
+
+* **ADC marketing mistake**: We originally advertised the Maple as
+ having 16 analog input pins. Due to :ref:`the following issue
+ <maple-adc-led>`, the correct number is 15.
+
+.. _maple-adc-led:
+
+* **ADC on BOARD_LED_PIN**: We originally sold the Maple RET6 Edition
+ advertising 16 analog input lines. However, one of them (the one on
+ pin 13) is also connected to the built-in LED. The voltage drop
+ across the LED means that the analog to digital converter on that
+ pin is not really useful. While it is still usable, its readings
+ will be incorrect.
+
+
+By Rev
+^^^^^^
+
+The following subsections lists known issues and warnings for each
+revision of the Maple board.
+
+Rev 5
+~~~~~
+
+* **Pin 3 AIN missing**: Pin 3 is capable of analog input, but on Rev
+ 5s manufactured during Fall 2010, the corresponding "AIN" is missing
+ from its silkscreen. This mistake was fixed in later manufacturing
+ runs.
+
+Rev 3
+~~~~~
+
+* **Pin 3 AIN missing**: Pin 3 is capable of analog input, but the
+ corresponding "AIN" is missing from the Rev 3 silkscreen.
+
+.. _maple-rev3-bad-buttons:
+
+* **Bad/Sticky Buttons**: a number of Rev 3 boards sold in May-June 2010
+ have questionable RESET and BUT buttons.
+
+ What seems to have happened is that the flux remover we used to
+ clean the boards before shipping eroded the plastic internals, which
+ resulted in intermittent functionality. All buttons on all shipped
+ boards did function in testing, but some may have been unreliable in
+ regular use.
+
+ If you have this problem, we will be happy to ship you new buttons
+ if you think you can re-solder them yourself, or you can ship us
+ your board and we will swap out that part.
+
+ For reference, the button part number is KMR211GLFS and the flux
+ remover we used is "Precision Electronics Cleaner" from RadioShack,
+ which is "Safe on most plastics" and contains: dipropylene glycol
+ monomethyl ether, hydrotreated heavy naphtha, dipropylene glycol
+ methyl ether acetate (say that three times fast!), and carbon
+ dioxide.
+
+* **Resistors on pins 0 and 1**: these header pins, which are RX/TX on
+ USART2 (:ref:`Serial2 <lang-serial>`), have resistors in-line
+ between the STM32 and the headers. These resistors increase the
+ impedance of the lines for ADC reads and affect the open drain GPIO
+ functionality of the pins.
+
+ These resistors were accidentally copied over from older Arduino USB
+ designs, where they appear to protect the USB-Serial converter from
+ TTL voltage on the headers.
+
+* **Silkscreen Errors**: the silkscreen on the bottom indicated PWM
+ functionality on pin 25 and listen the external header GND pin as
+ number 38 (actually 38 is connected to the BUT button). We manually
+ sharpied over both of these mistakes.
+
+Rev 1
+~~~~~
+
+* **ADC noise**: generally very high, in particular when the USB port
+ is being used for communications (including keep-alive pings when
+ connected to a computer).
+
+ This issue was resolved in Rev 3 with a 4-layer design and a
+ :ref:`geometrically isolated ADC Vref plane <maple-adc-bank>`.
+
+* **Resistors on pins 0 and 1**: these header pins, which are RX/TX on
+ USART2 (:ref:`Serial2 <lang-serial>`), have resistors in-line
+ between the STM32 and the headers. These resistors increase the
+ impedance of the lines for ADC reads and affect the open drain GPIO
+ functionality of the pins.
+
+ These resistors were accidentally copied over from older Arduino USB
+ designs, where they appear to protect the USB-Serial converter from
+ TTL voltage on the headers.
+
+* **Silkscreen Differences**: the pin numbering scheme on Rev 1 is
+ different from Rev 3, and thus Rev 3 software is difficult to use
+ with Rev 1 boards. Notably, the analog input bank is labeled A0-A4
+ on Rev 1 but 15-20 on Rev 3, and the extra header bank does not have
+ a pinout table on the bottom.
+
+* **No BUT Button**: the BUT button, useful for serial bootloading,
+ was only added in Rev 3. As a workaround, you can directly short the
+ appropriate MCU pin to Vcc; see `this forum posting
+ <http://forums.leaflabs.com/topic.php?id=32#post-126>`_.
+
+Recommended Reading
+-------------------
+
+.. _maple-stdocs:
+
+STMicro documentation for STM32F103RB microcontroller:
+
+* `Datasheet
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00161566.pdf>`_
+ (PDF); covers STM32F103x8, STM32F103xB.
+* `Reference Manual RM0008
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_
+ (PDF); definitive resource for peripherals on the STM32F1 line.
+* `Programming Manual PM0056
+ <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf>`_
+ (PDF); assembly language and register reference.
+* `STM32F103RB <http://www.st.com/internet/mcu/product/164487.jsp>`_
+ overview page with links to further references.
+
+.. rubric:: Footnotes
+
+.. [#frev2_4] Revs 2 and 4 were prototypes that didn't pass internal
+ testing.
diff --git a/docs/source/i2c.rst b/docs/source/i2c.rst
new file mode 100644
index 0000000..a206ed4
--- /dev/null
+++ b/docs/source/i2c.rst
@@ -0,0 +1,77 @@
+.. _i2c:
+
+|i2c|
+=====
+
+|i2c| is a crude and easy-to-hack serial protocol that requires only
+two wires/channels for communication between Maple and many other
+devices.
+
+.. contents:: Contents
+ :local:
+
+Overview
+--------
+
+Communication via |i2c| is broken up into messages. Every message is
+between a *master* device, which initiates the message, and a *slave*
+device, which responds.
+
+Slaves are addressed using 7-bit addresses (up to 127 unique devices);
+10-bit addressing is also possible. Every message consists of an
+arbitrary combination of 8-bit reads and writes as requested by the
+master. Higher level functionality, such as reading a particular
+register value, is achieved by writing to set the memory location then
+reading to pull out the data.
+
+Note that the master/slave designation is on a message-by-message
+basis. Maple can act as both a master (messages initiated by user
+code) and slave device (responding to requests via configurable
+interrupt handlers) at the same time (though slave mode is currently
+unimplemented).
+
+Hardware/Circuit Design
+-----------------------
+
+.. FIXME [0.1.0] Link to board-specific values (BOARD_I2C1_SDA_PIN, etc.)
+
+Maple boards have two |i2c| ports. Maples reliably communicate with
+up to a 400kHz clock speed; this doesn't translate into a 400kbps
+data rate except in extreme cases because of addressing and protocol
+overhead. We have tested clock speeds up to a megahertz and have had
+mixed results; in theory, it could be possible to achieve even higher
+rates, but signal quality degrades rapidly, and the bus becomes
+unreliable.
+
+Proper wiring and pull-up resistor selection are essential when
+incorporating |i2c| into a circuit, especially with data rates above
+100kHz. In the lab, we usually use approximately 5kΩ resistors with
+|vcc| (3.3V) as the high voltage, and try to connect the pullup
+voltage as close to the SDA and SCL pins as possible. We recommend
+looking at the ST reference website for |i2c| (see the
+:ref:`recommended reading <i2c-recommended-reading>` below), starting
+with a slow clock rate (10kHz), and, if possible, using an
+oscilloscope to debug any issues.
+
+Function Reference
+------------------
+
+Currently, only low-level support in :ref:`libmaple-i2c` exists. A
+Wiring-style library is planned for a future release.
+
+SMBus
+-----
+
+The STM32 microcontroller has hardware support for SMBus, but software
+for it is not yet implemented.
+
+.. _i2c-recommended-reading:
+
+Recommended Reading
+-------------------
+
+* `I2C Bus <http://www.i2c-bus.org/>`_
+* `Wikipedia: I2C <http://en.wikipedia.org/wiki/I%C2%B2C>`_
+* `Arduino I2C/TWI reference <http://www.arduino.cc/en/Reference/Wire>`_
+* ST `Application note STM32F10xxx I2C optimized examples
+ <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00209826.pdf>`_ (PDF)
diff --git a/docs/source/ide.rst b/docs/source/ide.rst
new file mode 100644
index 0000000..e6d49fc
--- /dev/null
+++ b/docs/source/ide.rst
@@ -0,0 +1,166 @@
+.. _ide:
+
+Using Maple IDE
+===============
+
+This page documents the basic functionality of the Maple IDE.
+Specifically, it describes the operation of the buttons on the main
+toolbar. It is expected to become more comprehensive over time.
+
+If you're new to Maple, you should begin with the :ref:`Maple
+Quickstart <maple-quickstart>`.
+
+If you need to install the IDE for the first time, see the
+:ref:`maple-ide-install` page.
+
+.. contents:: Contents
+ :local:
+
+IDE Windows
+-----------
+
+The following screenshot shows the appearance of a Maple IDE window:
+
+.. figure:: /_static/img/ide-blinky.png
+ :align: center
+ :alt: Maple IDE
+
+Note the toolbar buttons at the top; they're the icons with circles or
+squares around them. You can program your board mostly through the
+use of these buttons, which are described in the next section.
+
+Toolbar Buttons
+---------------
+
+.. _ide-verify:
+
+Verify
+~~~~~~
+
+.. image:: /_static/img/button-verify.png
+ :align: left
+
+Click Verify to compile the current sketch. This will process your
+program and produce an executable which can run on your board.
+
+.. _ide-stop:
+
+Stop
+~~~~
+
+.. image:: /_static/img/button-stop.png
+ :align: left
+
+Click Stop to cancel a compilation. Longer programs may take a while
+to compile. Clicking Stop will let you go back to writing code
+without having to wait for compilation to finish.
+
+.. _ide-new:
+
+New
+~~~
+
+.. image:: /_static/img/button-new.png
+ :align: left
+
+Click New to make a fresh sketch.
+
+.. _ide-open:
+
+Open
+~~~~
+
+.. image:: /_static/img/button-open.png
+ :align: left
+
+Click Open to open an existing sketch. Maple IDE will first look for
+the sketch in your *sketchbook*, which is a folder on your computer
+that contains your sketches. The sketchbook is stored in different
+places depending on your operating system. You can change its
+location in the IDE's preferences.
+
+.. _ide-save:
+
+Save
+~~~~
+
+.. image:: /_static/img/button-save.png
+ :align: left
+
+Click Save to save the currently opened sketch. This will save all
+open tabs, not just the one you're currently looking at.
+
+.. _ide-upload:
+
+Upload
+~~~~~~
+
+.. image:: /_static/img/button-upload.png
+ :align: left
+
+Click Upload to send the compiled sketch to your Maple to run. Before
+you click Upload, you must have a memory location and serial port
+selected.
+
+The memory location, either Flash or RAM, determines whether the
+compiled sketch binary will be stored on the Maple. You can choose
+this using the Tools > Board menu.
+
+The serial port corresponds to the :ref:`SerialUSB <lang-serialusb>`
+connection the Maple establishes with your computer. This looks like
+"COM1", "COM2", etc. on Windows, "/dev/tty.usbmodemXXX" on Mac (where
+"XXX" is some sequence of letters and numbers), or "/dev/ttyACMXXX" on
+Linux (again, where "XXX" is some sequence of letters and numbers).
+You can choose a serial port using the Tools > Serial Port menu.
+
+If you're trying to upload and are unsuccessful, make sure you've made
+choices for both board and serial port. More help on uploading
+(including screenshots) is available in the :ref:`quickstart
+<maple-quickstart-upload>`.
+
+If all else fails, try putting your Maple in :ref:`perpetual
+bootloader mode <troubleshooting-perpetual-bootloader>` before
+uploading. You can always find us on the `forum`_ or `contact us
+directly`_ for help on any problems you're having.
+
+.. _ide-serial-monitor:
+
+Serial Monitor
+~~~~~~~~~~~~~~
+
+.. image:: /_static/img/button-serial-monitor.png
+ :align: left
+
+Click Serial Monitor to open up a communication channel between your
+PC and the Maple's :ref:`SerialUSB <lang-serialusb>` virtual serial
+port.
+
+If the serial monitor is open, any information sent to the computer
+(for example, using :ref:`SerialUSB.println()
+<lang-serialusb-println>`) will be displayed in the large text area.
+You can send data to the Maple by typing into the small text box and
+either hitting the Enter key or pressing the Send button. (The Maple
+can read the data you send with :ref:`SerialUSB.read()
+<lang-serialusb-read>`).
+
+Here is an example serial monitor session with the InteractiveTest
+sketch (which you can load in the IDE by choosing menu item File >
+Examples > Maple > InteractiveTest):
+
+.. image:: /_static/img/serial-monitor.png
+
+This is the result of typing "?" in the text box and clicking Send.
+
+.. note:: You cannot upload a sketch while the serial monitor is open.
+ If you click :ref:`Upload <ide-upload>` while the serial monitor is
+ open, the IDE will close it for you before proceeding with the
+ upload.
+
+.. _ide-examples:
+
+Example Code
+------------
+
+Maple IDE comes with a variety of sample code you can use to help you
+get started writing your own programs. To load an example in a new
+Maple IDE window, choose one from the submenus under File > Examples.
diff --git a/docs/source/jtag.rst b/docs/source/jtag.rst
new file mode 100644
index 0000000..caba223
--- /dev/null
+++ b/docs/source/jtag.rst
@@ -0,0 +1,81 @@
+.. highlight:: cpp
+
+.. _jtag:
+
+JTAG
+====
+
+.. FIXME [0.1.0] Updated adapter schematic, better information
+
+JTAG is an interface for low-level debugging of digital devices. It
+gives instruction by instruction control over the microprocessor and
+allows data to be read and written to arbitrary memory and register
+locations. It is typically used with a debugging tool like `gdb
+<http://www.gnu.org/software/gdb/>`_ when hacking low level routines
+and hardware peripherals (we use it when working on :ref:`libmaple
+<libmaple>`) or to flash a new bootloader.
+
+Note that the STM32 on the Maple has a built-in low level serial
+debugger which could also be used to flash bootloaders, and
+:ref:`lang-assert` allows basic debugging over a USART serial channel.
+We expect only fairly advanced users to use this feature.
+
+.. contents:: Contents
+ :local:
+
+Wiring Diagram
+--------------
+
+.. figure:: /_static/img/jtag-wiring.png
+ :align: center
+ :alt: JTAG wiring diagram
+ :width: 7.4in
+ :target: _images/jtag-wiring.png
+
+ JTAG wiring diagram (`large version <_images/jtag-wiring.png>`_)
+ to connect a standard 20-pin ARM JTAG device to the 8-pin JTAG port
+ on the Maple.
+
+The Maple has holes for a 8-pin JTAG header, but that header is not
+soldered on. To use JTAG, simply solder on standard 0.1" pitch male
+header pins (either the exact 4 by 2 block, or two 4-pin pieces of
+straight breakaway header).
+
+Compatible Devices
+------------------
+
+We have had good experience with the `Olimex ARM-USB-OCD
+<http://www.olimex.com/dev/arm-usb-ocd.html>`_ device, which costs
+about €55 plus shipping (as of April 2011).
+
+Function Reference
+------------------
+
+You can disable or enable the JTAG and Serial Wire debugging ports in
+software using the ``disableDebugPorts()`` and ``enableDebugPorts()``
+functions.
+
+* :ref:`lang-disabledebugports`
+* :ref:`lang-enabledebugports`
+
+Recommended Reading
+-------------------
+
+* `Wikipedia Article on Joint Test Action Group (JTAG)
+ <http://en.wikipedia.org/wiki/Joint_Test_Action_Group>`_
+
+* `STM32, GDB, OpenOCD How To
+ <http://fun-tech.se/stm32/OpenOCD/gdb.php>`_
+
+* `LeafLabs Wiki JTAG How To
+ <http://wiki.leaflabs.com/index.php?title=Maple_JTAG_How_To>`_
+
+* `LeafLabs forum thread on JTAG
+ <http://forums.leaflabs.com/topic.php?id=536>`_
+
+* ST documentation:
+
+ * Reference Manual `RM0008
+ <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_
+ (PDF), Chapter 31, "Debug support", and Chapter 9,
+ "General-purpose and alternate function I/Os".
diff --git a/docs/source/lang/api/abs.rst b/docs/source/lang/api/abs.rst
new file mode 100644
index 0000000..d9f1ca3
--- /dev/null
+++ b/docs/source/lang/api/abs.rst
@@ -0,0 +1,48 @@
+.. highlight:: cpp
+
+.. _lang-abs:
+
+
+abs()
+======
+
+(Macro) computes the absolute value of a number.
+
+Syntax
+------
+
+::
+
+ abs(x)
+
+Parameters
+----------
+
+**x**: the number.
+
+Returns
+-------
+
+**x**: if **x** is greater than or equal to 0.
+
+**-x**: if **x** is less than 0.
+
+Warning
+-------
+
+Because of the way ``abs()`` is implemented, avoid using other
+functions or causing side effects inside the parentheses, as it may
+lead to incorrect results::
+
+ abs(a++); // avoid this - yields incorrect results
+
+ abs(a); // use this instead -
+ a++; // keep other operations outside abs()
+
+
+Arduino Compatibility
+---------------------
+
+Maple's implementation of ``abs()`` is compatible with Arduino.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/analogread.rst b/docs/source/lang/api/analogread.rst
new file mode 100644
index 0000000..6665a94
--- /dev/null
+++ b/docs/source/lang/api/analogread.rst
@@ -0,0 +1,119 @@
+.. highlight:: cpp
+
+.. _lang-analogread:
+
+.. _lang-api-analogread:
+
+analogRead()
+============
+
+Used to perform ADC conversion.
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: analogRead
+
+Discussion
+----------
+
+Reads the value from the specified analog pin. The Maple boards
+contain 16-channel, 12-bit analog to digital converters. This means
+that a converter will map input voltages between 0 and 3.3 volts into
+integer values between 0 and 4095. However, a number of factors
+interfere with getting full accuracy and precision. For more
+information, see :ref:`adc`.
+
+Before calling analogRead() on a pin, that pin must first be
+configured for analog input, using :ref:`lang-pinMode`. You only have
+to do this once, so it's usually done in :ref:`lang-setup`\ .
+
+Parameter Discussion
+--------------------
+
+The pin parameter is the number of the analog input pin to read from.
+The pins which support analog to digital conversion have ``AIN``
+listed underneath their number on your board's silkscreen. These pin
+numbers are available to your program in the :ref:`boardADCPins
+<lang-board-values-adc-pins>` board-specific array. The number of
+pins which are capable of analog to digital conversion on your board
+is given by the ``BOARD_NR_ADC_PINS`` constant. These values are
+documented for each board in the :ref:`Board Hardware Documentation
+<index-boards>` pages.
+
+.. note:: Pin 3 is not marked ``AIN`` on the silkscreen for Maple
+ revisions through Rev 5; however **it does work** as an analog
+ input pin.
+
+Note
+----
+
+If the analog input pin is not connected to anything, the value
+returned by ``analogRead()`` will fluctuate due to a number of reasons
+(like the values of the other analog inputs, how close your hand is to
+the board, etc.) in a "random" way.
+
+Example
+-------
+
+::
+
+ int analogPin = 3; // Potentiometer wiper (middle terminal) connected
+ // to analog pin 3. outside leads to ground and +3.3V.
+ // You may have to change this value if your board
+ // cannot perform ADC conversion on pin 3.
+
+ int val = 0; // variable to store the value read
+
+ void setup() {
+ pinMode(analogPin, INPUT_ANALOG); // set up pin for analog input
+ }
+
+ void loop() {
+ val = analogRead(analogPin); // read the input pin
+ SerialUSB.println(val); // print the value, for debugging with
+ // a serial monitor
+ }
+
+Arduino Compatibility
+---------------------
+
+The Arduino board contains a 6 channel (8 channels on the Mini and
+Nano, 16 on the Mega), 10-bit analog to digital converter with an
+input voltage range of 0V--5V. This means that it will map input
+voltages between 0 and 5 volts (which is **larger** than Maple's range
+of 0V-3.3V) into integer values between 0 and 1023 (which is
+**smaller** than the Maple's range of 0--4095).
+
+This yields a theoretical resolution between readings of: 5 volts /
+1024 units or .0049 volts (4.9 mV) per unit on Arduino boards, which
+is larger, and thus less precise, than Maple's 0.0008 volts (0.8 mV).
+
+If your program expects Arduino-style 10-bit ADC, you can :ref:`right
+shift <lang-bitshift>` the value of a Maple readout by 2, like so::
+
+ // right shift means that the result will be between 0 and 1023;
+ // be aware that you're losing a lot of precision if you do this
+ int adc_reading = analogRead(pin) >> 2;
+
+.. FIXME [0.1.0] Mention that Native can do analogReference()
+
+On the Arduino, the input range and resolution can be changed using
+the `analogReference()
+<http://arduino.cc/en/Reference/AnalogReference>`_ function. Because
+of hardware restrictions, this function is not available on the Maple
+and Maple RET6 Edition. If your inputs lie in a different voltage
+range than 0V--3.3V, you'll need to bring them into that range before
+using ``analogRead()``. See the :ref:`ADC reference <adc-range>` for
+more information.
+
+See Also
+--------
+
+- :ref:`ADC tutorial <adc>`
+- `(Arduino) Tutorial: Analog Input Pins <http://arduino.cc/en/Tutorial/AnalogInputPins>`_
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/analogwrite.rst b/docs/source/lang/api/analogwrite.rst
new file mode 100644
index 0000000..0169976
--- /dev/null
+++ b/docs/source/lang/api/analogwrite.rst
@@ -0,0 +1,181 @@
+.. highlight:: cpp
+
+.. _lang-analogwrite:
+
+.. _lang-api-analogwrite:
+
+
+analogWrite()
+=============
+
+analogWrite() is used to create a :ref:`PWM <pwm>` wave on a pin.
+
+.. note::
+
+ On the Maple, calling analogWrite() is the same as calling
+ :ref:`lang-pwmwrite`. We recommend writing pwmWrite() instead of
+ analogWrite().
+
+ This is because PWM is not true analog output (it's not the output
+ of a `DAC
+ <http://en.wikipedia.org/wiki/Digital-to-analog_converter>`_\ ), so
+ the function is very badly named. For instance, **analogWrite()
+ has nothing to do with** :ref:`lang-analogread`\ , which can be
+ confusing.
+
+ We provide analogWrite() for the sake of compatibility with Arduino
+ only.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-analogwrite-compatibility:
+
+Arduino Compatibility
+---------------------
+
+There are a few important differences between Arduino's `analogWrite()
+<http://arduino.cc/en/Reference/AnalogWrite>`_ and Maple's
+:ref:`lang-pwmwrite` that you should keep in mind. In each case, we
+have some recommendations you can use to help converting from Arduino
+to Maple.
+
+Difference 1: Duty cycle range is different
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The first and most important difference is that the largest possible
+value for the duty cycle is much bigger on the Maple. Using Arduino's
+analogWrite(), the duty cycle ranges between 0--255 (always off --
+always on)\ [#fbytemax]_\ . Using Maple's pwmWrite(), the duty cycle
+ranges from 0--65,535 by default\ [#fuint16max]_\ .
+
+This is a good thing! The greater range of values on the Maple gives
+you much more precise control over the duty cycle of your PWM output.
+
+If you're porting code from the Arduino and want a quick-and-dirty
+fix, one solution is to :ref:`map <lang-map>` the argument to
+analogWrite() into the right range::
+
+ // Arduino code:
+ analogWrite(pin, duty);
+
+ // Becomes Maple code:
+ analogWrite(pin, map(duty, 0, 255, 0, 65535));
+
+This will convert values in the range 0-255 to values in the range
+0--65,535, which is the correct default range for all of the timers
+which control PWM output. See the :ref:`timers reference <timers>`
+for more information.
+
+Another fix is to consult your board's :ref:`pin maps <gpio-pin-maps>`
+to find the timer which controls PWM on the pin you're using, then set
+that timer's overflow to 255. Subsequent calls to analogWrite()
+should work as on the Arduino (with the same loss of precision).
+Note, however, that that affects the overflow for the **entire
+timer**, so other code relying on that timer (such as any
+:ref:`interrupts <lang-hardwaretimer-interrupts>` the timer controls)
+will likely need to be modified as well.
+
+Difference 2: You must use pinMode() to set up PWM
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The second difference is that on the Maple, you **must** set up the pin
+for PWM output using :ref:`lang-pinmode`\ , with argument ``PWM``.
+This should just be one extra line of code in your
+:ref:`lang-setup` function. Example::
+
+ void setup() {
+ // set up pin 9 for PWM
+ pinMode(9, PWM);
+ }
+
+This also means that you can't later call :ref:`lang-digitalread`
+or :ref:`lang-digitalwrite` on that pin (unless some time in
+between, you use pinMode() to reconfigure that pin for ``INPUT`` or
+``OUTPUT``; see the :ref:`lang-pinmode` page for more information).
+
+Difference 3: No PWM on pin 10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On the Maple, the pins which support PWM are: 0, 1, 2, 3, 5, 6, 7, 8,
+9, 11, 12, 14, 24, 27, and 28 or fifteen pins in total. That's *more*
+PWM-capable pins as any Arduino board, but there are differences in
+*which* pins support PWM.
+
+* On **most Arduino boards** (those with the ATmega168 or ATmega328;
+ this includes the **Arduino Uno**), this function works on pins 3,
+ 5, 6, 9, 10, and 11, or six pins total. Note that these boards
+ support PWM on pin 10, while Maple does not.
+
+* On the **Arduino Mega**, PWM works on pins 2 through 13, or twelve
+ pins total. Note that this board supports PWM on pins 4, 10, and
+ 13, while the Maple does not.
+
+* **Older Arduino boards** with an ATmega8 only support analogWrite()
+ on pins 9, 10, and 11. Maple does not support PWM on pin 10.
+
+In all cases, Arduino boards support PWM on pin 10, unlike Maple. We
+did our best to make PWM as pin-compatible as possible; however,
+circuit layout constraints prevented us from achieving perfect
+compatibility.
+
+The "safest" pins to use for PWM output are pins 9 and 11. These pins
+work on any Arduino board and on Maple. The "safe" pins, which work
+on most recent Arduino boards, the Arduino Mega and the Maple, are
+pins 3, 5, 6, 9, and 11. Thus, if you want your project to be as
+portable as possible between Maple and Arduino, we recommend using the
+"safest" pins first, then the "safe" pins, then any other pins, as
+necessary.
+
+Difference 4: PWM frequency
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The frequency of the PWM signal (i.e., the frequency of a complete
+on/off cycle) on the Arduino is approximately 490 Hz.
+
+On the Maple, the frequency is configurable, defaulting to about 1100
+Hz, or 1.1 KHz. This is because the PWM frequency is the frequency of
+the timer which controls PWM output on the particular pin (\
+:ref:`the PWM tutorial has the details <pwm>`\ ).
+
+If your application definitely requires Arduino's PWM frequency, then
+the steps are:
+
+1. Figure out which :ref:`timer <lang-hardwaretimer>` controls PWM
+ output on your pin (\ :ref:`your board's Timer Pin Map
+ <gpio-pin-maps>` is your friend here).
+
+2. Let's say it's timer ``n``, where ``n`` is some number. You'll
+ then need to put "``HardwareTimer timer(n);``" with your variables,
+ as described in the :ref:`HardwareTimer
+ <lang-hardwaretimer-getting-started>` reference.
+
+3. In your :ref:`lang-setup`, put "``timer.setPeriod(2041);``". This
+ will set the timer's period to approximately 2041 microseconds,
+ which is a frequency of approximately 490 Hz.
+
+Be aware that this will change the period for the **entire timer**\ ,
+and will affect anything else in your program that depends on that
+timer. The important examples are :ref:`timer interrupts
+<lang-hardwaretimer-interrupts>` and :ref:`PWM
+<timers-pwm-conflicts>`\ .
+
+See Also
+--------
+
+- :ref:`pwm`
+- :ref:`lang-pwmwrite`
+- :ref:`BOARD_NR_PWM_PINS <lang-board-values-nr-pwm-pins>`
+- :ref:`boardPWMPins <lang-board-values-pwm-pins>`
+
+.. rubric:: Footnotes
+
+.. [#fbytemax] This is because the value for the duty cycle on Arduino
+ must fit in 1 byte of memory, and an unsigned (i.e., nonnegative)
+ integer with size 1 byte can hold the values between 0 and 255.
+
+.. [#fuint16max] This is because the value for the duty cycle on the
+ Maple uses 2 bytes of memory, and an unsigned (i.e., nonnegative)
+ integer with size 2 bytes can hold the values between 0 and 65,535.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/assert.rst b/docs/source/lang/api/assert.rst
new file mode 100644
index 0000000..76330b6
--- /dev/null
+++ b/docs/source/lang/api/assert.rst
@@ -0,0 +1,30 @@
+.. highlight:: cpp
+
+.. _lang-assert:
+
+``ASSERT(...)``
+===============
+
+ASSERT() can be very useful for basic program debugging. It accepts a
+boolean; for example::
+
+ ASSERT(state == WAIT);
+
+Zero is false and any other number is true. If the boolean is true,
+the assertion passes and the program continues as usual. If it is
+false, the assertion fails: the program is halted, debug information
+is printed to USART2, and the status LED begins to throb (it's
+noticeably different from blinking). The debug information is printed
+at 9600 baud and consists of the filename and line number where the
+ASSERT() failed.
+
+Including assertions in a program increases the program size. When
+using libmaple **from the command line only**, they can be disabled by
+making the definition ::
+
+ #define DEBUG_LEVEL DEBUG_NONE
+
+before including either wirish.h or libmaple.h. In this case, all
+assertions will pass without any lost clock cycles. Note that this
+will **not work in the IDE**; even with this definition, assertions
+will still be enabled.
diff --git a/docs/source/lang/api/attachinterrupt.rst b/docs/source/lang/api/attachinterrupt.rst
new file mode 100644
index 0000000..58e4764
--- /dev/null
+++ b/docs/source/lang/api/attachinterrupt.rst
@@ -0,0 +1,114 @@
+.. highlight:: cpp
+
+.. _lang-attachinterrupt:
+
+attachInterrupt()
+=================
+
+Used to specify a function to call when an :ref:`external interrupt
+<external-interrupts>` occurs.
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. FIXME [doxygenfunction] once Breathe knows how to get the correct
+.. attachInterupt (right now it's copying from HardwareTimer), replace
+.. with a doxygenfunction directive
+
+.. cpp:function:: void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode)
+
+ Registers an interrupt handler on a pin.
+
+ The interrupt will be triggered on a given transition on the pin,
+ as specified by the mode parameter. The handler runs in interrupt
+ context. The new handler will replace whatever handler is
+ currently registered for the pin, if any.
+
+ *Parameters*
+
+ - ``pin`` - Maple pin number
+
+ - ``handler`` - Function to run upon external interrupt trigger.
+ The handler should take no arguments, and have void return type.
+
+ - ``mode`` - Type of transition to trigger on, e.g. falling,
+ rising, etc.
+
+.. doxygenenum:: ExtIntTriggerMode
+
+.. doxygentypedef:: voidFuncPtr
+
+.. note::
+
+ You should set the :ref:`pin mode <lang-pinmode>` of your desired
+ pin to an input mode (e.g. ``INPUT``, ``INPUT_PULLUP``,
+ ``INPUT_PULLDOWN``).
+
+Discussion
+----------
+
+Because the function will run in interrupt context, inside of it,
+:ref:`lang-delay` won't work, and the value returned by
+:ref:`lang-millis` will not increment. Serial data received while in
+the function may be lost. You should declare as ``volatile`` any
+global variables that you modify within the attached function.
+
+There are some limits you should be aware of if you're using
+``attachInterrupt()`` with more than one pin; the :ref:`External
+Interrupts <external-interrupts-exti-line>` page has more information.
+
+Example
+-------
+
+The following example blinks the LED any time pin 0 changes from
+``HIGH`` to ``LOW`` or vice versa. ::
+
+ volatile int state = LOW; // must declare volatile, since it's
+ // modified within the blink() handler
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ pinMode(0, INPUT);
+ attachInterrupt(0, blink, CHANGE);
+ }
+
+ void loop() {
+ digitalWrite(BOARD_LED_PIN, state);
+ }
+
+ void blink() {
+ if (state == HIGH) {
+ state = LOW;
+ } else { // state must be LOW
+ state = HIGH;
+ }
+ }
+
+In this example, the function ``blink()`` is the interrupt handler.
+Whenever the state on pin 0 changes, ``blink()`` gets called. It
+reacts to the change by changing the ``state`` variable to ``LOW`` if
+it is ``HIGH``, and to ``HIGH`` if it is ``LOW``. It then exits,
+letting the board get back to calling ``loop()``. Since ``loop()``
+sets the LED pin to whatever ``state`` is, changing the voltage on pin
+0 will toggle the LED.
+
+Arduino Compatibility
+---------------------
+
+Most Arduino boards have two external interrupts: numbers 0 (on
+digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an
+additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5
+(pin 18). On the Maple, you don't have to remember which interrupt
+number goes with which pin -- just tell ``attachInterrupt()`` the pin
+you want.
+
+See Also
+--------
+
+- :ref:`lang-detachinterrupt`
+- :ref:`external-interrupts`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/bit.rst b/docs/source/lang/api/bit.rst
new file mode 100644
index 0000000..3df042c
--- /dev/null
+++ b/docs/source/lang/api/bit.rst
@@ -0,0 +1,38 @@
+.. _lang-bit:
+
+bit()
+=====
+
+(Macro) Computes the value of an (unsigned) integer with the specified
+bit set (``bit(0)`` is 1, ``bit(1)`` is 2, ``bit(2)`` is 4, then 8,
+16, 32, etc.).
+
+Syntax
+------
+
+``bit(n)``
+
+Parameters
+----------
+
+* **n** the bit to set.
+
+Value
+-----
+
+The value of an integer with the given bit set.
+
+Arduino Compatibility
+---------------------
+
+The Maple implementation of ``bit()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`lang-bitread`
+- :ref:`lang-bitwrite`
+- :ref:`lang-bitset`
+- :ref:`lang-bitclear`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/bitclear.rst b/docs/source/lang/api/bitclear.rst
new file mode 100644
index 0000000..f487059
--- /dev/null
+++ b/docs/source/lang/api/bitclear.rst
@@ -0,0 +1,39 @@
+.. _lang-bitclear:
+
+bitClear()
+==========
+
+(Macro) Clears (writes a 0 to) a bit of a numeric variable.
+
+Syntax
+------
+
+``bitClear(x, n)``
+
+Parameters
+----------
+
+* **x** the numeric variable whose bit to clear
+
+* **n** which bit to clear, starting at 0 for the least-significant
+ (rightmost) bit
+
+Returns
+-------
+
+Nothing.
+
+Arduino Compatibility
+---------------------
+
+The Maple implementation of ``bitClear()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`bit <lang-bit>`\ ()
+- :ref:`bitRead <lang-bitread>`\ ()
+- :ref:`bitWrite <lang-bitwrite>`\ ()
+- :ref:`bitSet <lang-bitset>`\ ()
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/bitread.rst b/docs/source/lang/api/bitread.rst
new file mode 100644
index 0000000..fd9fbbe
--- /dev/null
+++ b/docs/source/lang/api/bitread.rst
@@ -0,0 +1,39 @@
+.. _lang-bitread:
+
+bitRead()
+=========
+
+(Macro) Gets the value of a bit in a number.
+
+Syntax
+------
+
+``bitRead(x, n)``
+
+Parameters
+----------
+
+* **x** the number from which to read the bit.
+
+* **n** which bit to read, starting at 0 for the least-significant
+ (rightmost) bit
+
+Value
+-----
+
+The value of the bit (0 or 1).
+
+Arduino Compatibility
+---------------------
+
+The Maple implementation of ``bitRead`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`lang-bit`
+- :ref:`lang-bitwrite`
+- :ref:`lang-bitset`
+- :ref:`lang-bitclear`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/bitset.rst b/docs/source/lang/api/bitset.rst
new file mode 100644
index 0000000..83ab5f8
--- /dev/null
+++ b/docs/source/lang/api/bitset.rst
@@ -0,0 +1,39 @@
+.. _lang-bitset:
+
+bitSet()
+========
+
+(Macro) Sets (writes a 1 to) a bit of a numeric variable.
+
+Syntax
+------
+
+``bitSet(x, n)``
+
+Parameters
+----------
+
+* **x** the numeric variable whose bit to set
+
+* **n** which bit to set, starting at 0 for the least-significant
+ (rightmost) bit
+
+Value
+-----
+
+None.
+
+Arduino Compatibility
+---------------------
+
+The Maple implementation of bitSet is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`lang-bit`
+- :ref:`lang-bitread`
+- :ref:`lang-bitwrite`
+- :ref:`lang-bitclear`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/bitwrite.rst b/docs/source/lang/api/bitwrite.rst
new file mode 100644
index 0000000..6106545
--- /dev/null
+++ b/docs/source/lang/api/bitwrite.rst
@@ -0,0 +1,45 @@
+.. highlight:: cpp
+
+.. _lang-bitwrite:
+
+bitWrite()
+==========
+
+(Macro) Writes a bit of a numeric variable.
+
+Syntax
+------
+
+::
+
+ bitWrite(x, n, b)
+
+Parameters
+----------
+
+**x**: the numeric variable whose bit to write.
+
+**n**: which bit of the number to write, starting at 0 for the
+least-significant (rightmost) bit.
+
+**b**: the value to write to the bit (0 or 1).
+
+Returns
+-------
+
+Nothing.
+
+Arduino Compatibility
+---------------------
+
+Maple's implementation of ``bitWrite()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`bit() <lang-bit>`
+- :ref:`bitRead() <lang-bitRead>`
+- :ref:`bitSet() <lang-bitSet>`
+- :ref:`bitClear() <lang-bitClear>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/board-values.rst b/docs/source/lang/api/board-values.rst
new file mode 100644
index 0000000..d944c8d
--- /dev/null
+++ b/docs/source/lang/api/board-values.rst
@@ -0,0 +1,189 @@
+.. highlight:: cpp
+
+.. _lang-board-values:
+
+Board-Specific Values
+=====================
+
+There are a number of board-specific values: constants or variables
+which are different depending on which LeafLabs board you have. The
+exact values for each board are given in your :ref:`board's hardware
+documentation <index-boards>`.
+
+This page lists and documents the board-specific values. You should
+use these when appropriate in your own programs. This will help make
+it easier to share your code with other people who have different
+boards. Some example usages are given :ref:`below
+<lang-board-values-examples>`.
+
+.. contents:: Contents
+ :local:
+
+Constants
+---------
+
+- ``CYCLES_PER_MICROSECOND``: Number of CPU cycles per microsecond on
+ your board.
+
+- ``CLOCK_SPEED_MHZ``: Clock speed of your board, in megahertz
+ (MHz). This is the same as ``CYCLES_PER_MICROSECOND``.
+
+- ``CLOCK_SPEED_HZ``: Clock speed of your board, in hertz (Hz). This
+ is the same as ``CLOCK_SPEED_MHZ`` × 1,000,000.
+
+- ``SYSTICK_RELOAD_VAL``: Value used when reloading the :ref:`systick`
+ timer's counter [#fmillis]_.
+
+.. _lang-board-values-but:
+
+- ``BOARD_BUTTON_PIN``: Pin connected to the built-in button (labeled
+ "BUT" on your board's silkscreen).
+
+.. _lang-board-values-led:
+
+- ``BOARD_LED_PIN``: Pin connected to the built-in LED.
+
+- ``BOARD_NR_GPIO_PINS``: Total number of :ref:`GPIO pins <gpio>` that
+ are broken out to headers. Some of these might already be connected
+ to external hardware (like the built-in LED and button). To find
+ out if a pin is in use, see :ref:`boardUsesPin()
+ <lang-boardusespin>` (and also :ref:`boardUsedPins
+ <lang-board-values-used-pins>`).
+
+.. _lang-board-values-nr-pwm-pins:
+
+- ``BOARD_NR_PWM_PINS``: Total *number* of GPIO pins that can be used
+ for :ref:`PWM <pwm>`. The actual *pins* that can do PWM are in the
+ :ref:`boardPWMPins <lang-board-values-pwm-pins>` array.
+
+.. _lang-board-values-nr-adc-pins:
+
+- ``BOARD_NR_ADC_PINS``: Total number of GPIO pins that can be used
+ for :ref:`analog-to-digital conversion <adc>`. The actual pins that
+ can do ADC conversion are in the :ref:`boardADCPins
+ <lang-board-values-adc-pins>` array.
+
+.. _lang-board-values-nr-used-pins:
+
+- ``BOARD_NR_USED_PINS``: Total number of GPIO pins that are already
+ connected to some external hardware (like a built-in LED) on the
+ board. The actual pins that that are already used are in the
+ :ref:`boardUsedPins <lang-board-values-used-pins>` array. To see if
+ a pin is already in use, use the :ref:`boardUsesPin()
+ <lang-boardusespin>` function.
+
+.. _lang-board-values-usart:
+
+- :ref:`USART <usart>` (serial port) related constants:
+
+ * ``BOARD_USART1_TX_PIN``, ``BOARD_USART2_TX_PIN``, ``BOARD_USART3_TX_PIN``:
+ TX pins for the 3 USARTS.
+
+ * ``BOARD_USART1_RX_PIN``, ``BOARD_USART2_RX_PIN``, ``BOARD_USART3_RX_PIN``:
+ RX pins for the 3 USARTS.
+
+ * ``BOARD_UART4_TX_PIN``, ``BOARD_UART5_TX_PIN``: TX pins for
+ UARTs 4 and 5 (high-density boards like Maple Native only).
+
+ * ``BOARD_UART4_RX_PIN``, ``BOARD_UART5_RX_PIN``: RX pins for
+ UARTs 4 and 5 (high-density boards like Maple Native only).
+
+ * ``BOARD_NR_USARTS``: Number of serial ports on the board. This
+ number includes UARTs 4 and 5 if they are available.
+
+- :ref:`SPI <spi>` related constants:
+
+ * ``BOARD_SPI1_NSS_PIN``, ``BOARD_SPI1_MOSI_PIN``,
+ ``BOARD_SPI1_MISO_PIN``, ``BOARD_SPI1_SCK_PIN``: SPI1
+ peripheral's NSS, MOSI, MISO, and SCK pins, respectively.
+
+ * ``BOARD_SPI2_NSS_PIN``, ``BOARD_SPI2_MOSI_PIN``,
+ ``BOARD_SPI2_MISO_PIN``, ``BOARD_SPI2_SCK_PIN``: SPI2
+ peripheral's NSS, MOSI, MISO, and SCK pins, respectively.
+
+ * ``BOARD_SPI3_NSS_PIN``, ``BOARD_SPI3_MOSI_PIN``,
+ ``BOARD_SPI3_MISO_PIN``, ``BOARD_SPI3_SCK_PIN``: SPI3
+ peripheral's NSS, MOSI, MISO, and SCK pins, respectively
+ (available on high-density devices like Maple Native and Maple
+ RET6 edition only).
+
+ * ``BOARD_NR_SPI``: Number of SPI peripherals on the board.
+
+.. _lang-board-values-debug:
+
+- Debug (JTAG, SW-Debug) related constants: ``BOARD_JTMS_SWDIO_PIN``,
+ ``BOARD_JTCK_SWCLK_PIN``, ``BOARD_JTDI_PIN``, ``BOARD_JTDO_PIN``,
+ and ``BOARD_NJTRST_PIN``.
+
+ These constants are the pin numbers for :ref:`GPIOs <gpio>` used by
+ the :ref:`jtag` and Serial-Wire Debug peripherals. Except for the
+ Maple Mini, these pins are usually reserved for special purposes by
+ default (i.e., they are in :ref:`boardUsedPins
+ <lang-board-values-used-pins>`). However, they can be used as
+ ordinary GPIOs if you call the :ref:`lang-disabledebugports`
+ function. (Be careful with this on the Maple and Maple RET6
+ Edition, as writing to ``BOARD_NJTRST_PIN`` :ref:`may cause your
+ board to reset <maple-nrst-pb4>`\ !).
+
+.. _lang-board-values-pwm-pins:
+
+.. _lang-board-values-adc-pins:
+
+.. _lang-board-values-used-pins:
+
+Pin Arrays
+----------
+
+Some :ref:`arrays <lang-array>` of pin numbers are available which you
+can use to find out certain important information about a given pin.
+
+- ``boardPWMPins``: Pin numbers of each pin capable of :ref:`PWM
+ <pwm>` output, using :ref:`pwmWrite() <lang-pwmwrite>`. The total
+ number of these pins is :ref:`BOARD_NR_PWM_PINS
+ <lang-board-values-nr-pwm-pins>`.
+
+- ``boardADCPins``: Pin numbers of each pin capable of :ref:`ADC
+ <adc>` conversion, using :ref:`analogRead() <lang-analogread>`. The
+ total number of these pins is :ref:`BOARD_NR_ADC_PINS
+ <lang-board-values-nr-adc-pins>`.
+
+- ``boardUsedPins``: Pin numbers of each pin that, by default, is used
+ for some special purpose by the board. The total number of these
+ pins is :ref:`BOARD_NR_USED_PINS <lang-board-values-nr-used-pins>`.
+ To check if a pin is used for a special purpose, use
+ :ref:`boardUsesPin() <lang-boardusespin>`.
+
+.. _lang-board-values-examples:
+
+Examples
+--------
+
+:ref:`BOARD_LED_PIN <lang-board-values-led>` On the Maple, the
+built-in LED is connected to pin 13. On the Maple Mini, however, it
+is connected to pin 33. You can write a "blinky" program that works
+on both boards using :ref:`this example <lang-toggleled-example>`.
+
+:ref:`BOARD_BUTTON_PIN <lang-board-values-but>`: On the Maple, the
+built-in button is connected to pin 38. On the Maple Mini, however,
+it is connected to pin 32. :ref:`This example
+<lang-waitforbuttonpress-example>` shows how you can write a program
+that prints a message whenever the button is pressed which will work
+on all LeafLabs boards.
+
+See Also
+--------
+
+- :ref:`lang-boardusespin`
+- :ref:`lang-isbuttonpressed`
+- :ref:`lang-waitforbuttonpress`
+- :ref:`lang-pinmode`
+- :ref:`lang-toggleled`
+- :ref:`lang-analogread`
+- :ref:`lang-pwmwrite`
+- :ref:`lang-enabledebugports`
+- :ref:`lang-disabledebugports`
+
+.. rubric:: Footnotes
+
+.. [#fmillis] In order for :ref:`lang-millis` to work properly, this
+ must be ``CYCLES_PER_MICROSECOND`` × 1,000 - 1.
diff --git a/docs/source/lang/api/boardusespin.rst b/docs/source/lang/api/boardusespin.rst
new file mode 100644
index 0000000..126c4a0
--- /dev/null
+++ b/docs/source/lang/api/boardusespin.rst
@@ -0,0 +1,27 @@
+.. highlight:: cpp
+
+.. _lang-boardusespin:
+
+boardUsesPin()
+==============
+
+Each LeafLabs board connects some pins to external hardware. The most
+important examples of this are the pins connected to the built-in LED
+and button. You can check if a board uses a particular pin using this
+function.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: boardUsesPin
+
+See Also
+--------
+
+- :ref:`Board-specific values <lang-board-values>`
+- :ref:`boardUsedPins <lang-board-values-used-pins>`
+- :ref:`BOARD_LED_PIN <lang-board-values-led>`
+- :ref:`toggleLED() <lang-toggleled>`
+- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>`
+- :ref:`isButtonPressed() <lang-isbuttonpressed>`
+- :ref:`waitForButtonPress() <lang-waitforbuttonpress>`
diff --git a/docs/source/lang/api/constants.rst b/docs/source/lang/api/constants.rst
new file mode 100644
index 0000000..6f69dfe
--- /dev/null
+++ b/docs/source/lang/api/constants.rst
@@ -0,0 +1,318 @@
+.. _lang-constants:
+
+Constants
+=========
+
+Constants are like predefined variables, whose values can't
+change. They are used to make the programs easier to read and modify.
+This page describes the most commonly used constants.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-constants-bool:
+
+Boolean Constants
+-----------------
+
+There are two constants used to represent truth and falsity: ``true``,
+and ``false``.
+
+.. _lang-constants-false:
+
+false
+^^^^^
+
+``false`` is the false ``bool`` value. An integer which is 0 evaluates
+to ``false`` as a boolean.
+
+.. _lang-constants-true:
+
+true
+^^^^
+
+``true`` is the true ``bool`` value. As an integer, ``true`` is often
+said to be 1. This is correct in the sense that ``true`` evaluates to
+1 as an integer. However, any integer which is *non-zero* is ``true``
+as a :ref:`bool <lang-booleanvariables>`. So -1, 2 and -200 are all
+"true", in the sense that these numbers are treated the same as
+``true`` in a boolean context.
+
+Note that the ``true`` and ``false`` constants are typed in lowercase;
+unlike e.g. ``HIGH``, ``LOW``, ``INPUT``, and ``OUTPUT`` (which are
+described below).
+
+.. _lang-pin-levels:
+
+Pin Levels: HIGH and LOW
+------------------------
+
+When reading or writing to a digital pin there are only two possible
+values a pin can be set to: ``HIGH`` and ``LOW``.
+
+.. _lang-constants-high:
+
+HIGH
+^^^^
+
+The meaning of ``HIGH`` (in reference to a pin) is somewhat different
+depending on whether the pin is set to ``INPUT`` or ``OUTPUT``. When a
+pin is configured as an ``INPUT`` (using :ref:`pinMode()
+<lang-pinmode>`), and read with :ref:`digitalRead()
+<lang-digitalread>`, the microcontroller will report ``HIGH`` if a
+voltage of 3 volts or more is present at the pin.
+
+When a pin is configured to ``OUTPUT`` with ``pinMode()``, and set to
+``HIGH`` with :ref:`digitalWrite() <lang-digitalwrite>`, the pin is at
+3.3 volts. In this state it can *source* current, e.g. light an LED
+that is connected through a series resistor to ground, or to another
+pin configured as an output and set to ``LOW``.
+
+.. _lang-constants-low:
+
+LOW
+^^^
+
+The meaning of ``LOW`` also has a different meaning depending on
+whether a pin is set to ``INPUT`` or ``OUTPUT``. When a pin is
+configured as an ``INPUT`` with :ref:`pinMode() <lang-pinmode>`, and
+read with :ref:`digitalRead() <lang-digitalread>`, the microcontroller
+will report ``LOW`` if a voltage of 2 volts or less is present at the
+pin.
+
+When a pin is configured to ``OUTPUT`` with ``pinMode()``, and set to
+``LOW`` with :ref:`digitalWrite() <lang-digitalwrite>`, the
+microcontroller will attempt to keep that pin's voltage at 0 V. In this
+state it can *sink* current, e.g. light an LED that is connected
+through a series resistor to +3.3 V, or to another pin configured as an
+output, and set to ``HIGH``.
+
+Pin Modes
+---------
+
+Digital pins can be used in a variety of modes. The basic modes,
+``INPUT`` and ``OUTPUT``, have been introduced above. Changing a pin
+from ``INPUT`` TO ``OUTPUT`` with :ref:`pinMode() <lang-pinmode>`
+drastically changes the electrical behavior of the pin.
+
+This section describes the basic digital pin modes (``INPUT`` and
+``OUTPUT``) only. For a detailed description of all possible pin
+modes, see the :ref:`pinMode() <lang-pinmode>` reference page.
+
+.. _lang-constants-input:
+
+INPUT
+^^^^^
+
+Pins configured as ``INPUT`` are said to be in a *high-impedance
+state*. One way of explaining this is that pins configured as
+``INPUT`` make very few demans on circuit that they are connected
+to. This makes them useful for reading a sensor, but not powering an
+LED.
+
+.. _lang-constants-output:
+
+OUTPUT
+^^^^^^
+
+Pins configured as ``OUTPUT`` with :ref:`pinMode() <lang-pinmode>` are
+said to be in a low-impedance state. This means that they can provide
+a substantial amount of current to other circuits. Pins can source
+(provide positive current) or sink (provide negative current) up to 50
+mA (milliamps) of current to other devices/circuits. This makes them
+useful for powering LEDs, but useless for reading sensors.
+
+Pins configured as outputs can also be damaged or destroyed if short
+circuited to either ground or power supplies. The amount of current
+provided by a pin is also not enough to power most relays or motors,
+and some interface circuitry will be required.
+
+.. _lang-constants-integers:
+
+Integer Constants
+-----------------
+
+Integer constants are numbers used directly in a sketch, like
+``123``. By default, an integer constant is treated as a (signed)
+:ref:`int <lang-int>`, but you can change this with the U and L
+modifiers (see :ref:`below <lang-constants-integers-u-l>`). You can
+specify negative numbers by putting a minus sign in front, like
+``-123``.
+
+Normally, integer constants are treated as base 10 (decimal) integers,
+but special notation (formatters) may be used to enter numbers in
+other bases. These are explained in the following table:
+
+.. list-table::
+ :header-rows: 1
+
+ * - Base
+ - Example
+ - Formatter
+ - Comment
+
+ * - 10 (decimal)
+ - ``123``
+ - None
+ -
+
+ * - 2 (binary)
+ - ``0b1111011``
+ - Leading "0b"
+ - GCC extension; not standard C++
+
+ * - 8 (octal)
+ - ``0173``
+ - Leading "0"
+ - Characters 0-7 valid
+
+ * - 16 (hexadecimal)
+ - ``0x7B``
+ - Leading "0x"
+ - Characters 0-9, A-F (or a-f) valid
+
+Binary constants (like ``B1111011``) for values between 0 and 255 are
+supported for compatibility with Arduino only. You shouldn't use them
+in new programs.
+
+.. _lang-constants-integers-dec:
+
+**Decimal** is base 10. This is the common number system we learn in
+school. Integer literals without other prefixes are assumed to be in
+decimal format.
+
+For example, the decimal literal ``101`` is one hundred and one: 1×10\
+:sup:`2` + 0×10\ :sup:`1` + 1×10\ :sup:`0` = 101.
+
+.. _lang-constants-integers-bin:
+
+**Binary** is base two. Only characters 0 and 1 are valid. Binary
+literals are indicated by the prefix ``0b``.
+
+For example, the binary literal ``0b101`` is five: 1×2\ :sup:`2` +
+0×2\ :sup:`1` + 1×2\ :sup:`0` = 5.
+
+.. _lang-constants-integers-oct:
+
+**Octal** is base eight. Only characters 0 through 7 are valid. Octal
+literals are indicated by the prefix ``0``.
+
+For example, the octal literal ``0101`` is sixty five: 1×8\ :sup:`2` +
+0×8\ :sup:`1` + 1×8\ :sup:`0` = 65.
+
+.. warning:: Bugs sometimes result by (unintentionally) including a
+ leading "0" before an integer literal, which makes the compiler
+ treat it as an octal number.
+
+.. _lang-constants-integers-hex:
+
+**Hexadecimal** (or "hex") is base sixteen. Valid characters are 0
+through 9 and letters A through F; A has the value 10, B is 11, up to
+F, which is 15. Hex values are indicated by the prefix ``0x``. A-F
+can be typed in upper or lower case (a-f).
+
+For example, the hexadecimal constant ``0x101`` is two hundred fifty
+seven: 1×16\ :sup:`2` + 0×16\ :sup:`1` + 1×16\ :sup:`0` = 257.
+
+The hexadecimal constant ``0xCF2`` is three thousand, three hundred
+fourteen: 12×16\ :sup:`2` + 15×16\ :sup:`1` + 2×16\ :sup:`0` = 3314.
+
+(Remember that in hex, ``A`` means 10, and counting up, ``B``\ =11, so
+``C``\ =12 and ``F``\ =15).
+
+.. _lang-constants-integers-u-l:
+
+U and L Suffixes
+^^^^^^^^^^^^^^^^
+
+By default, an integer constant is treated as an :ref:`int <lang-int>`
+(and must be in the int type's :ref:`range limits
+<lang-int-overflow>`). To specify an integer constant with another
+data type, follow it with:
+
+- a ``u`` or ``U`` to interpret the constant as an unsigned value.
+ For example, ``33U`` is an :ref:`unsigned int <lang-unsignedint>`.
+
+- an ``l`` or ``L`` to interpret the constant as a long value. For
+ example, ``100000L`` is a :ref:`long <lang-long>`. On the Maple,
+ ``long`` is just a synonym for ``int``.
+
+- a ``ul`` or ``UL`` to do both. For example, ``32767UL`` is an
+ :ref:`unsigned long <lang-unsignedlong>`. On the Maple, ``unsigned
+ long`` is just a synonym for ``unsigned int``.
+
+- an ``ll`` or ``LL`` to interpret the constant as a :ref:`long long
+ <lang-longlong>` value.
+
+- a ``ull`` or ``ULL`` to interpret the constant as an :ref:`unsigned
+ long long <lang-unsignedlonglong>`.
+
+.. _lang-constants-fp:
+
+Floating-Point Constants
+------------------------
+
+A floating point constant is any number which includes a decimal
+point. For instance, ``3.0`` is a floating-point constant for the
+number 3. By default, a floating-point constant is a :ref:`double
+<lang-double>`. In order for the constant to be interpreted as a
+:ref:`float <lang-float>`, you can write ``f`` directly after it. For
+example, ``3.0f`` is a floating-point constant with type ``float``.
+
+Floating point constants can also be expressed in a variety of
+scientific notation. ``E`` and ``e`` are both accepted as valid
+exponent indicators. Some examples are given in the following table:
+
+
+.. list-table::
+ :header-rows: 1
+
+ * - Floating-point constant
+ - Evaluates to
+ - Alternate expression
+
+ * - ``10.0``
+ - 10
+ -
+
+ * - ``2.34E5``
+ - 2.34×10\ :sup:`5`
+ - ``234000.0``
+
+ * - ``67e-12``
+ - 67.0×10\ :sup:`-12`
+ - ``0.000000000067``
+
+.. _lang-constants-board:
+
+Board-Specific Constants
+------------------------
+
+There are several :ref:`board-specific constants <lang-board-values>`
+whose value depends on which LeafLabs board you have. If you use
+them, it will help make sure that your code will work well on all
+LeafLabs boards, not just the one you have. This will make it easier
+to share your code with others.
+
+For example, the pin number connected to the board's built-in LED is
+different on the different boards, but the board-specific constant
+:ref:`BOARD_LED_PIN <lang-board-values-led>` will always be the
+correct value for each board.
+
+See Also
+--------
+
+- :ref:`pinMode() <lang-pinmode>`
+- :ref:`Boolean Variables <lang-booleanvariables>`
+- :ref:`#define <lang-define>`
+- :ref:`int <lang-int>`
+- :ref:`unsigned int <lang-unsignedint>`
+- :ref:`long <lang-long>`
+- :ref:`unsigned long <lang-unsignedlong>`
+- :ref:`long long <lang-longlong>`
+- :ref:`unsigned long long <lang-unsignedlonglong>`
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+- :ref:`Board-Specific Values <lang-board-values>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/constrain.rst b/docs/source/lang/api/constrain.rst
new file mode 100644
index 0000000..28af1e3
--- /dev/null
+++ b/docs/source/lang/api/constrain.rst
@@ -0,0 +1,68 @@
+.. highlight:: cpp
+
+.. _lang-constrain:
+
+constrain()
+===========
+
+(Macro) Constrains a number to be within a range.
+
+Syntax
+------
+
+::
+
+ constrain(x, a, b)
+
+
+Parameters
+----------
+
+**x**: the number to constrain
+
+**a**: the lower end of the range
+
+**b**: the upper end of the range
+
+Returns
+-------
+
+**x**: if **x** is between **a** and **b**
+
+**a**: if **x** is less than **a**
+
+**b**: if **x** is greater than **b**
+
+Example
+-------
+
+::
+
+ // limits range of sensor values to between 10 and 150:
+ sensVal = constrain(sensVal, 10, 150);
+
+
+Warning
+-------
+
+Because of the way ``constrain()`` is implemented, avoid using other
+functions or causing side effects inside the parentheses, as it may
+lead to incorrect results::
+
+ constrain(x,a++,b); // avoid this - yields incorrect results
+
+ constrain(x,a,b); // use this instead-
+ a++; // keep other math outside constrain()
+
+Arduino Compatibility
+---------------------
+
+Maple's implementation of ``constrain()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`min() <lang-min>`
+- :ref:`max() <lang-max>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/cos.rst b/docs/source/lang/api/cos.rst
new file mode 100644
index 0000000..c340f09
--- /dev/null
+++ b/docs/source/lang/api/cos.rst
@@ -0,0 +1,30 @@
+.. _lang-cos:
+
+cos()
+=====
+
+Calculates the cosine of an angle.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: cos
+
+Arduino Compatibility
+---------------------
+
+The Maple ``cos()`` implementation is compatible with Arduino.
+
+Note that the Maple implementation comes from `newlib
+<http://sourceware.org/newlib/>`_\ , while Arduino's is that of
+`avr-libc <http://avr-libc.nongnu.org/>`_\ .
+
+See Also
+--------
+
+- :ref:`sin() <lang-sin>`
+- :ref:`tan() <lang-tan>`
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/delay.rst b/docs/source/lang/api/delay.rst
new file mode 100644
index 0000000..30bd436
--- /dev/null
+++ b/docs/source/lang/api/delay.rst
@@ -0,0 +1,69 @@
+.. highlight:: cpp
+
+.. _lang-delay:
+
+delay()
+=======
+
+Pauses the program for at least a given number of milliseconds. (There
+are 1000 milliseconds in a second.)
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: delay
+
+
+Discussion
+----------
+
+While it is easy to create a blinking LED with the ``delay()``
+function, and many sketches use short delays for such tasks as switch
+debouncing, the use of ``delay()`` in a sketch has significant
+drawbacks. No other reading of sensors, mathematical calculations, or
+pin manipulation can go on during the delay function, so in effect, it
+brings most other activity to a halt. For alternative approaches to
+controlling timing see the :ref:`millis() <lang-millis>` function
+and the "Blink Without Delay" sketch cited :ref:`below
+<lang-delay-seealso>`\ . More knowledgeable programmers usually
+avoid the use of ``delay()`` for timing of events longer than tens of
+milliseconds, unless the sketch is very simple.
+
+Certain things *do* go on while the ``delay()`` function is
+controlling the STM32 chip, however, because the delay function does
+not disable interrupts. Serial communication that appears at the RX
+pin is recorded, PWM (see :ref:`pwmWrite() <lang-pwmwrite>`\ ) values
+and pin states are maintained, and :ref:`interrupts
+<lang-attachinterrupt>` will work as they should.
+
+
+Example
+-------
+
+::
+
+ void setup() {
+ // set up the built-in LED pin for output:
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ }
+
+ void loop() {
+ digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on
+ delay(1000); // waits for a second
+ digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off
+ delay(1000); // waits for a second
+ }
+
+.. _lang-delay-seealso:
+
+See Also
+--------
+
+- :ref:`millis() <lang-millis>`
+- :ref:`micros() <lang-micros>`
+- :ref:`delayMicroseconds() <lang-delayMicroseconds>`
+- (Arduino) `Blink Without Delay
+ <http://arduino.cc/en/Tutorial/BlinkWithoutDelay>`_ example (works
+ unmodified on Maple)
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/delaymicroseconds.rst b/docs/source/lang/api/delaymicroseconds.rst
new file mode 100644
index 0000000..7078660
--- /dev/null
+++ b/docs/source/lang/api/delaymicroseconds.rst
@@ -0,0 +1,62 @@
+.. highlight:: cpp
+
+.. _lang-delaymicroseconds:
+
+delayMicroseconds()
+===================
+
+Pauses the program for the amount of time (in microseconds)
+specified as parameter. There are a thousand microseconds in a
+millisecond, and a million microseconds in a second.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: delayMicroseconds
+
+
+Example
+-------
+
+The following example configures pin number 8 to work as an output
+pin, and sends a train of pulses with a period of roughly 100
+microseconds::
+
+ int outPin = 8;
+
+ void setup() {
+ pinMode(outPin, OUTPUT); // sets the digital pin as output
+ }
+
+ void loop() {
+ digitalWrite(outPin, HIGH); // sets the pin on
+ delayMicroseconds(50); // pauses for 50 microseconds
+ digitalWrite(outPin, LOW); // sets the pin off
+ delayMicroseconds(50); // pauses for 50 microseconds
+ }
+
+
+Caveats and Known Issues
+------------------------
+
+The longest time ``delayMicroseconds()`` can delay is bounded by its
+argument type and the STM32 clock rate to be (2^32 - 1) / 12
+microseconds, or less than 6 minutes. For longer pauses, use of
+:ref:`lang-delay` is possible.
+
+Arduino Compatibility
+---------------------
+
+While we have made every effort we could to ensure that the timing of
+``delayMicroseconds()`` is as accurate as possible, we cannot
+guarantee it will behave as the Arduino implementation down to the
+microsecond, especially for smaller values of ``us``.
+
+See Also
+--------
+
+- :ref:`millis <lang-millis>`
+- :ref:`micros <lang-micros>`
+- :ref:`delay <lang-delay>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/detachinterrupt.rst b/docs/source/lang/api/detachinterrupt.rst
new file mode 100644
index 0000000..6eb8e53
--- /dev/null
+++ b/docs/source/lang/api/detachinterrupt.rst
@@ -0,0 +1,43 @@
+.. _lang-detachinterrupt:
+
+detachInterrupt()
+=================
+
+Used to disable an interrupt specified with
+:ref:`lang-attachinterrupt`\ .
+
+Library Documentation
+---------------------
+
+.. FIXME [Breathe] once we can get the correct detachInterrupt(),
+.. replace with doxygenfunction.
+
+.. cpp:function:: void detachInterrupt(uint8 pin)
+
+ Disable any registered external interrupt on the given pin.
+
+ *Parameters*
+
+ - ``pin`` Maple pin number
+
+Arduino Compatibility
+---------------------
+
+There is one important difference between the Maple version of
+detachInterrupt and the Arduino version. On the Maple, the argument
+to ``detachInterrupt()`` is the *pin* on which the interrupt is
+attached, while on the Arduino, the argument is the *interrupt
+number*, which is different from the pin the interrupt is enabled on.
+
+If you're calling this function, you've already called
+:ref:`lang-attachinterrupt` to set up your interrupt handler, so
+just call ``detachInterrupt()`` with the same pin argument you gave to
+``attachInterrupt()``.
+
+See Also
+--------
+
+- :ref:`attachInterrupt() <lang-attachInterrupt>`
+- :ref:`external-interrupts`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/digitalread.rst b/docs/source/lang/api/digitalread.rst
new file mode 100644
index 0000000..03ccd7f
--- /dev/null
+++ b/docs/source/lang/api/digitalread.rst
@@ -0,0 +1,51 @@
+.. highlight:: cpp
+
+.. _lang-digitalread:
+
+digitalRead()
+=============
+
+Reads the value from a specified digital pin, either :ref:`HIGH
+<lang-constants-high>` or :ref:`LOW <lang-constants-low>`.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: digitalRead
+
+Discussion
+----------
+
+If the pin isn't connected to anything, ``digitalRead()`` can return
+either HIGH or LOW (and this will change in a way that seems random).
+
+Example
+-------
+
+The following example turns the LED on or off when the button is pressed::
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ pinMode(BOARD_BUTTON_PIN, INPUT);
+ }
+
+ void loop() {
+ int val = digitalRead(BOARD_BUTTON_PIN); // reads the input pin
+ togglePin(BOARD_LED_PIN);
+ }
+
+Arduino Compatibility
+---------------------
+
+The Maple version of ``digitalRead()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>`
+- :ref:`lang-isButtonPressed`
+- :ref:`lang-pinmode`
+- :ref:`lang-digitalWrite`
+- :ref:`lang-togglepin`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/digitalwrite.rst b/docs/source/lang/api/digitalwrite.rst
new file mode 100644
index 0000000..bae8db9
--- /dev/null
+++ b/docs/source/lang/api/digitalwrite.rst
@@ -0,0 +1,56 @@
+.. highlight:: cpp
+
+.. _lang-digitalwrite:
+
+digitalWrite()
+==============
+
+Write a :ref:`HIGH <lang-constants-high>` or a :ref:`LOW
+<lang-constants-low>` value to a pin configured as :ref:`OUTPUT
+<lang-constants-output>`.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: digitalWrite
+
+Discussion
+----------
+
+If the pin has been configured as an ``OUTPUT`` with :ref:`pinMode()
+<lang-pinmode>` its voltage will be set to the corresponding value:
+3.3V for ``HIGH``, and 0V (ground) for ``LOW``.
+
+Because it is soldered to an LED and resistor in series, your board's
+:ref:`BOARD_LED_PIN <lang-board-values-led>` will respond slightly
+more slowly as an output than the other pins.
+
+Example
+-------
+
+The following example sets the built-in LED pin to ``HIGH``, makes a
+one-second-long delay, sets the pin back to ``LOW``, and delays again,
+causing a blinking pattern (you could also use
+:ref:`lang-toggleled`)::
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT); // sets the digital pin as output
+ }
+
+ void loop() {
+ digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on
+ delay(1000); // waits for a second
+ digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off
+ delay(1000); // waits for a second
+ }
+
+See Also
+--------
+
+- :ref:`pinMode <lang-pinmode>`
+- :ref:`digitalRead <lang-digitalread>`
+- :ref:`BOARD_LED_PIN <lang-board-values-led>`
+- :ref:`lang-toggleled`
+- :ref:`lang-togglepin`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/disabledebugports.rst b/docs/source/lang/api/disabledebugports.rst
new file mode 100644
index 0000000..283cdbf
--- /dev/null
+++ b/docs/source/lang/api/disabledebugports.rst
@@ -0,0 +1,33 @@
+.. highlight:: cpp
+
+.. _lang-disabledebugports:
+
+disableDebugPorts()
+===================
+
+Used to disable the JTAG and Serial Wire debugging ports.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: disableDebugPorts
+
+Example
+-------
+
+ ::
+
+ void setup() {
+ disableDebugPorts();
+ }
+
+ void loop() {
+ // Now you can use the debug port pins (the pins on the JTAG
+ // header on the Maple) as ordinary pins.
+ }
+
+See Also
+--------
+
+- :ref:`lang-enabledebugports`
+- :ref:`Important erratum on Maple pin 43 <maple-nrst-pb4>`
diff --git a/docs/source/lang/api/enabledebugports.rst b/docs/source/lang/api/enabledebugports.rst
new file mode 100644
index 0000000..bee2b0a
--- /dev/null
+++ b/docs/source/lang/api/enabledebugports.rst
@@ -0,0 +1,31 @@
+.. highlight:: cpp
+
+.. _lang-enabledebugports:
+
+enableDebugPorts()
+==================
+
+Used to enable the JTAG and Serial Wire debugging ports.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: enableDebugPorts
+
+Example
+-------
+
+ ::
+
+ void setup() {
+ enableDebugPorts();
+ // Now you can debug using JTAG and SW-Debug
+ }
+
+ void loop() {
+ }
+
+See Also
+--------
+
+* :ref:`lang-disabledebugports`
diff --git a/docs/source/lang/api/hardwarespi.rst b/docs/source/lang/api/hardwarespi.rst
new file mode 100644
index 0000000..a44a65f
--- /dev/null
+++ b/docs/source/lang/api/hardwarespi.rst
@@ -0,0 +1,170 @@
+.. highlight:: cpp
+
+.. _lang-hardwarespi:
+
+HardwareSPI
+===========
+
+This page describes how to use the built-in SPI ports. It does not
+describe the SPI protocol itself. For more information about SPI, see
+the :ref:`SPI reference <spi>`.
+
+.. contents:: Contents
+ :local:
+
+Getting Started
+---------------
+
+In order to get started, you'll first need to define a ``HardwareSPI``
+variable, which you'll use to control the SPI port. Do this by
+putting the line "``HardwareSPI spi(number);``" with your variables,
+where ``number`` is the SPI port's number.
+
+Here's an example (we'll fill in :ref:`setup() <lang-setup>` and
+:ref:`loop() <lang-loop>` later)::
+
+ // Use SPI port number 1
+ HardwareSPI spi(1);
+
+ void setup() {
+ // Your setup code
+ }
+
+ void loop() {
+ // Do stuff with SPI
+ }
+
+Turning the SPI Port On
+-----------------------
+
+Now it's time to turn your SPI port on. Do this with the ``begin()``
+function (an example is given below).
+
+.. FIXME [Breathe] Output doesn't include the class; fix & submit pull req
+
+.. doxygenfunction:: HardwareSPI::begin
+
+.. note:: If you are using SPI port 3 (on a board that supports it;
+ not all do); you'll need to call :ref:`lang-disabledebugports`
+ before calling ``begin()``.
+
+The speed at which the SPI port communicates is configured using a
+``SPIFrequency`` value:
+
+.. FIXME [0.1.0] Breathe's enum output is enormous; shrink & submit pull req
+
+.. doxygenenum:: SPIFrequency
+
+.. note:: Due to hardware issues, you can't use the frequency
+ ``SPI_140_625KHz`` with SPI port 1.
+
+The "mode" value determines the clock phase and polarity, like so:
+
+.. doxygenenum:: spi_mode
+
+You'll need to determine the correct values for ``frequency``,
+``bitOrder``, and ``mode`` yourself, by consulting the datasheet for
+the device you're communicating with. Continuing our example from
+before, we'll add a call to ``begin()`` to our ``setup()``::
+
+ // Use SPI port number 1
+ HardwareSPI spi(1);
+
+ void setup() {
+ // Turn on the SPI port
+ spi.begin(SPI_18MHZ, MSBFIRST, 0);
+ }
+
+ void loop() {
+ // Do stuff with SPI
+ }
+
+If you call ``begin()`` with no arguments (as in "``spi.begin();``"),
+it's the same as if you wrote "``spi.begin(SPI_1_125MHZ, MSBFIRST,
+0);``".
+
+Communicating Over SPI
+----------------------
+
+Now that you've got your SPI port set up, it's time to start
+communicating. You can send data using ``HardwareSPI::write()``,
+receive data using ``HardwareSPI::read()``, and do both using
+``HardwareSPI::transfer()``.
+
+.. cpp:function:: void HardwareSPI::write(byte data)
+
+ Send a single byte of data.
+
+ **Parameters**:
+
+ - ``data``: Byte to send
+
+.. cpp:function:: byte HardwareSPI::read()
+
+ Get the next available, unread byte. If there aren't any unread
+ bytes, this function will wait until one is received.
+
+.. cpp:function:: byte HardwareSPI::transfer(byte data)
+
+ Send a byte, then return the next byte received.
+
+ **Parameters:**
+
+ - ``data``: Byte to send
+
+ **Returns:** Next unread byte
+
+Continuing our example from before, let's send a number over SPI and
+print out whatever we get back over :ref:`lang-serialusb`::
+
+ // Use SPI port number 1
+ HardwareSPI spi(1);
+
+ void setup() {
+ // Turn on the SPI port
+ spi.begin(SPI_18MHZ, MSBFIRST, 0);
+ }
+
+ void loop() {
+ // Send 245 over SPI, and wait for a response.
+ spi.write(245);
+ byte response = spi.read();
+ // Print out the response received.
+ SerialUSB.print("response: ");
+ SerialUSB.println(response, DEC);
+ }
+
+HardwareSPI Class Reference
+---------------------------
+
+There are a number of other things you can accomplish with your
+``spi`` object. A full function listing follows.
+
+.. doxygenclass:: HardwareSPI
+ :members: HardwareSPI, begin, beginSlave, end, read, write, transfer
+
+Deprecated Functions
+--------------------
+
+The following functions are defined for now, but they have been
+deprecated, and will be removed in a future Maple IDE release. You
+shouldn't use them in new programs, and you should change any of your
+programs which do use them to the up-to-date functions discussed
+above.
+
+.. cpp:function:: uint8 HardwareSPI::send(uint8 *data, uint32 length)
+
+ Writes ``data`` into the port buffer to be transmitted as soon as
+ possible, where ``length`` is the number of bytes to send from
+ ``data``. Returns the last byte shifted back from slave.
+
+.. cpp:function:: uint8 HardwareSPI::send(uint8 data)
+
+ Writes the single byte ``data`` into the port buffer to be
+ transmitted as soon as possible. Returns the data byte shifted
+ back from the slave.
+
+.. cpp:function:: uint8 HardwareSPI::recv()
+
+ Reads a byte from the peripheral. Returns the next byte in the
+ buffer.
diff --git a/docs/source/lang/api/hardwaretimer.rst b/docs/source/lang/api/hardwaretimer.rst
new file mode 100644
index 0000000..b919e52
--- /dev/null
+++ b/docs/source/lang/api/hardwaretimer.rst
@@ -0,0 +1,345 @@
+.. highlight:: cpp
+
+.. _lang-hardwaretimer:
+
+HardwareTimer
+=============
+
+This page describes how to control the built-in timers. It does not
+describe how the timers work on your board. For more information on
+that, the :ref:`timers reference <timers>`.
+
+.. warning:: The timer interface is still taking shape, and is
+ expected to change significantly between releases. Because of
+ that, the functionality described in this page shouldn't be
+ considered stable.
+
+ If you want a timer API that will be consistent between releases of
+ the Maple IDE, your best bet for now is to use the low-level
+ support in :ref:`libmaple-timer`.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-hardwaretimer-getting-started:
+
+Getting Started
+---------------
+
+You'll first need to define a ``HardwareTimer`` variable, which you'll
+use to control the timer. Do this by putting the line
+"``HardwareTimer timer(number);``" with your variables, where
+``number`` is the timer's number.
+
+Here's an example (we'll fill in :ref:`setup() <lang-setup>` and
+:ref:`loop() <lang-loop>` later)::
+
+ // Use timer 1
+ HardwareTimer timer(1);
+
+ void setup() {
+ // Your setup code
+ }
+
+ void loop() {
+ // ...
+ }
+
+Configuring the Prescaler and Overflow
+--------------------------------------
+
+After defining your ``timer`` variable, you'll probably want to
+configure how fast your timer's counter changes (using the prescaler)
+and when it gets reset to zero (using the overflow value). You can do
+that with the ``setPrescaleFactor()`` and ``setOverflow()`` functions.
+
+.. _lang-hardwaretimer-setprescalefactor:
+
+.. doxygenfunction:: HardwareTimer::setPrescaleFactor
+ :no-link:
+
+.. _lang-hardwaretimer-setoverflow:
+
+.. doxygenfunction:: HardwareTimer::setOverflow
+ :no-link:
+
+For example::
+
+ // Use timer 1
+ HardwareTimer timer(1);
+
+ void setup() {
+ timer.setPrescaleFactor(5);
+ timer.setOverflow(255);
+ }
+
+ void loop() {
+ // ...
+ }
+
+You may also find the ``setPeriod()`` function useful:
+
+.. _lang-hardwaretimer-setperiod:
+
+.. doxygenfunction:: HardwareTimer::setPeriod
+ :no-link:
+
+For example::
+
+ // Use timer 1
+ HardwareTimer timer(1);
+
+ void setup() {
+ // Have the timer repeat every 20 milliseconds
+ int microseconds_per_millisecond = 1000;
+ timer.setPeriod(20 * microseconds_per_millisecond);
+ }
+
+ void loop() {
+ // ...
+ }
+
+.. _lang-hardwaretimer-interrupts:
+
+Using Timer Interrupts
+----------------------
+
+.. TODO [0.2.0] Improve the interrupts section, here or in timers.rst
+
+In order to use timer interrupts, we recommend the following sequence:
+
+* Pause the timer.
+* Configure the prescaler and overflow.
+* Pick a timer channel to handle the interrupt and set the channel's
+ :ref:`mode <lang-hardwaretimer-timermode>` to ``TIMER_OUTPUT_COMPARE``.
+* Set the channel compare value appropriately (this controls what counter value,
+ from 0 to overflow - 1). If you just want to make the interrupt fire once
+ every time the timer overflows, and you don't care what the timer count is,
+ the channel compare value can just be 1.
+* Attach an interrupt handler to the channel.
+* Refresh the timer.
+* Resume the timer.
+
+Here are two complete examples.
+
+**LED blink**: This example blinks the built-in LED without doing
+anything in ``loop()``. ::
+
+ #define LED_RATE 500000 // in microseconds; should give 0.5Hz toggles
+
+ // We'll use timer 2
+ HardwareTimer timer(2);
+
+ void setup() {
+ // Set up the LED to blink
+ pinMode(BOARD_LED_PIN, OUTPUT);
+
+ // Pause the timer while we're configuring it
+ timer.pause();
+
+ // Set up period
+ timer.setPeriod(LED_RATE); // in microseconds
+
+ // Set up an interrupt on channel 1
+ timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
+ timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
+ timer.attachInterrupt(1, handler_led);
+
+ // Refresh the timer's count, prescale, and overflow
+ timer.refresh();
+
+ // Start the timer counting
+ timer.resume();
+ }
+
+ void loop() {
+ // Nothing! It's all in the handler_led() interrupt:
+ }
+
+ void handler_led(void) {
+ toggleLED();
+ }
+
+**Racing Counters**: This example shows how to use multiple timers at
+the same time. ::
+
+ int count3 = 0;
+ int count4 = 0;
+
+ // We'll use timers 3 and 4
+ HardwareTimer timer3(3);
+ HardwareTimer timer4(4);
+
+ void setup() {
+ // Set up the button for input
+ pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP);
+
+ // Set up timers to add 1 to their counts each time
+ // their interrupts fire.
+ timer3.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
+ timer4.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
+ timer3.pause();
+ timer4.pause();
+ timer3.setCount(0);
+ timer4.setCount(0);
+ timer3.setOverflow(30000);
+ timer4.setOverflow(30000);
+ timer3.setCompare(TIMER_CH1, 1000); // somewhere in the middle
+ timer4.setCompare(TIMER_CH1, 1000);
+ timer3.attachCompare1Interrupt(handler3);
+ timer4.attachCompare1Interrupt(handler4);
+ timer3.refresh();
+ timer4.refresh();
+ timer3.resume();
+ timer4.resume();
+ }
+
+ void loop() {
+ // Display the running counts
+ SerialUSB.print("Count 3: ");
+ SerialUSB.print(count3);
+ SerialUSB.print("\t\tCount 4: ");
+ SerialUSB.println(count4);
+
+ // While the button is held down, pause timer 4
+ for (int i = 0; i < 1000; i++) {
+ if (digitalRead(BOARD_BUTTON_PIN)) {
+ timer4.pause();
+ } else {
+ timer4.resume();
+ }
+ delay(1);
+ }
+ }
+
+ void handler3(void) {
+ count3++;
+ }
+
+ void handler4(void) {
+ count4++;
+ }
+
+``HardwareTimer`` Class Reference
+---------------------------------
+
+This section gives a full listing of the capabilities of a
+``HardwareTimer``.
+
+.. doxygenclass:: HardwareTimer
+ :members: HardwareTimer, pause, resume, getPrescaleFactor, setPrescaleFactor, getOverflow, setOverflow, getCount, setCount, setPeriod, setMode, getCompare, setCompare, attachInterrupt, detachInterrupt, refresh
+
+.. _lang-hardwaretimer-timermode:
+
+.. doxygenenum:: timer_mode
+
+Deprecated Functionality
+------------------------
+
+The following functionality exists for now, but it has been
+deprecated, and will be removed in a future Maple IDE release. You
+shouldn't use it in new programs, and you should change any of your
+programs which do use them to use the up-to-date features described
+above.
+
+The ``TimerMode`` type from previous releases has been renamed
+``timer_mode``. The mode ``TIMER_OUTPUTCOMPARE`` is still present,
+but will be removed in a future release. Use ``TIMER_OUTPUT_COMPARE``
+instead.
+
+.. cpp:function:: void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler)
+
+ Use ``attachInterrupt(1, handler)`` instead.
+
+.. cpp:function:: void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler)
+
+ Use ``attachInterrupt(2, handler)`` instead.
+
+.. cpp:function:: void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler)
+
+ Use ``attachInterrupt(3, handler)`` instead.
+
+.. cpp:function:: void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler)
+
+ Use ``attachInterrupt(4, handler)`` instead.
+
+.. _lang-hardwaretimer-setchannelmode:
+
+.. cpp:function:: void HardwareTimer::setChannelMode(int channel, timer_mode mode)
+
+ Use ``setMode(channel, mode)`` instead.
+
+.. cpp:function:: void HardwareTimer::setChannel1Mode(timer_mode mode)
+
+ Use ``setMode(1, mode)`` instead.
+
+.. cpp:function:: void HardwareTimer::setChannel2Mode(timer_mode mode)
+
+ Use ``setMode(2, mode)`` instead.
+
+.. cpp:function:: void HardwareTimer::setChannel3Mode(timer_mode mode)
+
+ Use ``setMode(3, mode)`` instead.
+
+.. cpp:function:: void HardwareTimer::setChannel4Mode(timer_mode mode)
+
+ Use ``setMode(4, mode)`` instead.
+
+.. cpp:function:: uint16 HardwareTimer::getCompare1()
+
+ Use ``getCompare(1, mode)`` instead.
+
+.. cpp:function:: uint16 HardwareTimer::getCompare2()
+
+ Use ``getCompare(2, mode)`` instead.
+
+.. cpp:function:: uint16 HardwareTimer::getCompare3()
+
+ Use ``getCompare(3, mode)`` instead.
+
+.. cpp:function:: uint16 HardwareTimer::getCompare4()
+
+ Use ``getCompare(4, mode)`` instead.
+
+.. cpp:function:: void HardwareTimer::setCompare1(uint16 compare)
+
+ Use ``setCompare(1, compare)`` instead.
+
+.. cpp:function:: void HardwareTimer::setCompare2(uint16 compare)
+
+ Use ``setCompare(2, compare)`` instead.
+
+.. cpp:function:: void HardwareTimer::setCompare3(uint16 compare)
+
+ Use ``setCompare(3, compare)`` instead.
+
+.. cpp:function:: void HardwareTimer::setCompare4(uint16 compare)
+
+ Use ``setCompare(4, compare)`` instead.
+
+.. cpp:function:: void HardwareTimer::detachCompare1Interrupt()
+
+ Use ``detachInterrupt(1)`` instead.
+
+.. cpp:function:: void HardwareTimer::detachCompare2Interrupt()
+
+ Use ``detachInterrupt(2)`` instead.
+
+.. cpp:function:: void HardwareTimer::detachCompare3Interrupt()
+
+ Use ``detachInterrupt(3)`` instead.
+
+.. cpp:function:: void HardwareTimer::detachCompare4Interrupt()
+
+ Use ``detachInterrupt(4)`` instead.
+
+.. cpp:function:: void HardwareTimer::generateUpdate()
+
+ Use ``refresh()`` instead.
+
+In previous releases, to interact with a particular timers, you would
+use one of the predefined ``HardwareTimer`` instances ``Timer1``,
+``Timer2``, ``Timer3``, and ``Timer4``. These are still available for
+now, but they are also deprecated, and will be removed in a future
+release. As detailed in :ref:`lang-hardwaretimer-getting-started`,
+you should define your own ``HardwareTimer`` variables.
diff --git a/docs/source/lang/api/highbyte.rst b/docs/source/lang/api/highbyte.rst
new file mode 100644
index 0000000..4cb6f9b
--- /dev/null
+++ b/docs/source/lang/api/highbyte.rst
@@ -0,0 +1,55 @@
+.. highlight:: cpp
+
+.. _lang-highbyte:
+
+highByte()
+==========
+
+(Macro) Extracts the second lowest byte of an integral data type.
+
+.. warning:: This macro is provided for compatibility with Arduino
+ only. It returns the second-least significant byte in an integral
+ value. It makes sense to call this the "high" byte on a 16-bit
+ ``int`` microcontroller like the Atmel chips on Arduinos, but it
+ makes no sense at all on a 32-bit microcontroller like the STM32s
+ in the Maple line.
+
+ In short: we provide this so that existing Arduino code works as
+ expected, but **strongly discourage its use** in new programs.
+
+Syntax
+------
+
+::
+
+ highByte(x)
+
+Parameters
+----------
+
+**x**: a value of any integral type.
+
+Returns
+-------
+
+Second lowest byte in **x**.
+
+Example
+-------
+
+::
+
+ int x = 0xDEADBEEF;
+ SerialUSB.println(x, HEX); // prints "BE"
+
+Arduino Compatibility
+---------------------
+
+The Maple version of ``highByte()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`lowByte() <lang-lowbyte>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/interrupts.rst b/docs/source/lang/api/interrupts.rst
new file mode 100644
index 0000000..58fd2cc
--- /dev/null
+++ b/docs/source/lang/api/interrupts.rst
@@ -0,0 +1,47 @@
+.. highlight:: cpp
+
+.. _lang-interrupts:
+
+interrupts()
+============
+
+Re-enables interrupts (after they've been disabled by
+:ref:`noInterrupts() <lang-nointerrupts>`). Interrupts allow certain
+important tasks to happen in the background, and certain interrupts
+are enabled by default.
+
+Some functions will not work while interrupts are disabled, and both
+incoming and outgoing communication may be ignored. Interrupts can
+slightly disrupt the timing of code, however, and may be disabled for
+particularly critical sections of code.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: interrupts
+
+Example
+-------
+
+::
+
+ void setup() {}
+
+ void loop() {
+ noInterrupts();
+ // critical, time-sensitive code here
+ interrupts();
+ // other code here
+ }
+
+See Also
+--------
+
+- :ref:`noInterrupts() <lang-nointerrupts>`
+- :ref:`attachInterrupt() <lang-attachinterrupt>`
+- :ref:`detachInterrupt() <lang-detachinterrupt>`
+- :ref:`Timers reference <timers>`
+- :ref:`Timer API <lang-hardwaretimer>`
+- :ref:`External interrupts <external-interrupts>`
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/api/isbuttonpressed.rst b/docs/source/lang/api/isbuttonpressed.rst
new file mode 100644
index 0000000..8c350b9
--- /dev/null
+++ b/docs/source/lang/api/isbuttonpressed.rst
@@ -0,0 +1,20 @@
+.. _lang-isbuttonpressed:
+
+isButtonPressed()
+=================
+
+Check whether the board's built-in button (labeled BUT on the
+silkscreen) is pressed. The pin number of the built-in button is
+given by the constant ``BOARD_BUTTON_PIN``.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: isButtonPressed
+
+See Also
+--------
+
+- :ref:`Board-specific values <lang-board-values>`
+- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>`
+- :ref:`lang-waitforbuttonpress`
diff --git a/docs/source/lang/api/loop.rst b/docs/source/lang/api/loop.rst
new file mode 100644
index 0000000..c2a5097
--- /dev/null
+++ b/docs/source/lang/api/loop.rst
@@ -0,0 +1,44 @@
+.. highlight:: cpp
+
+.. _lang-loop:
+
+loop()
+======
+
+After creating a :ref:`setup() <lang-setup>` function, which
+initializes your sketch, the ``loop()`` function gets called
+repeatedly, allowing your program to change and respond. Use it to
+actively control your Maple board.
+
+Example
+-------
+
+::
+
+ int buttonPin = 38;
+
+ // setup initializes serial and the button pin
+ void setup() {
+ SerialUSB.begin();
+ pinMode(buttonPin, INPUT);
+ }
+
+ // loop() checks the button pin each time it executes,
+ // and will print 'H' if it is pressed, 'L' otherwise
+ void loop() {
+ if (digitalRead(buttonPin) == HIGH) {
+ SerialUSB.println('H');
+ } else {
+ SerialUSB.println('L');
+ }
+
+ delay(1000);
+ }
+
+See Also
+--------
+
+- :ref:`setup() <lang-setup>`
+
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/lowbyte.rst b/docs/source/lang/api/lowbyte.rst
new file mode 100644
index 0000000..c513711
--- /dev/null
+++ b/docs/source/lang/api/lowbyte.rst
@@ -0,0 +1,25 @@
+.. _lang-lowbyte:
+
+lowByte()
+=========
+
+Extracts the low-order (rightmost) byte of a variable (e.g. a
+word).
+
+Syntax
+------
+
+lowByte(x)
+
+Parameters
+----------
+
+**x**: a value of any type. However, if a non-integral type is used,
+the results will be strange.
+
+Returns
+-------
+
+The low byte's value (this will be between 0 and 255).
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/map.rst b/docs/source/lang/api/map.rst
new file mode 100644
index 0000000..69661a0
--- /dev/null
+++ b/docs/source/lang/api/map.rst
@@ -0,0 +1,68 @@
+.. highlight:: cpp
+
+.. _lang-map:
+
+map()
+=====
+
+Re-maps a number from one range to another.
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: map
+
+Discussion
+----------
+
+``map()`` does not constrain values to within the range, because
+out-of-range values are sometimes intended and useful. The
+:ref:`constrain() <lang-constrain>` macro may be used either before or
+after this function, if limits to the ranges are desired.
+
+Note that the "lower bounds" of either range may be larger or smaller
+than the "upper bounds" so that ``map()`` may be used to reverse a
+range of numbers; for example::
+
+ y = map(x, 1, 50, 50, 1);
+
+The function also handles negative numbers well, so that this
+example ::
+
+ y = map(x, 1, 50, 50, -100);
+
+is also valid.
+
+The ``map()`` function uses integer math (its arguments and return
+values all have type :ref:`long <lang-long>`), so it will not generate
+fractions, when the math might indicate that it should do so.
+Fractional remainders are truncated, and are not rounded or averaged.
+
+Example
+-------
+
+::
+
+ /* Map an ADC reading (12 bits) to 16-bit PWM (0 to 65,535) */
+
+ void setup() {
+ pinMode(0, INPUT_ANALOG);
+ pinMode(9, PWM);
+ }
+
+ void loop() {
+ int val = analogRead(0);
+ val = map(val, 0, 4095, 0, 65535);
+ analogWrite(9, val);
+ }
+
+
+See Also
+--------
+
+- :ref:`constrain() <lang-constrain>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/max.rst b/docs/source/lang/api/max.rst
new file mode 100644
index 0000000..d356f08
--- /dev/null
+++ b/docs/source/lang/api/max.rst
@@ -0,0 +1,64 @@
+.. highlight:: cpp
+
+.. _lang-max:
+
+max()
+=====
+
+(Macro) Calculates the maximum of two numbers.
+
+Syntax
+------
+
+::
+
+ max(x, y)
+
+Parameters
+----------
+
+**x**: the first number; may be any number or numeric expression.
+
+**y**: the second number; may be any number or numeric expression.
+
+
+Returns
+-------
+
+The larger of the two parameter values.
+
+Example
+-------
+
+::
+
+ sensVal = max(senVal, 20); // assigns sensVal to the larger of sensVal or 20
+ // (effectively ensuring that it is at least 20)
+
+.. note:: Perhaps counter-intuitively, max() is often used to
+ constrain the lower end of a variable's range, while :ref:`min()
+ <lang-min>` is used to constrain the upper end of the range.
+
+Warning
+-------
+
+Because of the way ``max()`` is implemented, avoid using other
+functions inside the parentheses. It may lead to incorrect results::
+
+ max(a--, 0); // avoid this - yields incorrect results
+
+ a--; // use this instead -
+ max(a, 0); // keep other operations outside max()
+
+Arduino Compatibility
+---------------------
+
+The Maple implementation of ``max()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`min() <lang-min>`
+- :ref:`constrain() <lang-constrain>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/micros.rst b/docs/source/lang/api/micros.rst
new file mode 100644
index 0000000..de85303
--- /dev/null
+++ b/docs/source/lang/api/micros.rst
@@ -0,0 +1,46 @@
+.. highlight:: cpp
+
+.. _lang-micros:
+
+micros()
+========
+
+Returns the number of microseconds since the Maple board began running
+the current program. This number will overflow (go back to zero),
+after approximately 70 minutes.
+
+.. note:: There are 1,000 microseconds in a millisecond, and 1,000,000
+ microseconds in a second.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: micros
+
+Example
+-------
+
+::
+
+ unsigned int time;
+
+ void setup() {
+ }
+
+ void loop() {
+ SerialUSB.print("Time: ");
+ time = micros();
+ // prints time since program started
+ SerialUSB.println(time);
+ // wait a second so as not to send massive amounts of data
+ delay(1000);
+ }
+
+See Also
+--------
+
+- :ref:`millis() <lang-millis>`
+- :ref:`delay() <lang-delay>`
+- :ref:`delayMicroseconds() <lang-delaymicroseconds>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/millis.rst b/docs/source/lang/api/millis.rst
new file mode 100644
index 0000000..b6fbf55
--- /dev/null
+++ b/docs/source/lang/api/millis.rst
@@ -0,0 +1,52 @@
+.. highlight:: cpp
+
+.. _lang-millis:
+
+millis()
+========
+
+Returns the number of milliseconds since the Maple board began running
+the current program. This number will overflow (go back to zero) after
+approximately 50 days.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: millis
+
+Example
+-------
+
+The following time prints the value returned by ``millis()`` roughly
+once per second::
+
+ unsigned int time;
+
+ void setup() {
+ }
+
+ void loop() {
+ SerialUSB.print("Time: ");
+ time = millis();
+ // prints time since program started
+ SerialUSB.println(time);
+
+ // wait a second so as not to send massive amounts of data
+ delay(1000);
+ }
+
+Tip
+---
+
+Since the return value for ``millis()`` is an :ref:`unsigned long
+<lang-unsignedlong>`, overflow errors may occur if you try to do math
+with other data types, such as :ref:`chars <lang-char>`.
+
+See Also
+--------
+
+- :ref:`micros <lang-micros>`
+- :ref:`delay <lang-delay>`
+- :ref:`delayMicroseconds <lang-delaymicroseconds>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/min.rst b/docs/source/lang/api/min.rst
new file mode 100644
index 0000000..3307105
--- /dev/null
+++ b/docs/source/lang/api/min.rst
@@ -0,0 +1,65 @@
+.. highlight:: cpp
+
+.. _lang-min:
+
+min()
+=====
+
+(Macro) Calculates the minimum of two numbers.
+
+Syntax
+------
+
+::
+
+ min(x,y)
+
+Parameters
+----------
+
+**x**: the first number; may be any number or numeric expression.
+
+**y**: the second number; may be any number or numeric expression.
+
+Returns
+-------
+
+The smaller of the two numbers.
+
+Example
+-------
+
+::
+
+ sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100
+ // ensuring that it never gets above 100.
+
+
+.. note:: Perhaps counter-intuitively, max() is often used to
+ constrain the lower end of a variable's range, while min() is used
+ to constrain the upper end of the range.
+
+
+Warning
+-------
+
+Because of the way ``min()`` is implemented, avoid using other
+functions inside the parentheses. It may lead to incorrect results::
+
+ min(a++, 100); // avoid this - yields incorrect results
+
+ a++; // use this instead -
+ min(a, 100); // keep other operations outside min()
+
+Arduino Compatibility
+---------------------
+
+The Maple version of ``min()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`max() <lang-max>`
+- :ref:`constrain() <lang-constrain>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/nointerrupts.rst b/docs/source/lang/api/nointerrupts.rst
new file mode 100644
index 0000000..68f0498
--- /dev/null
+++ b/docs/source/lang/api/nointerrupts.rst
@@ -0,0 +1,47 @@
+.. highlight:: cpp
+
+.. _lang-nointerrupts:
+
+noInterrupts()
+==============
+
+Description
+-----------
+
+Disables interrupts. Interrupts allow certain important tasks to
+happen in the background and are enabled by default. Some functions
+will not work while interrupts are disabled, and incoming
+communication may be ignored. Interrupts can slightly disrupt the
+timing of code, however, and may be disabled for particularly critical
+sections of code.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: noInterrupts
+
+Example
+-------
+
+::
+
+ void setup() {}
+
+ void loop() {
+ noInterrupts();
+ // critical, time-sensitive code here
+ interrupts();
+ // other code here
+ }
+
+See Also
+--------
+
+- :ref:`interrupts() <lang-interrupts>`
+- :ref:`attachInterrupt() <lang-attachinterrupt>`
+- :ref:`detachInterrupt() <lang-detachinterrupt>`
+- :ref:`Timers reference <timers>`
+- :ref:`Timer API <lang-hardwaretimer>`
+- :ref:`External interrupts <external-interrupts>`
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/api/pinmode.rst b/docs/source/lang/api/pinmode.rst
new file mode 100644
index 0000000..643e26e
--- /dev/null
+++ b/docs/source/lang/api/pinmode.rst
@@ -0,0 +1,80 @@
+.. highlight:: cpp
+
+.. _lang-pinmode:
+
+pinMode()
+=========
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: pinMode
+
+.. _lang-pinmode-wiringpinmode:
+
+.. doxygenenum:: WiringPinMode
+
+Discussion
+----------
+
+pinMode() is usually called within :ref:`lang-setup` in order to
+configure a pin for a certain usage (although it may be called
+anywhere).
+
+Example
+-------
+
+This example uses pinMode() to set up the pin connected to the
+built-in LED as an output. Once this is done,
+:ref:`lang-digitalwrite` can be used to turn the pin ``HIGH`` and
+``LOW``, which turn the LED on and off.
+
+::
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT); // sets the LED pin as output
+ }
+
+ void loop() {
+ digitalWrite(BOARD_LED_PIN, HIGH); // sets the LED on
+ delay(1000); // waits for a second
+ digitalWrite(BOARD_LED_PIN, LOW); // sets the LED off
+ delay(1000); // waits for a second
+ }
+
+Arduino Compatibility
+---------------------
+
+.. TODO check out Arduino vs. Maple static discilpline cutoffs to
+.. ensure accuracy of following:
+
+On Maple, pinMode() supports the ``INPUT`` and ``OUTPUT`` modes in the
+same way as Arduino (however, remember that the Maple, as a 3.3V
+device, will only drive 3.3V to an ``OUTPUT`` pin that has been set
+``HIGH``, instead of 5V like on Arduino).
+
+``INPUT_ANALOG`` and ``PWM`` modes were added because the Maple
+doesn't separate the analog and digital pins the same way Arduino
+does. Unlike on Arduino, you **must call** pinMode() to set up a pin
+for these purposes before a call to, e.g., :ref:`lang-analogRead`.
+This should only add a few lines to your :ref:`lang-setup` function.
+
+.. TODO [0.1.0] verify following before putting it in:
+
+.. ``OUTPUT_OPEN_DRAIN``, ``INPUT_PULLUP``, ``INPUT_PULLDOWN``, and
+.. ``PWM_OPEN_DRAIN`` modes represent functionality not currently
+.. available on Arduino boards.
+
+See Also
+--------
+
+- :ref:`lang-board-values`
+- :ref:`lang-constants`
+- :ref:`lang-digitalwrite`
+- :ref:`lang-digitalread`
+- :ref:`gpio`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/pow.rst b/docs/source/lang/api/pow.rst
new file mode 100644
index 0000000..219a866
--- /dev/null
+++ b/docs/source/lang/api/pow.rst
@@ -0,0 +1,20 @@
+.. _lang-pow:
+
+pow()
+=====
+
+Calculates the value of a number raised to a power.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: pow
+
+See Also
+--------
+
+- :ref:`sqrt() <lang-sqrt>`
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/pwmwrite.rst b/docs/source/lang/api/pwmwrite.rst
new file mode 100644
index 0000000..5cc112e
--- /dev/null
+++ b/docs/source/lang/api/pwmwrite.rst
@@ -0,0 +1,61 @@
+.. highlight:: cpp
+
+.. _lang-pwmwrite:
+
+pwmWrite()
+==========
+
+Writes a :ref:`PWM wave <pwm>` to a pin. You can use this to make an
+LED get brighter or dimmer, control a servomotor, etc. After a call to
+pwmWrite(), the pin will output a steady square wave with the given
+duty cycle. You can change the duty cycle later by calling pwmWrite()
+again with the same pin and a different duty.
+
+The pins which support PWM have ``PWM`` listed underneath their number
+on your board's silkscreen. These pin numbers are available to your
+program in the :ref:`boardPWMPins <lang-board-values-pwm-pins>`
+board-specific array. The number of pins which are capable of PWM on
+your board is given by the ``BOARD_NR_PWM_PINS`` constant. These
+values are documented for each board in the :ref:`Board Hardware
+Documentation <index-boards>` pages.
+
+The Arduino function :ref:`analogWrite() <lang-analogwrite>` is an
+alias for ``pwmWrite()``, but it is badly named, and its use is
+discouraged.
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: pwmWrite
+
+Example
+-------
+
+Sets the output to the LED proportional to the value read from the
+potentiometer::
+
+ int analogPin = 3; // potentiometer connected to analog pin 3
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT); // sets the LED pin as output
+
+ pinMode(analogPin, INPUT_ANALOG); // sets the potentiometer pin as
+ // analog input
+ }
+
+ void loop() {
+ int val = analogRead(analogPin); // read the input pin
+
+ pwmWrite(BOARD_LED_PIN, val * 16); // analogRead values go from 0
+ // to 4095, pwmWrite values
+ // from 0 to 65535, so scale roughly
+ }
+
+See Also
+--------
+
+- :ref:`Maple PWM tutorial <pwm>`
+- :ref:`boardPWMPins <lang-board-values-pwm-pins>`
diff --git a/docs/source/lang/api/random.rst b/docs/source/lang/api/random.rst
new file mode 100644
index 0000000..9875ee6
--- /dev/null
+++ b/docs/source/lang/api/random.rst
@@ -0,0 +1,71 @@
+.. highlight:: cpp
+
+.. _lang-random:
+
+random()
+========
+
+The ``random()`` function generates pseudo-random numbers.
+
+Library Documentation
+---------------------
+
+.. FIXME [Breathe] use doxygenfunction when possible
+
+.. cpp:function:: random(long max)
+
+ Same as a call to ``random(0, max)``.
+
+.. cpp:function:: random(long min, long max)
+
+ Generate a pseudo-random number with given lower and upper bounds.
+
+ *Parameters*
+
+ - ``min`` - Lower bound on the returned value, inclusive
+ - ``max`` - Upper bound on the returned value, exclusive
+
+ *Returns*: A pseudo-random number in the range [min, max).
+
+Discussion
+----------
+
+If it is important for a sequence of values generated by
+:ref:`random() <lang-random>` to differ, on subsequent executions of a
+sketch, use :ref:`randomSeed() <lang-randomseed>` to initialize the
+random number generator with a fairly random input, such as
+:ref:`analogRead() <lang-analogread>` on an unconnected pin.
+
+Conversely, it can occasionally be useful to use pseudorandom
+sequences that repeat exactly. This can be accomplished by calling
+``randomSeed()`` with a fixed number, before starting the random
+sequence.
+
+Example
+-------
+
+The following sketch initializes the random seed based on an :ref:`ADC
+<adc>` reading of pin 0. If this pin is unconnected, the Sketch
+should print different values to the :ref:`serial monitor
+<ide-serial-monitor>` each time it is run::
+
+ long randNumber;
+
+ void setup() {
+ pinMode(0, INPUT_ANALOG);
+ randomSeed(analogRead(0));
+ }
+
+ void loop() {
+ randNumber = random(300);
+ SerialUSB.println(randNumber);
+
+ delay(50);
+ }
+
+See Also
+--------
+
+- :ref:`randomSeed() <lang-randomseed>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/randomseed.rst b/docs/source/lang/api/randomseed.rst
new file mode 100644
index 0000000..ca7b75f
--- /dev/null
+++ b/docs/source/lang/api/randomseed.rst
@@ -0,0 +1,60 @@
+.. highlight:: cpp
+
+.. _lang-randomseed:
+
+randomSeed()
+============
+
+``randomSeed()`` initializes the `pseudorandom number generator
+<http://en.wikipedia.org/wiki/Pseudorandom_number_generator>`_,
+causing it to start at an arbitrary point in its random sequence.
+This sequence, while very long, and random, is always the same.
+
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: randomSeed
+
+Discussion
+----------
+
+If it is important for a sequence of values generated by
+:ref:`random() <lang-random>` to differ, on subsequent executions of a
+sketch, use ``randomSeed()`` to initialize the random number generator
+with a fairly random input, such as :ref:`analogRead()
+<lang-analogread>` on an unconnected pin.
+
+Conversely, it can occasionally be useful to use pseudorandom
+sequences that repeat exactly. This can be accomplished by calling
+``randomSeed()`` with a fixed number, before starting the random
+sequence.
+
+Example
+-------
+
+The following sketch initializes the random seed based on an :ref:`ADC
+<adc>` reading of pin 0. If this pin is unconnected, the Sketch
+should print different values to the :ref:`serial monitor
+<ide-serial-monitor>` each time it is run::
+
+ long randNumber;
+
+ void setup() {
+ pinMode(0, INPUT_ANALOG);
+ randomSeed(analogRead(0));
+ }
+
+ void loop() {
+ randNumber = random(300);
+ SerialUSB.println(randNumber);
+
+ delay(50);
+ }
+
+See Also
+--------
+
+- :ref:`random() <lang-random>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/serial.rst b/docs/source/lang/api/serial.rst
new file mode 100644
index 0000000..e287015
--- /dev/null
+++ b/docs/source/lang/api/serial.rst
@@ -0,0 +1,282 @@
+.. FIXME [0.0.13] This doesn't include UART4/5, or USART6
+.. highlight:: cpp
+
+.. _lang-serial:
+
+Serial Ports (``Serial1``, ``Serial2``, ``Serial3``)
+====================================================
+
+This page describes how to use the built-in serial ports (also known
+as USARTs). For more information about serial ports, see
+:ref:`usart`.
+
+.. contents:: Contents
+ :local:
+
+Getting Started
+---------------
+
+First, decide which serial port you wish to use, and :ref:`connect its
+pins to the device you're communicating with <usart-circuit>`. (The TX
+and RX pins for a serial port are labeled on your board's silkscreen;
+for example, serial port 2 has pins labeled "TX2" and "RX2").
+
+The variable for controlling a serial port is the word ``Serial``,
+plus the serial port's number. For example, you can control serial
+port 1 with the variable ``Serial1``, serial port 2 with ``Serial2``,
+and so on.
+
+In order to get started using your serial port, you'll first need to
+turn it on. Do this by calling your serial port's ``begin()``
+function, giving it the baud rate you wish it to communicate at. If
+you're not sure what baud rate to use, 9600 is a safe (although slow)
+value to try. Put this call to ``begin()`` in your :ref:`lang-setup`,
+like in the following example::
+
+ void setup() {
+ // 9600 is the baud rate to use. The baud rate determines how
+ // fast the communication goes.
+ Serial2.begin(9600);
+ }
+
+ void loop() {
+ // Communicate using Serial2 here
+ }
+
+Communicating Over Serial
+-------------------------
+
+Now that your serial port is set up, it's time to start communicating.
+
+One common use for serial ports is to print strings and other
+debugging information to a computer. You can print numbers or strings
+using ``print()`` and ``println()``, like this::
+
+ void printSomeInformation() {
+ Serial2.print("First, print this string. Then print a number: ");
+ Serial2.print(42);
+ Serial2.print(". You can print floating point values, too: ");
+ Serial2.print(3.14);
+ Serial2.println(". Using println() instead of print() ends the line.");
+ Serial2.println("This sentence starts on a new line.");
+ }
+
+This sort of communication can go both ways: you can send characters
+from a computer to a serial port as well. You can check how many
+characters are waiting for you to read using the ``available()``
+function, and read them out one at a time using ``read()``. The
+following example program uses these functions to "echo" back anything
+sent to ``Serial2``::
+
+ void setup() {
+ Serial2.begin(9600);
+ }
+
+ void echoCharacter() {
+ // Check to see if we have received any information. numUnread
+ // will hold the number of bytes we've received, but haven't
+ // looked at yet.
+ int numUnread = Serial2.available();
+
+ // numUnread > 0 means that there are some unread bytes waiting
+ if (numUnread > 0) {
+ // Read a single byte out:
+ byte b = Serial2.read();
+ // And then print it back:
+ Serial2.print(b);
+ }
+ }
+
+ void loop() {
+ echoCharacter();
+ }
+
+Function Reference
+------------------
+
+This section gives a full listing of functions available for use with
+serial ports.
+
+Library Documentation
+---------------------
+
+All of the ``Serial[1,2,3]`` objects are instances of the
+``HardwareSerial`` class, which is documented in this section. (This
+means that you can use any of these functions on any of ``Serial1``,
+``Serial2``, and ``Serial3``).
+
+.. cpp:class:: HardwareSerial
+
+ Serial port class. Predefined instances are ``Serial1``,
+ ``Serial2``, and ``Serial3``.
+
+.. cpp:function:: void HardwareSerial::begin(unsigned int baud)
+
+ Set up a ``HardwareSerial`` object for communications. This method
+ must be called before attempting to use the ``HardwareSerial``
+ object (typically, you call this in your :ref:`setup()
+ <lang-setup>` function).
+
+.. cpp:function:: void HardwareSerial::end()
+
+ Disables the USART associated with this object, allowing any
+ associated communication pins to be used for other purposes.
+
+.. cpp:function:: unsigned int HardwareSerial::available()
+
+ Returns the number of bytes available for reading.
+
+.. cpp:function:: unsigned char HardwareSerial::read()
+
+ Returns the next available, unread character. If there are no
+ available characters (you can check this with :cpp:func:`available
+ <HardwareSerial::available>`), the call will block until one
+ becomes available.
+
+.. cpp:function:: void HardwareSerial::flush()
+
+ Throw away the contents of the serial port's receiver (RX) buffer.
+ That is, clears any buffered characters, so that the next character
+ read is guaranteed to be new.
+
+.. cpp:function:: void HardwareSerial::print(unsigned char b)
+
+ Print the given byte over the USART.
+
+.. cpp:function:: void HardwareSerial::print(char c)
+
+ Print the given character over the USART. 7-bit clean characters
+ are typically interpreted as ASCII text.
+
+.. cpp:function:: void HardwareSerial::print(const char *str)
+
+ Print the given null-terminated string over the USART.
+
+.. cpp:function:: void HardwareSerial::print(int n)
+
+ Print the argument's digits over the USART, in decimal format.
+ Negative values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: void HardwareSerial::print(unsigned int n)
+
+ Print the argument's digits over the USART, in decimal format.
+
+.. cpp:function:: void HardwareSerial::print(long n)
+
+ Print the argument's digits over the USART, in decimal format.
+ Negative values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: void HardwareSerial::print(unsigned long n)
+
+ Print the argument's digits over the USART, in decimal format.
+
+.. cpp:function:: void HardwareSerial::print(long n, int base)
+
+ Print the digits of ``n`` over the USART, in base ``base`` (which
+ may be between 2 and 16). The ``base`` value 2 corresponds to
+ binary, 8 to octal, 10 to decimal, and 16 to hexadecimal. Negative
+ values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: void HardwareSerial::print(double n)
+
+ Print ``n``, accurate to 2 digits after the decimal point.
+
+.. _lang-serial-println:
+
+.. cpp:function:: void HardwareSerial::println(char c)
+
+ Like ``print(c)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(const char *c)
+
+ Like ``print(c)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(unsigned char b)
+
+ Like ``print(b)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(int n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(unsigned int n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(long n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(unsigned long n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(long n, int base)
+
+ Like ``print(n, b)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println(double n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: void HardwareSerial::println()
+
+ Prints ``"\r\n"`` over the USART.
+
+.. cpp:function:: void HardwareSerial::write(unsigned char ch)
+
+ Sends one character over the USART. This function is currently
+ blocking.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+.. cpp:function:: void HardwareSerial::write(const char* str)
+
+ Send the given null-terminated character string over the USART.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+.. cpp:function:: void HardwareSerial::write(void *buf, unsigned int size)
+
+ Writes the first ``size`` bytes of ``buf`` over the USART. Each
+ byte is transmitted as an individual character.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+.. cpp:function:: int HardwareSerial::txPin()
+
+ Return the number of the TX (transmit) pin.
+
+.. cpp:function:: int HardwareSerial::rxPin()
+
+ Return the number of the RX (receive) pin.
+
+Arduino Compatibility Note
+--------------------------
+
+Unlike the Arduino, none of the Maple's serial ports is connected to
+the USB port on the Maple board. If you want to communicate using the
+built-in USB port, use :ref:`SerialUSB <lang-serialusb>` instead. You
+will need an additional USB-to-serial adapter to communicate between a
+USART and your computer.
+
+.. FIXME [0.1.0] port these examples over
+
+.. Examples
+.. --------
+
+.. - `ASCII Table <http://arduino.cc/en/Tutorial/ASCIITable>`_
+.. - `Dimmer <http://arduino.cc/en/Tutorial/Dimmer>`_
+.. - `Graph <http://arduino.cc/en/Tutorial/Graph>`_
+.. - `Physical Pixel <http://arduino.cc/en/Tutorial/PhysicalPixel>`_
+.. - `Virtual Color Mixer <http://arduino.cc/en/Tutorial/VirtualColorMixer>`_
+.. - `Serial Call Response <http://arduino.cc/en/Tutorial/SerialCallResponse>`_
+.. - `Serial Call Response ASCII <http://arduino.cc/en/Tutorial/SerialCallResponseASCII>`_
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/serialusb.rst b/docs/source/lang/api/serialusb.rst
new file mode 100644
index 0000000..ed466f2
--- /dev/null
+++ b/docs/source/lang/api/serialusb.rst
@@ -0,0 +1,242 @@
+.. highlight:: cpp
+
+.. _lang-serialusb:
+
+``SerialUSB``
+=============
+
+Used for communication between the Maple board and a computer.
+
+.. contents:: Contents
+ :local:
+
+Introduction
+------------
+
+In addition to three :ref:`serial ports <lang-serial>`, the Maple's
+STM32 microprocessor includes a dedicated USB peripheral. This
+peripheral is used to emulate a regular serial port for use as a
+terminal. The emulated terminal is relatively slow; it is best for
+transferring data at regular serial speeds (kilobaud).
+
+Library access to the emulated serial port is provided through the
+``SerialUSB`` object. You can mostly use ``SerialUSB`` as a drop-in
+replacement for ``Serial1``, ``Serial2``, and ``Serial3``.
+
+.. warning:: The ``SerialUSB`` functionality includes a 50 millisecond
+ timeout for writes, and does not try to detect if the USB host is
+ "really" connected, or just enumerated and initialized.
+
+ This means that if you have a number of calls to one of the
+ ``SerialUSB`` ``write()`` or ``print()`` functions in your code,
+ and you are not monitoring ``SerialUSB`` on a computer, your
+ program will run much slower than if it is being monitored or
+ totally disconnected (run off of a battery).
+
+ You can avoid this behavior by :ref:`deciphering the port status
+ using the DTR and RTS line status <lang-serialusb-safe-print>` (the
+ behavior of these control lines is platform dependent and we no
+ longer interpret them by default).
+
+Library Documentation
+---------------------
+
+The ``SerialUSB`` object is an instance of the ``USBSerial`` class,
+which is documented in this section. This means that you can use any
+of these functions by writing
+``SerialUSB.functionName(arguments...)``. For example, to print the
+message "hello, world!", you can write ``USBSerial.println("hello,
+world!")``.
+
+.. cpp:class:: USBSerial
+
+ Emulated serial-over-USB class. ``SerialUSB`` is the predefined
+ (singleton) instance.
+
+.. _lang-serialusb-begin:
+
+.. cpp:function:: USBSerial::begin()
+
+ Set up the USB peripheral for emulated serial communication. The
+ peripheral is configured this way by default; calling this function
+ should only be necessary if you have disabled the peripheral using
+ ``SerialUSB.end()``.
+
+.. _lang-serialusb-end:
+
+.. cpp:function:: USBSerial::end()
+
+ Disables the USB peripheral. Note that using this function will
+ terminate all USB communications between the Maple and the USB
+ host; in particular, it implies that you won't be able to upload
+ any new programs without resetting the board or using
+ :ref:`perpetual bootloader mode
+ <troubleshooting-perpetual-bootloader>`.
+
+.. cpp:function:: unsigned int USBSerial::available()
+
+ Returns the number of bytes available for reading.
+
+.. _lang-serialusb-read:
+
+.. cpp:function:: unsigned char USBSerial::read()
+
+ Returns the next available, unread character. If there are no
+ available characters (you can check this with :cpp:func:`available
+ <USBSerial::available>`), the call will block until one
+ becomes available.
+
+.. cpp:function:: USBSerial::print(unsigned char b)
+
+ Print the given byte over the USB connection.
+
+.. cpp:function:: USBSerial::print(char c)
+
+ Print the given character over the USB connection. 7-bit clean characters
+ are typically interpreted as ASCII text.
+
+.. cpp:function:: USBSerial::print(const char *str)
+
+ Print the given null-terminated string over the USB connection.
+
+.. cpp:function:: USBSerial::print(int n)
+
+ Print the argument's digits over the USB connection, in decimal format.
+ Negative values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: USBSerial::print(unsigned int n)
+
+ Print the argument's digits over the USB connection, in decimal format.
+
+.. cpp:function:: USBSerial::print(long n)
+
+ Print the argument's digits over the USB connection, in decimal
+ format. Negative values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: USBSerial::print(unsigned long n)
+
+ Print the argument's digits over the USB connection, in decimal
+ format.
+
+.. cpp:function:: USBSerial::print(long n, int base)
+
+ Print the digits of ``n`` over the USB connection, in base ``base``
+ (which may be between 2 and 16). The ``base`` value 2 corresponds
+ to binary, 8 to octal, 10 to decimal, and 16 to hexadecimal.
+ Negative values will be prefixed with a ``'-'`` character.
+
+.. cpp:function:: USBSerial::print(double n)
+
+ Print ``n``, accurate to 2 digits after the decimal point.
+
+.. _lang-serialusb-println:
+
+.. cpp:function:: USBSerial::println(char c)
+
+ Like ``print(c)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(const char *c)
+
+ Like ``print(c)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(unsigned char b)
+
+ Like ``print(b)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(int n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(unsigned int n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(long n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(unsigned long n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(long n, int base)
+
+ Like ``print(n, b)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println(double n)
+
+ Like ``print(n)``, followed by ``"\r\n"``.
+
+.. cpp:function:: USBSerial::println()
+
+ Prints ``"\r\n"`` over the USB connection.
+
+.. cpp:function:: USBSerial::write(unsigned char ch)
+
+ Sends one character over the USB connection. This function is
+ currently blocking, although nonblocking writes are a planned
+ future extension.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+.. cpp:function:: USBSerial::write(const char* str)
+
+ Send the given null-terminated character string over the USB
+ connection.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+.. cpp:function:: USBSerial::write(void *buf, unsigned int size)
+
+ Writes the first ``size`` bytes of ``buf`` over the USB connection.
+ Each byte is transmitted as an individual character.
+
+ This is a low-level function. One of the ``print()`` or
+ ``println()`` functions is likely to be more useful when printing
+ multiple characters, when formatting numbers for printing, etc.
+
+Examples
+--------
+
+.. _lang-serialusb-safe-print:
+
+**Safe print**: This function should run smoothly and not block; the
+LED should blink at roughly the same speed whether being monitored,
+running from battery, or connected but not monitored. You may need to
+experiment with the DTR/RTS logic for your platform and device
+configuration. ::
+
+ #define LED_PIN BOARD_LED_PIN
+
+ void setup() {
+ /* Set up the LED to blink */
+ pinMode(LED_PIN, OUTPUT);
+ }
+
+ void loop() {
+ // LED will stay off if we are disconnected, and will blink
+ // quickly if USB is unplugged (battery power, etc.).
+ if(SerialUSB.isConnected()) {
+ digitalWrite(LED_PIN, 1);
+ }
+ delay(100);
+
+ // If this logic fails to detect if bytes are going to be read
+ // by the USB host, then the println() take a long time,
+ // causing a very slow LED blink. If the characters are
+ // printed and read, the blink will only slow a small amount
+ // when "really" connected, and will be fast fast when the
+ // virtual port is only configured.
+ if(SerialUSB.isConnected() && (SerialUSB.getDTR() || SerialUSB.getRTS())) {
+ for(int i = 0; i < 10; i++) {
+ SerialUSB.println(123456, BIN);
+ }
+ }
+ digitalWrite(LED_PIN, 0);
+ delay(100);
+ }
+
diff --git a/docs/source/lang/api/setup.rst b/docs/source/lang/api/setup.rst
new file mode 100644
index 0000000..1e8e3b8
--- /dev/null
+++ b/docs/source/lang/api/setup.rst
@@ -0,0 +1,29 @@
+.. highlight:: cpp
+
+.. _lang-setup:
+
+setup()
+=======
+
+The ``setup()`` function is called when a sketch starts. Use it to
+initialize :ref:`variables <lang-variables>`, :ref:`pin modes
+<lang-pinmode>`, start using :ref:`libraries <libraries>`, etc. The
+``setup()`` function will only run once, after each power-up or reset
+of the Maple board.
+
+Example
+-------
+
+::
+
+ int buttonPin = 38;
+
+ void setup() {
+ pinMode(buttonPin, INPUT);
+ }
+
+ void loop() {
+ // ...
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/shiftout.rst b/docs/source/lang/api/shiftout.rst
new file mode 100644
index 0000000..1d9ba12
--- /dev/null
+++ b/docs/source/lang/api/shiftout.rst
@@ -0,0 +1,99 @@
+.. highlight:: cpp
+
+.. _lang-shiftout:
+
+shiftOut()
+==========
+
+Shift out a byte of data, one bit at a time.
+
+.. contents:: Contents
+ :local:
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: shiftOut
+
+Discussion
+----------
+
+This is a software implementation. There is also a hardware :ref:`SPI
+<spi>` library available which will be faster and consume less CPU
+cycles than this function.
+
+Note that the ``dataPin`` and ``clockPin`` must already be configured
+to :ref:`OUTPUT <lang-constants-output>` mode by a call to
+:ref:`pinMode() <lang-pinmode>`.
+
+Also note that since shiftOut() outputs 1 byte (8 bits) at a time, it
+requires multiple steps to output values larger than 255.
+
+Examples
+--------
+
+To use these examples, replace ``dataPin`` and ``clockPin`` with the
+numbers of the pins you want to use::
+
+ /* MSBFIRST example */
+
+ uint16 data = 500;
+ // shift out high byte
+ shiftOut(dataPin, clockPin, MSBFIRST, (data >> 8));
+ // shift out low byte
+ shiftOut(dataPin, clockPin, MSBFIRST, data);
+
+ /* LSBFIRST serial */
+
+ data = 500;
+ // shift out low byte
+ shiftOut(dataPin, clockPin, LSBFIRST, data);
+ // shift out high byte
+ shiftOut(dataPin, clockPin, LSBFIRST, (data >> 8));
+
+Arduino Tutorial Example
+------------------------
+
+This Arduino example runs unmodified on the Maple. For accompanying
+circuit, see the `tutorial on controlling a 74HC595 shift register
+<http://arduino.cc/en/Tutorial/ShiftOut>`_.
+
+::
+
+ //**************************************************************//
+ // Name : shiftOutCode, Hello World //
+ // Author : Carlyn Maw, Tom Igoe //
+ // Date : 25 Oct, 2006 //
+ // Version : 1.0 //
+ // Notes : Code for using a 74HC595 Shift Register //
+ // : to count from 0 to 255 //
+ //**************************************************************//
+
+ // Pin connected to ST_CP of 74HC595
+ int latchPin = 8;
+ // Pin connected to SH_CP of 74HC595
+ int clockPin = 12;
+ // Pin connected to DS of 74HC595
+ int dataPin = 11;
+
+ void setup() {
+ // Set pins to output because they are addressed in the main loop
+ pinMode(latchPin, OUTPUT);
+ pinMode(clockPin, OUTPUT);
+ pinMode(dataPin, OUTPUT);
+ }
+
+ void loop() {
+ // Count up routine
+ for (int j = 0; j < 256; j++) {
+ // Ground latchPin and hold low for as long as you are transmitting
+ digitalWrite(latchPin, LOW);
+ shiftOut(dataPin, clockPin, LSBFIRST, j);
+ // Return the latch pin high to signal chip that it
+ // no longer needs to listen for information
+ digitalWrite(latchPin, HIGH);
+ delay(1000);
+ }
+ }
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/api/sin.rst b/docs/source/lang/api/sin.rst
new file mode 100644
index 0000000..3e28c0b
--- /dev/null
+++ b/docs/source/lang/api/sin.rst
@@ -0,0 +1,31 @@
+.. _lang-sin:
+
+sin()
+=====
+
+Calculates the `sine <http://en.wikipedia.org/wiki/Sine>`_ of an
+angle.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: sin
+
+Arduino Compatibility
+---------------------
+
+The Maple version of ``sin()`` is compatible with Arduino.
+
+Note that the Maple implementation comes from `newlib
+<http://sourceware.org/newlib/>`_\ , while Arduino's is that of
+`avr-libc <http://avr-libc.nongnu.org/>`_\ .
+
+See Also
+--------
+
+- :ref:`cos <lang-cos>`
+- :ref:`tan <lang-tan>`
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/sq.rst b/docs/source/lang/api/sq.rst
new file mode 100644
index 0000000..96724d3
--- /dev/null
+++ b/docs/source/lang/api/sq.rst
@@ -0,0 +1,45 @@
+.. highlight:: cpp
+
+.. _lang-sq:
+
+sq()
+====
+
+(Macro) computes the square of a number.
+
+Syntax
+------
+
+::
+
+ sq(a)
+
+Parameters
+----------
+
+**a**: the number.
+
+Returns
+-------
+
+**a** squared (**a** × **a**).
+
+Warning
+-------
+
+Because of the way ``sq()`` is implemented, avoid using other
+functions or causing side effects inside the parentheses, as it may
+lead to incorrect results::
+
+ b = sq(a++); // avoid this - yields incorrect results
+
+ b = sq(a); // use this instead -
+ a++; // keep other operations outside sq()
+
+
+Arduino Compatibility
+---------------------
+
+Maple's implementation of ``sq()`` is compatible with Arduino.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/tan.rst b/docs/source/lang/api/tan.rst
new file mode 100644
index 0000000..b1aed31
--- /dev/null
+++ b/docs/source/lang/api/tan.rst
@@ -0,0 +1,30 @@
+.. _lang-tan:
+
+tan()
+=====
+
+Calculates the tangent of an angle.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: tan
+
+Arduino Compatibility
+---------------------
+
+The Maple version of ``tan()`` is compatible with Arduino.
+
+Note that the Maple implementation comes from `newlib
+<http://sourceware.org/newlib/>`_\ , while Arduino's is that of
+`avr-libc <http://avr-libc.nongnu.org/>`_\ .
+
+See Also
+--------
+
+- :ref:`sin <lang-sin>`
+- :ref:`cos <lang-cos>`
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/toggleled.rst b/docs/source/lang/api/toggleled.rst
new file mode 100644
index 0000000..cad347f
--- /dev/null
+++ b/docs/source/lang/api/toggleled.rst
@@ -0,0 +1,37 @@
+.. highlight:: cpp
+
+.. _lang-toggleled:
+
+toggleLED()
+===========
+
+*Toggle* the built-in LED: switch it from off to on, or on to off.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: toggleLED
+
+Example
+-------
+
+.. _lang-toggleled-example:
+
+This example sets up the board's LED pin for output, then toggles the
+LED every 100 milliseconds::
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ }
+
+ void loop() {
+ toggleLED();
+ delay(100);
+ }
+
+
+See Also
+--------
+
+- :ref:`BOARD_LED_PIN <lang-board-values-led>`
+- :ref:`togglePin() <lang-togglepin>`
diff --git a/docs/source/lang/api/togglepin.rst b/docs/source/lang/api/togglepin.rst
new file mode 100644
index 0000000..290718d
--- /dev/null
+++ b/docs/source/lang/api/togglepin.rst
@@ -0,0 +1,17 @@
+.. _lang-togglepin:
+
+togglePin()
+===========
+
+Switches a digital output pin from :ref:`HIGH <lang-constants-high>`
+to :ref:`LOW <lang-constants-low>`, or from LOW to HIGH.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: togglePin
+
+See Also
+--------
+
+- :ref:`toggleLED() <lang-toggleled>`
diff --git a/docs/source/lang/api/volatile.rst b/docs/source/lang/api/volatile.rst
new file mode 100644
index 0000000..1b72897
--- /dev/null
+++ b/docs/source/lang/api/volatile.rst
@@ -0,0 +1,65 @@
+.. highlight:: cpp
+
+.. _lang-volatile:
+
+``volatile``
+============
+
+The ``volatile`` keyword known is a variable *qualifier*. It is
+usually used before the datatype of a variable, to modify the way in
+which the compiler treats the variable.
+
+Declaring a variable ``volatile`` is a directive to the compiler. The
+compiler is software which translates your C++ code into the machine
+code, which are the real instructions for the STM32 chip in the
+Maple. (The particular compiler we provide for use with the Maple is a
+version of :ref:`GCC <arm-gcc>`).
+
+Specifically, it directs the compiler to read the variable's value
+fresh every time it is used, rather than "backing up" the value and
+reading from its backup copy. (Compilers often "back up" a variable's
+value in RAM into a storage location called a *register*; this is done
+for efficiency).
+
+A variable should be declared ``volatile`` whenever its value can be
+changed by something beyond the control of the code section in which
+it appears, such as an :ref:`external interrupt
+<external-interrupts>`. (The only place that this is likely to occur
+in most programs is inside of code called by interrupts).
+
+Example
+-------
+
+::
+
+ // toggles LED when interrupt pin changes state
+
+ int pin = 13;
+ volatile int state = LOW;
+
+ void setup() {
+ pinMode(pin, OUTPUT);
+ attachInterrupt(0, blink, CHANGE);
+ }
+
+ void loop() {
+ digitalWrite(pin, state);
+ }
+
+ void blink() {
+ if (state == HIGH) {
+ state = LOW;
+ } else {
+ // state must be HIGH
+ state = HIGH;
+ }
+ }
+
+See Also
+--------
+
+- :ref:`External Interrupts <external-interrupts>`
+- :ref:`lang-attachinterrupt`
+- :ref:`lang-detachinterrupt`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/api/waitforbuttonpress.rst b/docs/source/lang/api/waitforbuttonpress.rst
new file mode 100644
index 0000000..0e0fbaf
--- /dev/null
+++ b/docs/source/lang/api/waitforbuttonpress.rst
@@ -0,0 +1,43 @@
+.. highlight:: cpp
+
+.. _lang-waitforbuttonpress:
+
+waitForButtonPress()
+====================
+
+Wait for the board's built-in button to be pressed, possibly with
+timeout. The button is labeled "BUT" on the board's silkscreen. Its
+pin number is the constant :ref:`BOARD_BUTTON_PIN
+<lang-board-values-but>`.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: waitForButtonPress
+
+
+Example
+-------
+
+.. _lang-waitforbuttonpress-example:
+
+This example sets up the board's button pin as an input, then prints a
+message very time the button is pressed.
+
+::
+
+ void setup() {
+ pinMode(BOARD_BUTTON_PIN, INPUT);
+ }
+
+ void loop() {
+ waitForButtonPress();
+ SerialUSB.println("You pressed the button!");
+ }
+
+See Also
+--------
+
+- :ref:`Board-specific values <lang-board-values>`
+- :ref:`BOARD_BUTTON_PIN <lang-board-values-but>`
+- :ref:`lang-isbuttonpressed`
diff --git a/docs/source/lang/cc-attribution.txt b/docs/source/lang/cc-attribution.txt
new file mode 100644
index 0000000..11302b2
--- /dev/null
+++ b/docs/source/lang/cc-attribution.txt
@@ -0,0 +1,10 @@
+.. Included in all this directory's files in order to satisfy the
+.. Arduino CC Attribution-ShareAlike 3.0 License
+
+.. admonition:: License and Attribution
+
+ Some information in this page was adapted from the `Arduino
+ Reference Documentation
+ <http://arduino.cc/en/Reference/HomePage>`_\ , which is released
+ under a `Creative Commons Attribution-ShareAlike 3.0 License
+ <http://creativecommons.org/licenses/by-sa/3.0/>`_.
diff --git a/docs/source/lang/cpp/arithmetic.rst b/docs/source/lang/cpp/arithmetic.rst
new file mode 100644
index 0000000..cef3954
--- /dev/null
+++ b/docs/source/lang/cpp/arithmetic.rst
@@ -0,0 +1,124 @@
+.. highlight:: cpp
+
+.. _lang-arithmetic:
+
+Arithmetic Operators (``+``, ``-``, ``*``, ``/``)
+=================================================
+
+The operators ``+``, ``-``, ``*``, and ``/`` respectively evaluate to
+the sum, difference, product, or quotient (respectively) of the two
+operands. The operation is conducted using the data type of the
+operands, so, for example, ``9 / 4`` gives ``2`` since 9 and 4 are
+:ref:`int variables <lang-int>`.
+
+This also means that the operation can overflow if the result is
+larger than that which can be stored in the data type (e.g. adding 1
+to an :ref:`lang-int` with the value 2,147,483,647 gives
+-2,147,483,648).
+
+.. _lang-arithmetic-typeconversion:
+
+If the operands are of different types, the "larger" type is used for
+the calculation. If one of the numbers (operands) are of the type
+**float** or of type **double**, floating point math will be used for
+the calculation.
+
+.. note:: The specifics of these rules are beyond the scope of this
+ documentation; for more information, see `The C++ Programming
+ Language <http://www2.research.att.com/~bs/3rd.html>`_\ , by Bjarne
+ Stroustroup, Appendix C, especially §§C.4-C.6, or `this WikiBooks
+ entry on C++ type conversion
+ <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Variables/Type_Casting#Automatic_type_conversion>`_.
+
+.. note:: For more information on how computers represent integers,
+ see the Wikipedia page on `two's complement
+ <http://en.wikipedia.org/wiki/Two's_complement>`_.
+
+.. contents:: Contents
+ :local:
+
+Examples
+--------
+
+ ::
+
+ y = y + 3;
+ x = x - 7;
+ i = j * 6;
+ r = r / 5;
+
+
+Syntax
+------
+
+ ::
+
+ result = value1 + value2;
+ result = value1 - value2;
+ result = value1 * value2;
+ result = value1 / value2;
+
+
+Parameters
+----------
+
+**value1**: any numeric variable or constant
+
+**value2**: any numeric variable or constant
+
+Programming Tips
+----------------
+
+- Know that :ref:`integer constants <lang-constants-integers>`
+ default to :ref:`int <lang-int>`, so some constant calculations
+ may overflow (e.g., 200000 * 5000000 will yield a negative result).
+
+- Choose variable sizes that are large enough to hold the largest
+ results from your calculations.
+
+- Know at what point your variable will "roll over" and also what
+ happens in the other direction e.g. (0 - 1) for unsigned arithmetic,
+ or (0 - -2,147,483,648) for signed arithmetic.
+
+- For math that requires fractions, float variables may be used, but
+ be aware of their drawbacks: large size and slow computation speeds
+ (the STM32 has no floating point hardware, so all floating point
+ calculations have to be done in software).
+
+- Use cast operator, e.g. ``(int)myFloat`` to convert one variable type
+ to another on the fly.
+
+Arduino Compatibility
+---------------------
+
+Since the STM32 processor on the Maple is a 32-bit machine, the int
+type overflows at a much higher value on Maple than on Arduino. In
+particular, on Maple, ints do not overflow (become negative) until
+they reach 2,147,483,648; on the Arduino, they overflow at 32,767.
+Because of this, programs running on Maple are much less likely to run
+into overflow issues. The following table summarizes the sizes and
+ranges of integer datatypes on the Maple (the ranges of ``long long``
+types are approximate):
+
+.. _lang-arithmetic-int-sizes:
+
+.. csv-table::
+ :header: Datatype, Unsigned range, Signed range, Size (bytes)
+ :widths: 8, 12, 17, 8
+
+ ``char``, 0 --- 255, -128 --- 127, 1
+ ``short``, "0 --- 65,535", "-32,768 --- 32,767", 2
+ ``int``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4
+ ``long``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4
+ ``long long``, "0 --- 1.8*10\ :sup:`19`\ " (approx.), "-9.2*10\ :sup:`18` --- 9.2*10\ :sup:`18` (approx.)", 8
+
+
+See Also
+--------
+
+- The individual sizes (in bits) of various available types are
+ defined in :ref:`libmaple_types.h <libmaple-libmaple_types>`.
+
+- :ref:`sizeof <lang-sizeof>`\ ()
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/array.rst b/docs/source/lang/cpp/array.rst
new file mode 100644
index 0000000..39d4d91
--- /dev/null
+++ b/docs/source/lang/cpp/array.rst
@@ -0,0 +1,121 @@
+.. highlight:: cpp
+
+.. _lang-array:
+
+Arrays
+======
+
+An array is a collection of variables that are accessed with an index
+number. Arrays in the C++ programming language, in which the Maple is
+programmed, can be complicated, but using simple arrays is relatively
+straightforward.
+
+.. contents:: Contents
+ :local:
+
+Creating (Declaring) an Array
+-----------------------------
+
+All of the methods below are valid ways to create (declare) an
+array. ::
+
+ int myInts[6];
+ int myPins[] = {2, 4, 8, 3, 6};
+ int mySensVals[6] = {2, 4, -8, 3, 2};
+ char message[6] = "hello";
+
+You can declare an array without initializing it, as with myInts. In
+the line referring to myPins, we declare an array without explicitly
+choosing a size. The compiler counts the elements and creates an
+array of the appropriate size.
+
+Finally, you can both initialize and size your array, as in
+mySensVals. Note that when declaring an array with elements of type
+char, one more element than your initialization is required, to hold
+the required `null character <http://en.wikipedia.org/wiki/Null-terminated_string>`_.
+
+
+Accessing an Array
+------------------
+
+
+.. compound::
+
+ Arrays are **zero indexed**; that is, referring to the array
+ initialization above, the first element of the array is at index 0,
+ hence ::
+
+ mySensVals[0] == 2;
+ mySensVals[1] == 4
+
+ and so forth.
+
+It also means that in an array with ten elements, index nine is the
+last element. Hence::
+
+ int myArray[10]={9,3,2,4,3,2,7,8,9,11};
+ // myArray[9] contains 11
+ // myArray[10] is invalid and contains random information (other memory address)
+
+For this reason, you should be careful in accessing arrays. Accessing
+past the end of an array (using an index number greater than your
+declared array size - 1) is reading from memory that is in use for
+other purposes. Reading from these locations is probably not going to
+do much except yield invalid data. Writing to random memory locations
+is definitely a bad idea, and can often lead to unhappy results such
+as crashes or program malfunction. This can also be a difficult bug to
+track down.
+
+Unlike Basic or Java, the C compiler does no checking to see if array
+access is within legal bounds of the array size that you have
+declared.
+
+
+To assign a value to an array
+-----------------------------
+ ::
+
+ mySensVals[0] = 10;
+
+
+To retrieve a value from an array
+---------------------------------
+
+ ::
+
+ x = mySensVals[4];
+
+
+Arrays and ``for`` Loops
+------------------------
+
+Arrays are often manipulated inside :ref:`for loops <lang-for>`, where
+the loop counter is used as the index for each array element. For
+example, to print the elements of an array over the serial port, you
+could do something like this::
+
+ int i;
+ for (i = 0; i < 5; i = i + 1) {
+ SerialUSB.println(myPins[i]);
+ }
+
+
+Example
+-------
+
+For a complete program that demonstrates the use of arrays, see the
+Arduino `Knight Rider example
+<http://www.arduino.cc/en/Tutorial/KnightRider>`_\ (which will run
+unmodified on the Maple).
+
+Arduino Compatibility
+---------------------
+
+Arrays on Maple are identical those on Arduino.
+
+See Also
+--------
+
+- :ref:`Storing arrays in FLASH memory <arm-gcc-attribute-flash>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/assignment.rst b/docs/source/lang/cpp/assignment.rst
new file mode 100644
index 0000000..6379298
--- /dev/null
+++ b/docs/source/lang/cpp/assignment.rst
@@ -0,0 +1,60 @@
+.. highlight:: cpp
+
+.. _lang-assignment:
+
+Assignment Operator (``=``)
+===========================
+
+Stores the value to the right of the equal sign in the variable to
+the left of the equal sign.
+
+The single equal sign in the C++ programming language is called the
+assignment operator. It has a different meaning than in algebra
+class, where it indicated an equation or equality. The assignment
+operator tells the microcontroller to evaluate whatever value or
+expression is on the right side of the equal sign, and store it in
+the variable to the left of the equal sign [#fgross]_.
+
+Example
+-------
+
+::
+
+ int sensVal; // declare an integer variable named sensVal
+ sensVal = analogRead(0); // store the (digitized) input voltage at analog pin 0 in sensVal
+
+Programming Tips
+----------------
+
+The variable on the left side of the assignment operator (``=`` sign)
+needs to be able to hold the value stored in it. If it is not large
+enough to hold a value, the value stored in the variable will be
+incorrect.
+
+Don't confuse the assignment operator ``=`` (single equal sign) with
+the comparison operator ``==`` (double equal signs), which evaluates
+whether two expressions are equal.
+
+Arduino Compatibility
+---------------------
+
+Assignments on the Maple are identical to those on Arduino.
+
+See Also
+--------
+
+- :ref:`if <lang-if>`
+- :ref:`char <lang-char>`
+- :ref:`int <lang-int>`
+- :ref:`long long <lang-longlong>`
+
+.. rubric:: Footnotes
+
+.. [#fgross] Experienced C++ programmers know this to be an
+ oversimplification of what happens when the variable on the left
+ hand side is an object. See Richard Gillam's wonderful and scary
+ `The Anatomy of the Assignment Operator
+ <http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html>`_
+ for more information.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/bitshift.rst b/docs/source/lang/cpp/bitshift.rst
new file mode 100644
index 0000000..47413f2
--- /dev/null
+++ b/docs/source/lang/cpp/bitshift.rst
@@ -0,0 +1,143 @@
+.. highlight:: cpp
+
+.. _lang-bitshift:
+
+Bit Shift Operators (``<<``, ``>>``)
+====================================
+
+(Adapted from `The Bit Math Tutorial
+<http://www.arduino.cc/playground/Code/BitMath>`_ in `The Arduino
+Playground <http://www.arduino.cc/playground/Main/HomePage>`_\ )
+
+There are two bit shift operators in C++: the left shift operator
+``<<`` and the right shift operator ``>>``. These operators cause the
+bits in the left operand to be shifted left or right by the number of
+positions specified by the right operand.
+
+More information on bitwise math can be obtained in the Wikipedia
+article on `bitwise operations
+<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ , especially the
+section on shifts in `C, C++, and Java
+<http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23_and_Java>`_\ .
+
+
+Syntax
+------
+
+``some_int << number_of_bits``
+
+``some_int >> number_of_bits``
+
+
+Parameters
+----------
+
+* **some_int** An integer value or variable.
+
+* **number_of_bits** integer whose value is at most ``8 *
+ sizeof(variable)`` (so ``number_of_bits`` can be at most 32 for
+ ``int`` values, at most ``8`` for ``char`` values, etc.; the various
+ integer sizes are summarized :ref:`in this table
+ <lang-arithmetic-int-sizes>`\ ).
+
+
+
+Example:
+--------
+
+Here are some examples of bit shifting, with the binary representation of the number in comments::
+
+ int a = 5; // binary: 101
+ int b = a << 3; // binary: 101000, or 40 in decimal
+ int c = b >> 3; // binary: 101, or back to 5 like we started with
+
+
+When you left shift a value x by y bits (x << y), the leftmost y bits
+in x are lost, literally shifted out of existence. We'll do this
+example with ``char`` values (which are integers in the range 0-255,
+and take up 8 bits of memory)::
+
+ char a = 5; // binary (all 8 bits): 00000101
+ char b = a << 7; // binary: 10000000 - the first 1 in 101 was discarded
+
+
+If you are certain that none of the ones in a value are being shifted
+into oblivion, a simple way to think of the left-shift operator is
+that it multiplies the left operand by 2 raised to the right operand
+power (in math notation, ``x << y`` equals x * 2\ :sup:`y`\ , as long
+as none of the bits of x get shifted out). For example, to generate
+powers of 2, the following expressions can be employed::
+
+ 1 << 0 == 1
+ 1 << 1 == 2
+ 1 << 2 == 4
+ 1 << 3 == 8
+ ...
+ 1 << 8 == 256
+ 1 << 9 == 512
+ 1 << 10 == 1024
+ ...
+
+.. _lang-bitshift-signbit-gotcha:
+
+When you shift x right by y bits (``x >> y``), and the highest bit in
+x is a 1, the behavior depends on the exact data type of x. If x is of
+type ``int``, the highest bit is special, and determines whether x is
+negative or not; the details are too complicated to explain here, but
+they are thoroughly explained in the Wikipedia article on `two's
+complement arithmetic
+<http://en.wikipedia.org/wiki/Two%27s_complement>`_\ , which the
+system most computers use to store integers. In that case, the sign
+bit is copied into lower bits, for esoteric historical reasons::
+
+ int x = -16; // binary (all 32 bits): 11111111111111111111111111110000
+ int y = x >> 3; // binary: 11111111111111111111111111111110
+
+
+
+This behavior, called "sign extension", is often not what you
+want. You probably wish zeros to be shifted in from the left. It
+turns out that the right shift rules are different for ``unsigned
+int`` values, so you can use a type cast to suppress ones being copied
+from the left::
+
+ int x = -16; // binary: 11111111111111111111111111110000
+ int y = (unsigned int)x >> 3; // binary: 00011111111111111111111111111110
+
+
+
+If you are careful to avoid sign extension, you can use the
+right-shift operator, ``>>``, as a way to divide by powers of 2. For
+example::
+
+ int x = 1000;
+ int y = x >> 3; // integer division of 1000 by 8, causing y = 125.
+
+
+Arduino Compatibility
+---------------------
+
+Since it's part of the C++ language, bit shifting on the Maple is
+compatible with the Arduino; however, you should keep in mind that the
+Maple has bigger integer types (as in, more bits) than the Arduino.
+
+Since the STM32 is a 32-bit processor, the ``int`` type takes up 32
+bits instead of 16, like on Arduino's 16-bit microcontroller. This
+means that you can shift left, like ``x << y``, with bigger values of
+``y`` on the Maple before ones in ``x`` start to get shifted out.
+
+To calculate the number of bits of an integer type on the Maple,
+multiply its size in bytes (see :ref:`this table
+<lang-arithmetic-int-sizes>` for these) by 8, since there are 8
+bits in 1 byte. For example, a ``short`` takes up 2 bytes of memory,
+or 2 * 8 = 16 bits.
+
+See Also
+--------
+
+- :ref:`lang-bit`
+- :ref:`lang-bitread`
+- :ref:`lang-bitwrite`
+- :ref:`lang-bitclear`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/bitwisemath.rst b/docs/source/lang/cpp/bitwisemath.rst
new file mode 100644
index 0000000..cfe34f2
--- /dev/null
+++ b/docs/source/lang/cpp/bitwisemath.rst
@@ -0,0 +1,185 @@
+.. highlight:: cpp
+
+.. _lang-bitwisemath:
+
+Bitwise Operators (``&``, ``|``, ``^``, ``~``)
+==============================================
+
+The bitwise operators perform their calculations at the bit level of
+variables. They help solve a wide range of common programming
+problems.
+
+Much of the material here is adapted for Maple from an (Arduino)
+`tutorial on bitwise math
+<http://www.arduino.cc/playground/Code/BitMath>`_\ . Another great
+resource is the Wikipedia article on `bitwise operations
+<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ .
+
+Below are descriptions and syntax for all of the operators.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-bitwisemath-and:
+
+Bitwise AND (``&``)
+-------------------
+
+The bitwise AND operator in C++ is a single ampersand, ``&``, used
+between two other integer expressions. Bitwise AND operates on each
+bit position of the surrounding expressions independently, according
+to this rule: if both input bits are 1, the resulting output is 1,
+otherwise the output is 0. Another way of expressing this is::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 0 0 1 (operand1 & operand2) = result
+
+
+On the Maple, the type ``int`` is a 32-bit value, so using ``&``
+between two ``int`` expressions causes 32 simultaneous AND operations
+to occur. In a code fragment like::
+
+ int a = 92; // in binary: 00000000000000000000000001011100
+ int b = 101; // in binary: 00000000000000000000000001100101
+ int c = a & b; // result: 00000000000000000000000001000100,
+ // (or 68 in decimal).
+
+
+Each of the 32 bits in ``a`` and ``b`` are processed using bitwise
+AND, and all 32 resulting bits are stored in ``c``, resulting in the
+value 1000100 in binary, which is 68 in decimal.
+
+
+.. _lang-bitwisemath-or:
+
+Bitwise OR (``|``)
+------------------
+
+The bitwise OR operator in C++ is the vertical bar symbol, ``|``. Like
+the ``&`` operator, ``|`` operates independently on each bit in its
+two surrounding integer expressions, but what it does is
+different. The bitwise OR of two bits is 1 if either or both of the
+input bits is 1, otherwise it is 0. For example::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 1 1 1 (operand1 | operand2) = result
+
+Here is an example of bitwise OR used in a snippet of C++ code (using
+``char``, which takes up 8 bits of memory, instead of ``int``, which
+uses 32)::
+
+ char a = 92; // in binary: 01011100
+ char b = 101; // in binary: 01100101
+ char c = a | b; // result: 01111101, or 125 in decimal.
+
+.. _lang-bitwisemath-xor:
+
+Bitwise XOR (``^``)
+-------------------
+
+There is a somewhat unusual operator in C++ called bitwise EXCLUSIVE
+OR, also known as bitwise XOR. (In English, this is usually pronounced
+"zor" or "ex-or"). The bitwise XOR operator is written using the caret
+symbol, ``^``. This operator is very similar to the bitwise OR
+operator ``|``, except it evaluates to 0 for a given bit position when
+both of the input bits for that position are 1::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 1 1 0 (operand1 ^ operand2) = result
+
+
+Another way to look at bitwise XOR is that each bit in the result
+is a 1 if the input bits are different, or 0 if they are the same.
+
+Here is a simple example::
+
+ int x = 12; // binary (ignoring extra bits): 1100
+ int y = 10; // binary: 1010
+ int z = x ^ y; // binary: 0110, or decimal 6
+
+
+
+The ^ operator is often used to toggle (i.e. change from 0 to 1, or 1
+to 0) some of the bits in an integer expression. In a bitwise OR
+operation if there is a 1 in the mask bit, that bit is inverted; if
+there is a 0, the bit is not inverted and stays the same. Below is a
+program to toggle the built-in LED pin (you can also accomplish this
+with :ref:`lang-toggleled`)::
+
+ // Toggle built-in LED pin
+
+ int toggle = 0;
+
+ // demo for Exclusive OR
+ void setup(){
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ }
+
+ void loop(){
+ toggle = toggle ^ 1;
+ digitalWrite(BOARD_LED_PIN, toggle);
+ delay(100);
+ }
+
+.. _lang-bitwisemath-not:
+
+Bitwise NOT (``~``)
+-------------------
+
+The bitwise NOT operator in C++ is the tilde character ``~``. Unlike
+``&`` and ``|``, the bitwise NOT operator is applied to a single
+operand to its right. Bitwise NOT changes each bit to its opposite: 0
+becomes 1, and 1 becomes 0. For example::
+
+ 0 1 operand1
+ ----
+ 1 0 ~operand1 = result
+
+Another example::
+
+ char a = 103; // binary: 01100111
+ char b = ~a; // binary: 10011000 = -104
+
+You might be surprised to see a negative number like -104 as the
+result of this operation. This is because the highest bit in an int
+variable is the so-called "sign bit". If the highest bit is 1, the
+number is interpreted as negative. This encoding of positive and
+negative numbers is referred to as *two's complement*. For more
+information, see the Wikipedia article on `two's
+complement. <http://en.wikipedia.org/wiki/Twos_complement>`_
+
+As an aside, it is interesting to note that (under two's complement
+arithmetic) for any integer ``x``, ``~x`` is the same as ``-x-1``.
+
+At times, the sign bit in a signed integer expression can cause
+some unwanted surprises.
+
+
+Uses
+----
+
+One of the most common uses of bitwise operations is to select or
+manipulate a particular bit (or bits) from an integer value, often
+called `bit masking
+<http://en.wikipedia.org/wiki/Mask_%28computing%29>`_\ . See the
+linked Wikipedia article for more information and examples.
+
+If you really want to see bit-twiddling techniques in their full
+glory, you could do much worse than to get yourself a copy of
+`Hacker's Delight <http://www.hackersdelight.org/>`_\ .
+
+
+See Also
+--------
+
+- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``)
+- :ref:`Compound bitwise operations <lang-compoundbitwise>` (``&=``,
+ ``|=``, ``^=``).
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/boolean.rst b/docs/source/lang/cpp/boolean.rst
new file mode 100644
index 0000000..f09345e
--- /dev/null
+++ b/docs/source/lang/cpp/boolean.rst
@@ -0,0 +1,90 @@
+.. highlight:: cpp
+
+.. _lang-boolean:
+
+Boolean Operators
+=================
+
+These can be used inside the condition of an :ref:`if <lang-if>`
+statement. Evaluate to :ref:`true <lang-constants-true>` or
+:ref:`false <lang-constants-false>`.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-boolean-and:
+
+&& (logical and)
+----------------
+
+True only if both operands are true. For example::
+
+ if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) { // read two switches
+ // ...
+ }
+
+is true only if both inputs are high. Another example::
+
+ if (a >= 10 && a <= 20){} // true if a is between 10 and 20
+
+**Be careful** not to say ``10 <= a <= 20``! This won't work the way
+you want. You have to separately test whether ``a`` is at least 10
+using ``a >= 10``, then test whether ``a`` is at most 20 using ``a <=
+20``, then combine the results using ``&&``.
+
+
+.. _lang-boolean-or:
+
+\|\| (logical or)
+-----------------
+
+True if either operand is true. For example::
+
+ if (x > 0 || y > 0) {
+ // ...
+ }
+
+is true if either ``x`` or ``y`` is greater than 0.
+
+.. _lang-boolean-not:
+
+! (logical not)
+---------------
+
+True if the operand is false. For example::
+
+ if (!x) {
+ // ...
+ }
+
+is true if ``x`` is false (i.e. if ``x`` is zero).
+
+Some Advice
+-----------
+
+.. warning::
+
+ Make sure you don't mistake the boolean AND operator ``&&``
+ (double ampersand) for the :ref:`bitwise AND operator
+ <lang-bitwisemath-and>` ``&`` (single ampersand). They are
+ entirely different beasts.
+
+ Similarly, do not confuse the boolean OR operator ``||`` (double
+ pipe) with the :ref:`bitwise OR operator <lang-bitwisemath-or>`
+ ``|`` (single pipe).
+
+ The :ref:`bitwise NOT operator <lang-bitwisemath-not>` ``~``
+ (tilde) looks much different than the boolean not operator ``!``
+ (exclamation point, or "bang", as some programmers say), but you
+ still have to be sure which one you want.
+
+
+See Also
+--------
+
+- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``)
+- :ref:`Compound bitwise operators <lang-compoundbitwise>` (``&=``,
+ ``|=``, ``^=``).
+- :ref:`if statement <lang-if>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/booleanvariables.rst b/docs/source/lang/cpp/booleanvariables.rst
new file mode 100644
index 0000000..e032c74
--- /dev/null
+++ b/docs/source/lang/cpp/booleanvariables.rst
@@ -0,0 +1,47 @@
+.. highlight:: cpp
+
+.. _lang-booleanvariables:
+
+Booleans
+========
+
+A **boolean** holds one of two values, :ref:`true
+<lang-constants-true>` or :ref:`false <lang-constants-false>`. On a
+Maple, each boolean variable has type ``bool``.
+
+.. warning::
+
+ On an Arduino, the type ``boolean`` is also provided. While the
+ Maple also has this type for compatibility, **its use is strongly
+ discouraged**. The ``bool`` type is a standard part of C++, while
+ ``boolean`` is a non-standard extension that serves no purpose.
+
+Example
+-------
+
+::
+
+ // running is a boolean variable:
+ bool running = false;
+
+ void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ pinMode(BOARD_BUTTON_PIN, INPUT);
+ }
+
+ void loop() {
+ if (isButtonPressed()) {
+ // button is pressed
+ running = !running; // toggle running variable
+ digitalWrite(BOARD_LED_PIN, running) // indicate via LED
+ }
+ }
+
+See Also
+--------
+
+- :ref:`Boolean constants <lang-constants-bool>`
+- :ref:`Boolean operators <lang-boolean>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/break.rst b/docs/source/lang/cpp/break.rst
new file mode 100644
index 0000000..f367b99
--- /dev/null
+++ b/docs/source/lang/cpp/break.rst
@@ -0,0 +1,32 @@
+.. highlight:: cpp
+
+.. _lang-break:
+
+``break``
+=========
+
+``break`` is used to exit from a :ref:`while <lang-while>`\ ,
+:ref:`for <lang-for>`\ , or :ref:`do/while <lang-dowhile>` loop,
+bypassing the normal loop condition. It is also used to exit from a
+:ref:`switch <lang-switchcase>` statement.
+
+
+Example
+-------
+
+::
+
+ for (x = 0; x < 255; x ++)
+ {
+ digitalWrite(PWMpin, x);
+ sens = analogRead(sensorPin);
+ if (sens > threshold){ // bail out on sensor detect
+ x = 0;
+ // this line of code means that we'll immediately exit
+ // from the "for" loop:
+ break;
+ }
+ delay(50);
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/built-in-types.rst b/docs/source/lang/cpp/built-in-types.rst
new file mode 100644
index 0000000..f14dce5
--- /dev/null
+++ b/docs/source/lang/cpp/built-in-types.rst
@@ -0,0 +1,108 @@
+.. highlight:: cpp
+
+.. _lang-built-in-types:
+
+================
+ Built-in Types
+================
+
+This document serves as a reference for many of the built-in types
+which are available when programming in the IDE. Programmers using
+the :ref:`command-line tools <unix-toolchain>` will have access to
+these types as long as they have imported `wirish.h
+<https://github.com/leaflabs/libmaple/blob/master/wirish/wirish.h>`_;
+several are defined in in `libmaple_types.h
+<https://github.com/leaflabs/libmaple/blob/master/libmaple/libmaple_types.h>`_.
+
+.. _lang-built-in-types-integral:
+
+Integral types
+--------------
+
+.. cpp:type:: char
+
+ 8-bit integer value.
+
+.. cpp:type:: short
+
+ 16-bit integer value.
+
+.. cpp:type:: int
+
+ 32-bit integer value.
+
+.. cpp:type:: long
+
+ 32-bit integer value.
+
+.. cpp:type:: long long
+
+ 64-bit integer value.
+
+.. cpp:type:: int8
+
+ 8-bit integer value. Synonym for ``signed char``.
+
+.. cpp:type:: uint8
+
+ 8-bit unsigned integer value. Synonym for ``unsigned char``.
+
+.. cpp:type:: byte
+
+ 8-bit unsigned integer value. Synonym for ``unsigned char``.
+
+.. cpp:type:: int16
+
+ 16-bit integer value. Synonym for ``short``.
+
+.. cpp:type:: uint16
+
+ 16-bit unsigned integer value. Synonym for ``unsigned short``.
+
+.. cpp:type:: int32
+
+ 32-bit integer value. Synonym for ``int``.
+
+.. cpp:type:: uint32
+
+ Unsigned 32-bit integer value. Synonym for ``unsigned int``
+
+.. cpp:type:: int64
+
+ 64-bit integer value. Synonym for ``long long``
+
+.. cpp:type:: uint64
+
+ Unsigned 64-bit integer value. Synonym for ``unsigned long long``.
+
+Floating-Point Types
+--------------------
+
+.. cpp:type:: float
+
+ 32-bit, IEEE-754 single-precision floating-point type.
+
+.. cpp:type:: double
+
+ 64-bit, IEEE-754 double-precision floating-point type.
+
+Miscellaneous Types
+-------------------
+
+.. cpp:type:: voidFuncPtr
+
+ Pointer to a function that takes no arguments and returns nothing, i.e. ::
+
+ typedef void (*voidFuncPtr)(void);
+
+.. cpp:type:: bool
+
+ Boolean type.
+
+Other
+-----
+
+.. cpp:type:: void
+
+ Not really a type. To be honest with you, this only exists here to
+ silence warnings from our documentation build system.
diff --git a/docs/source/lang/cpp/byte.rst b/docs/source/lang/cpp/byte.rst
new file mode 100644
index 0000000..4634594
--- /dev/null
+++ b/docs/source/lang/cpp/byte.rst
@@ -0,0 +1,33 @@
+.. highlight:: cpp
+
+.. _lang-byte:
+
+byte
+====
+
+The ``byte`` type stores a 1-byte (8-bit) unsigned integer number,
+from 0 to 255.
+
+.. warning::
+
+ The ``byte`` type is provided for compatibility with Arduino.
+ However, it is a non-standard extension. The standard C++ type for
+ storing an 8-bit unsigned integer is ``unsigned char``; we
+ recommend using that instead. (Your code will still work on an
+ Arduino).
+
+
+Example
+-------
+
+::
+
+ byte b = 134;
+
+See Also
+--------
+
+- :ref:`byte() <lang-bytecast>` (casting a value to a byte)
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/bytecast.rst b/docs/source/lang/cpp/bytecast.rst
new file mode 100644
index 0000000..24c3b9e
--- /dev/null
+++ b/docs/source/lang/cpp/bytecast.rst
@@ -0,0 +1,44 @@
+.. highlight:: cpp
+
+.. _lang-bytecast:
+
+byte() (cast)
+=============
+
+Converts a value to the :ref:`byte <lang-byte>` data type.
+
+.. note::
+
+ Casting to the byte type is provided for compatibility with
+ Arduino. However, the recommended Maple type for storing an 8-bit
+ unsigned integer is ``uint8``. (C and C++ programmers: ``stdint.h``
+ is also available).
+
+ In order to cast a variable ``x`` to a ``uint8``, the
+ following syntax can be used::
+
+ uint8(x);
+
+Syntax
+------
+
+``byte(x)``
+
+Parameters
+----------
+
+**x**: a value of any integer type
+
+Returns
+-------
+
+The value, converted to a ``byte``. Note, however, that if the value
+is larger than the maximum value you can store in a byte (255), then
+the results might be strange and unexpected.
+
+See Also
+--------
+
+- :ref:`lang-byte`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/cc-attribution.txt b/docs/source/lang/cpp/cc-attribution.txt
new file mode 100644
index 0000000..e100140
--- /dev/null
+++ b/docs/source/lang/cpp/cc-attribution.txt
@@ -0,0 +1,9 @@
+.. Included in all this directory's files in order to satisfy the
+.. Arduino CC Attribution-ShareAlike 3.0 License
+
+.. admonition:: License and Attribution
+
+ This documentation page was adapted from the `Arduino Reference
+ Documentation <http://arduino.cc/en/Reference/HomePage>`_\ , which
+ is released under a `Creative Commons Attribution-ShareAlike 3.0
+ License <http://creativecommons.org/licenses/by-sa/3.0/>`_.
diff --git a/docs/source/lang/cpp/char.rst b/docs/source/lang/cpp/char.rst
new file mode 100644
index 0000000..686c0d1
--- /dev/null
+++ b/docs/source/lang/cpp/char.rst
@@ -0,0 +1,44 @@
+.. highlight:: cpp
+
+.. _lang-char:
+
+``char``
+========
+
+The ``char`` type stores a 1-byte character value (or integer with
+value from -128 to 127). Character literals are written in single
+quotes, like this: ``'A'`` (for multiple characters - strings - use
+double quotes: ``"ABC"``).
+
+Just like everything else on a computer, characters are stored as
+numbers. You can see the specific encoding in the `ASCII chart
+<http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters>`_\
+. This means that it is possible to do arithmetic on characters, in
+which the ASCII value of the character is used (e.g. ``'A' + 1`` has the
+decimal value 66, since the ASCII value of the capital letter A in
+decimal is 65). See the :ref:`Serial.println()
+<lang-serial-println>` documentation for more information about how
+characters are converted into numbers.
+
+The ``char`` datatype is a signed type, meaning that it encodes
+numbers from -128 to 127. For an unsigned type, which stores values
+from 0 to 255, just use the type ``unsigned char`` (two words).
+
+Example
+-------
+
+::
+
+ // The following two lines are equivalent, using the ASCII
+ // character encoding:
+ char c = 'A';
+ char c = 65;
+
+See Also
+--------
+
+- :ref:`lang-int`
+- :ref:`lang-array` (a string is just an array of ``char``\ s)
+- :ref:`Serial.println() <lang-serial-println>`
+
+.. include:: cc-attribution.txt
diff --git a/docs/source/lang/cpp/charcast.rst b/docs/source/lang/cpp/charcast.rst
new file mode 100644
index 0000000..640ad85
--- /dev/null
+++ b/docs/source/lang/cpp/charcast.rst
@@ -0,0 +1,32 @@
+.. highlight:: cpp
+
+.. _lang-charcast:
+
+``char()`` (cast)
+=================
+
+Converts a value to the :ref:`char <lang-char>` data type.
+
+Syntax
+------
+
+``char(x)``
+
+Parameters
+----------
+
+**x**: a value of any type
+
+Returns
+-------
+
+The value, converted to a ``char``. Note, however, that if the value
+is outside the range of a ``char`` (-128 to 127), then the results
+might be strange and unexpected.
+
+See Also
+--------
+
+- :ref:`char <lang-char>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/comments.rst b/docs/source/lang/cpp/comments.rst
new file mode 100644
index 0000000..1428dc3
--- /dev/null
+++ b/docs/source/lang/cpp/comments.rst
@@ -0,0 +1,64 @@
+.. highlight:: cpp
+
+.. _lang-comments:
+
+Comments
+========
+
+Comments are lines in the program that are used to inform yourself or
+others about the way the program works. They are ignored by the
+compiler, and not exported to the processor, so they don't take up any
+space in RAM or Flash.
+
+One use for comments is to help you understand (or remember) how your
+program works, or to inform others how your program works. There are
+two different ways of making comments.
+
+.. _lang-comments-singleline:
+
+**Single line comment**: Anything following two slashes, ``//``, until
+the end of the line, is a comment::
+
+ x = 5; // the rest of this line is a comment
+
+.. _lang-comments-multiline:
+
+**Multi-line comment**: Anything in between a pair of ``/*`` and ``*/``
+is a comment::
+
+ /* <-- a slash-star begins a multi-line comment
+
+ all of this in the multi-line comment - you can use it to comment
+ out whole blocks of code
+
+ if (gwb == 0){ // single line comment is OK inside a multi-line comment
+ x = 3;
+ }
+
+ // don't forget the "closing" star-slash - they have to be balanced:
+ */
+
+Note that it's okay to use single-line comments within a multi-line
+comment, but you can't use multi-line comments within a multi-line
+comment. Here's an example::
+
+ /* ok, i started a multi-line comment
+
+ x = 3; /* this next star-slash ENDS the multi-line comment: */
+
+ x = 4; // this line is outside of the multi-line comment
+
+ // next line is also outside of the comment, and causes a compile error:
+ */
+
+Programming Tip
+---------------
+
+When experimenting with code, "commenting out" parts of your program
+is a convenient way to remove lines that may be buggy. This leaves
+the lines in the code, but turns them into comments, so the compiler
+just ignores them. This can be especially useful when trying to locate
+a problem, or when a program refuses to compile and the compiler error
+is cryptic or unhelpful.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/comparison.rst b/docs/source/lang/cpp/comparison.rst
new file mode 100644
index 0000000..9cd0a9f
--- /dev/null
+++ b/docs/source/lang/cpp/comparison.rst
@@ -0,0 +1,86 @@
+.. highlight:: cpp
+
+.. _lang-comparison:
+
+Comparison Operators (``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``)
+===================================================================
+
+The comparison operators ``==``, ``!=``, ``<``, ``>``, ``<=``, and
+``>=`` are used to compare two numbers. They are :ref:`true
+<lang-constants-true>` when the comparison is true, and :ref:`false
+<lang-constants-false>` otherwise. They are based on the symbols
+=, ≠, <, >, ≤, and ≥ from mathematics.
+
+Here are some examples, with their meaning in comments::
+
+ // "eq" is true when x is equal to y
+ bool eq = (x == y);
+
+ // "neq" is true when x is different than y
+ bool neq = (x != y);
+
+ // "lt" is true when x is less than, but NOT equal to, y
+ bool lt = (x < y);
+
+ // "gt" is true when x is greater than, but NOT equal to, y
+ bool gt = (x > y);
+
+ // "lte" is true when x is less than or equal to y
+ bool lte = (x <= y);
+
+ // "gte" is true when x is greater than or equal to y
+ bool gte = (x >= y);
+
+The parentheses are optional; they are present only for clarity. For
+example, the following two lines are the same::
+
+ bool eq = x == y;
+
+ bool eq = (x == y);
+
+Uses
+----
+
+Comparison operators, along with :ref:`boolean operators
+<lang-boolean>`, are useful inside the conditionals of :ref:`if
+<lang-if>` statements. Here's one example::
+
+ if (x < 50) {
+ // only execute these lines if x is less than 50
+ SerialUSB.println("delaying:");
+ SerialUSB.println(x);
+ delay(x);
+ }
+
+.. warning::
+ Beware of accidentally using the single equal sign (``=``) when you
+ meant to test if two numbers are equal (``==``). This is a common
+ mistake inside of ``if`` statement conditionals, e.g.::
+
+ // DON'T MAKE THIS MISTAKE
+ if (x = 10) {
+ // body
+ }
+
+ The single equal sign is the assignment operator, and sets x to 10
+ (puts the value 10 into the variable x). Instead use the double equal
+ sign (e.g. ``if (x == 10)``), which is the comparison operator, and
+ tests *whether* x is equal to 10 or not. The latter statement is only
+ true if x equals 10, but the former statement will always be true.
+
+ This is because C evaluates the statement ``if (x=10)`` as follows: 10
+ is assigned to x (remember that the single equal sign is the
+ :ref:`assignment operator <lang-assignment>`), so x now
+ contains 10. Then the 'if' conditional evaluates 10, which evaluates
+ to :ref:`true <lang-constants-true>`, since any non-zero number
+ evaluates to ``true``.
+
+ Consequently, the conditional of an ``if`` statement like ``if (x =
+ 10) {...}`` will always evaluate to ``true``, and the variable x
+ will be set to 10, which is probably not what you meant.
+
+ (This sometimes has uses, though, so just because an assignment
+ appears within a conditional doesn't mean it's automatically wrong.
+ Be careful to know what you mean.)
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/compoundarithmetic.rst b/docs/source/lang/cpp/compoundarithmetic.rst
new file mode 100644
index 0000000..d70a43c
--- /dev/null
+++ b/docs/source/lang/cpp/compoundarithmetic.rst
@@ -0,0 +1,43 @@
+.. highlight:: cpp
+
+.. _lang-compoundarithmetic:
+
+Compound Arithmetic Operators (``+=`` , ``-=``, ``*=``, ``/=``)
+===============================================================
+
+These oparators perform a mathematical operation on a variable with
+another constant or variable. These operators are just a convenient
+shorthand::
+
+ x += y; // equivalent to the expression x = x + y;
+ x -= y; // equivalent to the expression x = x - y;
+ x *= y; // equivalent to the expression x = x * y;
+ x /= y; // equivalent to the expression x = x / y;
+
+Here is an example::
+
+ int x = 2;
+ int y = 10;
+
+ x += 4; // x now contains 6
+ x -= 3; // x now contains 3
+ x *= y; // x now contains 30
+ x /= 2; // x now contains 15
+ x += max(20, 6); // x now contains 35
+ x -= sq(5); // x now contains 15
+
+Parameters
+----------
+
+**x**: a numeric variable
+
+**y**: a numeric variable, number constant, or any other expression
+that evaluates to a number (e.g. call to a function that returns a
+number).
+
+See Also
+--------
+
+- :ref:`Arithmetic operators <lang-arithmetic>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/compoundbitwise.rst b/docs/source/lang/cpp/compoundbitwise.rst
new file mode 100644
index 0000000..4efe5df
--- /dev/null
+++ b/docs/source/lang/cpp/compoundbitwise.rst
@@ -0,0 +1,229 @@
+.. highlight:: cpp
+
+.. _lang-compoundbitwise:
+
+Compound Bitwise Operators (``&=``, ``|=``, ``^=``)
+===================================================
+
+The compound bitwise operators perform their calculations at the
+bit level of variables. They are often used to clear and set
+specific bits of a variable.
+
+See the :ref:`bitwise math tutorial <lang-bitwisemath>` for more
+information on bitwise operators.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-compoundbitwise-and:
+
+Compound bitwise AND (``&=``)
+-----------------------------
+
+The compound bitwise AND operator ``&=`` is often used with a variable
+and a constant to force particular bits in a variable to be zero. This
+is often referred to in programming guides as "clearing" or
+"resetting" bits. In a program, writing the line ``x &= y;`` is
+equivalent to writing ``x = x & y;``. That is, the value of ``x``
+after the line will be equal to its old value bitwise ANDed with the
+value of ``y``::
+
+ x &= y; // equivalent to x = x & y;
+
+You can use any integer variable for ``x`` (i.e., any variable of type
+``int``, ``char``, ``byte``, ``long long``, etc.). You can use either
+an integer variable or any :ref:`integer value
+<lang-constants-integers>` (like ``3`` or ``0x20``) for ``y``.
+
+Before doing an example of ``&=``, let's first review the Bitwise AND
+(``&``) operator::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 0 0 1 (operand1 & operand2) = result
+
+As shown above, bits that are "bitwise ANDed" with 0 become 0, while
+bits that are "bitwise ANDed" with 1 are left unchanged. So, if ``b``
+is a ``byte`` variable, then ``b & B00000000`` equals zero, and ``b &
+B11111111`` equals ``b``.
+
+.. _lang-compoundbitwise-binconst:
+
+.. note:: The above uses :ref:`binary constants
+ <lang-constants-integers-bin>`\ . The numbers are still the same
+ value in other representations, they just might not be as easy to
+ understand.
+
+ Normally, in C and C++ code, :ref:`hexadecimal
+ <lang-constants-integers-hex>` or :ref:`octal
+ <lang-constants-integers-oct>` are used when we're interested in
+ an integer's bits, rather than its value as a number.
+
+ While hexadecimal and octal literals might be harder to understand
+ at first, you should really take the time to learn them. They're
+ part of C, C++, and many other programming languages, while binary
+ constants are available only for compatibility with Arduino.
+
+ Also, ``B00000000`` is shown for clarity, but zero in any number
+ format is zero.
+
+So, to clear (set to zero) bits 0 and 1 of a one-byte variable, while
+leaving the rest of the variable's bits unchanged, use the compound
+bitwise AND operator ``&=`` with the constant ``B11111100``
+(hexadecimal ``0xFC``\ )::
+
+ 1 0 1 0 1 0 1 0 variable
+ 1 1 1 1 1 1 0 0 mask
+ ----------------------
+ 1 0 1 0 1 0 0 0
+ ^^^^^^^^^^^^^^^^ ^^^^
+ unchanged cleared
+
+
+Here is the same representation with the variable's bits replaced
+with the symbol ``x``\ ::
+
+ x x x x x x x x variable
+ 1 1 1 1 1 1 0 0 mask
+ ----------------------
+ x x x x x x 0 0
+ ^^^^^^^^^^^^^^^^ ^^^^
+ unchanged cleared
+
+
+So, using a byte variable ``b``\ , if we say::
+
+ b = B10101010; // B10101010 == 0xAA
+ b &= B11111100; // B11111100 == 0xFC
+
+then we will have ::
+
+ b == B10101000; // B10101000 == 0xA8
+
+.. _lang-compoundbitwise-or:
+
+Compound bitwise OR (``|=``)
+----------------------------
+
+The compound bitwise OR operator ``|=`` is often used with a variable
+and a constant to "set" (set to 1) particular bits in a variable. In
+a program, writing the line ``x |= y;`` is equivalent to writing ``x =
+x | y;``. That is, the value of ``x`` after the line will be equal to
+its old value bitwise ORed with the value of ``y``::
+
+ x |= y; // equivalent to x = x | y;
+
+You can use any integer variable for ``x`` (i.e., any variable of type
+``int``, ``char``, ``long long`` etc.). You can use either an integer
+variable or any integer value (like ``3`` or ``0x20``) for ``y``.
+(This works the same way as :ref:`compound bitwise AND
+<lang-compoundbitwise-and>`\ , ``&=``).
+
+Before doing an example of ``|=``, let's first review the Bitwise OR
+(``|``) operator::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 1 1 1 (operand1 | operand2) = result
+
+Bits that are "bitwise ORed" with 0 are unchanged, while bits that are
+"bitwise ORed" with 1 are set to 1. So if ``b`` is a ``byte``
+variable, then ``b | B00000000`` equals ``b``, and ``b & B11111111``
+equals ``B11111111`` (here we've used binary constants; see the
+:ref:`note <lang-compoundbitwise-binconst>` above).
+
+So, to set bits 0 and 1 of a one-byte variable, while leaving the rest
+of the variable unchanged, use the compound bitwise OR operator
+(``|=``) with the constant ``B00000011`` (hexadecimal ``0x3``)::
+
+ 1 0 1 0 1 0 1 0 variable
+ 0 0 0 0 0 0 1 1 mask
+ ----------------------
+ 1 0 1 0 1 0 1 1
+ ^^^^^^^^^^^^^^^^ ^^^^
+ unchanged set
+
+Here is the same representation with the variable's bits replaced with
+the symbol ``x``::
+
+ x x x x x x x x variable
+ 0 0 0 0 0 0 1 1 mask
+ ----------------------
+ x x x x x x 1 1
+ ^^^^^^^^^^^^^^^^ ^^^^
+ unchanged set
+
+So, using a byte variable ``b``, if we say::
+
+ b = B10101010; // B10101010 == 0xAA
+ b |= B00000011; // B00000011 == 0x3
+
+then we will have ::
+
+ b == B10101011; // B10101011 == 0xAB
+
+.. _lang-compoundbitwise-xor:
+
+Compound bitwise XOR (``^=``)
+-----------------------------
+
+The compound bitwise XOR operator ``^=`` is used with a variable and a
+constant to "toggle" (change 0 to 1, and 1 to 0) particular bits in a
+variable. In a program, writing the line ``x ^= y;`` is equivalent to
+writing ``x = x ^ y;``. That is, the value of ``x`` after the line
+will be equal to its old value bitwise XORed with the value of ``y``::
+
+ x ^= y; // equivalent to x = x ^ y;
+
+You can use any integer variable for ``x`` (i.e., any variable of type
+``int``, ``char``, ``long long``, etc.). You can use either an
+integer variable or any integer value (like ``3`` or ``0x20``) for
+``y``. (This works the same way as :ref:`&=
+<lang-compoundbitwise-and>` and :ref:`\|= <lang-compoundbitwise-or>`;
+in fact, these three operators all work the same in this way).
+
+Before doing an example of ``^=``, let's first review the Bitwise
+XOR operator, ``^``::
+
+ 0 0 1 1 operand1
+ 0 1 0 1 operand2
+ ----------
+ 0 1 1 0 (operand1 ^ operand2) = result
+
+One way to look at bitwise XOR is that each bit in the result is a 1
+if the input bits are different, or 0 if they are the same. Another
+way to think about it is that the result bit will be 1 when *exactly*
+one (no more, no less) of the input bits is 1; otherwise, it will be
+zero. This means that if you XOR a bit with 1, it will change (or
+toggle) its value, while if you XOR a bit with 0, it stays the same.
+
+So, to toggle bits 0 and 1 of a one-byte variable, while leaving the
+rest of the variable unchanged, use the compound bitwise XOR operator
+``^=`` with the constant ``B00000011`` (hexadecimal ``0x3``\ ; see
+:ref:`note <lang-compoundbitwise-binconst>` above)::
+
+ 1 0 1 0 1 0 1 0 variable
+ 0 0 0 0 0 0 1 1 mask
+ ----------------------
+ 1 0 1 0 1 0 1 1
+ ^^^^^^^^^^^^^^^^ ^^^^
+ unchanged toggled
+
+So, using a byte variable ``b``, if we say::
+
+ b = B10101010; // B10101010 == 0xAA
+ b ^= B00000011; // B00000011 == 0x3
+
+then we will have ::
+
+ b == B10101001; // B10101001 == 0xA9
+
+See Also
+--------
+
+- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``)
+- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``)
+
+.. include:: cc-attribution.txt
diff --git a/docs/source/lang/cpp/const.rst b/docs/source/lang/cpp/const.rst
new file mode 100644
index 0000000..ad0c580
--- /dev/null
+++ b/docs/source/lang/cpp/const.rst
@@ -0,0 +1,50 @@
+.. highlight:: cpp
+
+.. _lang-const:
+
+``const``
+=========
+
+The ``const`` keyword stands for "constant". It is a variable
+*qualifier* that modifies the behavior of the variable, making a
+variable "*read-only*". This means that the variable can be used just
+as any other variable of its type, but its value cannot be
+changed. You will get a compiler error if you try to assign a value to
+a ``const`` variable.
+
+Constants defined with the ``const`` keyword obey the same rules of
+:ref:`variable scoping <lang-scope>` that govern other
+variables. This, and the pitfalls of using :ref:`#define
+<lang-define>`, often makes using the ``const`` keyword a superior
+method for defining constants than ``#define``.
+
+Example
+-------
+
+ ::
+
+ // this defines a variable called "pi", which cannot be changed:
+ const float pi = 3.14;
+ float x;
+
+ // ....
+
+ x = pi * 2; // it's fine to find the value of a const variable
+
+ pi = 7; // illegal - you can't write to (modify) a constant
+
+**#define** or **const**
+------------------------
+
+You can use either ``const`` or ``#define`` for creating numeric or
+string constants. For :ref:`arrays <lang-array>`\ , you will need
+to use ``const``. In general, ``const`` is preferred over ``#define``
+for defining constants.
+
+See Also
+--------
+
+- :ref:`#define <lang-define>`
+- :ref:`volatile <lang-volatile>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/continue.rst b/docs/source/lang/cpp/continue.rst
new file mode 100644
index 0000000..2a694f6
--- /dev/null
+++ b/docs/source/lang/cpp/continue.rst
@@ -0,0 +1,30 @@
+.. highlight:: cpp
+
+.. _lang-continue:
+
+``continue``
+============
+
+The ``continue`` keyword skips the rest of the current iteration of a
+:ref:`while <lang-while>`\ , :ref:`for <lang-for>`\ , or
+:ref:`do/while <lang-dowhile>` loop. It continues by checking the
+conditional expression of the loop, and proceeding with any subsequent
+iterations.
+
+Example
+-------
+
+::
+
+
+ for (x = 0; x < 255; x ++) {
+ if (x > 40 && x < 120) { // create jump in values
+ continue; // skips the next two lines and goes to the
+ // beginning of the loop, with the next value of x
+ }
+
+ digitalWrite(PWMpin, x);
+ delay(50);
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/curly-braces.rst b/docs/source/lang/cpp/curly-braces.rst
new file mode 100644
index 0000000..df2fe2a
--- /dev/null
+++ b/docs/source/lang/cpp/curly-braces.rst
@@ -0,0 +1,106 @@
+.. highlight:: cpp
+
+.. _lang-curly-braces:
+
+Curly Braces (``{``, ``}``)
+===========================
+
+.. contents:: Contents
+ :local:
+
+Introduction
+------------
+
+Curly braces (also referred to as just "braces" or as "curly
+brackets") are a major part of the C and C++ programming
+languages. They are used in several different constructs, outlined
+below, and this can sometimes be confusing for beginners.
+
+An opening curly brace, ``{`` must always be followed by a closing
+curly brace ``}``. This is a condition that is often referred to as
+the braces being *balanced*. The Maple IDE (integrated development
+environment) includes a convenient feature to check the balance of
+curly braces. Just select a brace, or even click the insertion point
+immediately following a brace, and its companion will be highlighted\
+[#fbug]_\ .
+
+Beginning programmers, and programmers coming to C++ from languages
+without braces, often find using them confusing or daunting.
+
+Because the use of the curly brace is so varied, it is good
+programming practice to type the closing brace immediately after
+typing the opening brace when inserting a construct which requires
+curly braces. Then insert some blank lines between your braces and
+begin inserting statements. Your braces, and your attitude, will never
+become unbalanced.
+
+Unbalanced braces can often lead to cryptic, impenetrable compiler
+errors that can sometimes be hard to track down in a large program.
+Because of their varied usages, braces are also incredibly important
+to the syntax of a program and moving a brace one or two lines will
+usually dramatically affect the meaning of a program.
+
+The main uses of curly braces
+-----------------------------
+
+**Functions**::
+
+ // a function body needs braces around it
+ void myFunction(datatype argument) {
+ // ... function body goes in here ...
+ }
+
+**Loops** (see the :ref:`while <lang-while>`\ , :ref:`for
+<lang-for>`\ , and :ref:`do/while <lang-dowhile>` loop reference
+pages for more information)::
+
+ // you should put braces around the body of a loop:
+
+ while (boolean expression) {
+ // code inside the loop goes here
+ }
+
+ for (initialisation; termination condition; incrementing expr) {
+ // code inside the loop goes here
+ }
+
+ do {
+ // code inside the loop goes here
+ } while (boolean expression);
+
+
+**Conditional statements** (see the :ref:`if statement <lang-if>`
+reference page for more information)::
+
+ // you should put braces around the body of an "if", "else if",
+ // or "else":
+
+ if (boolean expression) {
+ // code inside the "if"
+ }
+ else if (boolean expression) {
+ // code inside the "else if"
+ }
+ else {
+ // code inside the "else"
+ }
+
+**Switch statements** (see the :ref:`switch statement
+<lang-switchcase>` reference page for more information)::
+
+ switch (var) {
+ case 1:
+ doThing1();
+ break;
+ case 2:
+ doThing2();
+ break;
+ }
+
+.. rubric:: Footnotes
+
+.. [#fbug] At present this feature is slightly buggy as the IDE will
+ often find (incorrectly) a brace in text that has been commented
+ out.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/define.rst b/docs/source/lang/cpp/define.rst
new file mode 100644
index 0000000..b22085f
--- /dev/null
+++ b/docs/source/lang/cpp/define.rst
@@ -0,0 +1,54 @@
+.. highlight:: cpp
+
+.. _lang-define:
+
+``#define``
+===========
+
+``#define`` is a useful C and C++ feature that allows the programmer
+to give a name to a constant value before the program is compiled.
+The compiler will replace references to these constants with the
+defined value at compile time.
+
+This can have some unwanted side effects. In general, the :ref:`const
+<lang-const>` keyword is preferred for defining constants.
+
+Syntax
+------
+
+The following line would define the name ``MY_CONSTANT`` to have value
+``value``::
+
+ #define MY_CONSTANT value
+
+Note that the ``#`` is necessary. It is usually good style for the
+name to be capitalized, although this is not required.
+
+There is no semicolon after the #define statement. If you include one,
+the compiler will likely throw cryptic errors in unrelated places.
+That is, **don't do this**::
+
+ // DON'T DO THIS! THE SEMICOLON SHOULDN'T BE THERE!
+ #define NAME value;
+
+Similarly, including an equal sign after the ``#define`` line will
+also generate a cryptic compiler error further down the page. That
+is, **don't do this, either**::
+
+ // DON'T DO THIS, EITHER! THE EQUALS SIGN SHOULDN'T BE THERE!
+ #define NAME = value
+
+Example
+-------
+
+ ::
+
+ #define MAPLE_LED_PIN 13
+ // The compiler will replace any mention of MAPLE_LED_PIN with
+ // the value 13 at compile time.
+
+See Also
+--------
+- :ref:`const <lang-const>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/double.rst b/docs/source/lang/cpp/double.rst
new file mode 100644
index 0000000..59422eb
--- /dev/null
+++ b/docs/source/lang/cpp/double.rst
@@ -0,0 +1,46 @@
+.. _lang-double:
+
+``double``
+==========
+
+Double precision floating point type. Occupies 8 bytes. On Maple, the
+``double`` type has a range of approximately -1.79769×10^308 to
+1.79769×10^308; the ``double`` type subject to the same :ref:`overflow
+issues <lang-variables-rollover>` as any numeric data type.
+
+Floating point numbers are not exact, and may yield strange results
+when compared. For example ``6.0 / 3.0`` may not equal ``2.0``. You
+should instead check that the absolute value of the difference between
+the numbers is less than some small number.
+
+Floating point math is also much slower than integer math in
+performing calculations, so should be avoided if, for example, a loop
+has to run at top speed for a critical timing function. Programmers
+often go to some lengths to convert floating point calculations to
+integer math to increase speed.
+
+For more information, see the `Wikipedia article on floating point
+math <http://en.wikipedia.org/wiki/Floating_point>`_\ .
+
+Floating-point numbers represent numbers with "decimal point", unlike
+integral types, which always represent whole numbers. Floating-point
+numbers are often used to approximate analog and continuous values
+because they have greater resolution than integers.
+
+The double implementation on the Maple uses twice the number of bytes
+as a :ref:`float <lang-float>`, with the corresponding gains in
+precision.
+
+Tip
+---
+
+Users who borrow code from other sources that includes ``double``
+variables may wish to examine the code to see if the implied range and
+precision are different from that actually achieved on the Maple.
+
+See Also
+--------
+
+- :ref:`float <lang-float>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/doublecast.rst b/docs/source/lang/cpp/doublecast.rst
new file mode 100644
index 0000000..d3f32ce
--- /dev/null
+++ b/docs/source/lang/cpp/doublecast.rst
@@ -0,0 +1,27 @@
+.. highlight:: cpp
+
+.. _lang-doublecast:
+
+``double()`` (cast)
+===================
+
+Converts a value to the :ref:`double <lang-double>` floating point
+data type. Here is an example::
+
+ int x = 2;
+ double d = double(x); // d now holds 2.0, a double value
+
+The value ``x`` can be of any type. However, if ``x`` is not a number
+(like an ``int`` or ``long long``), you will get strange results.
+
+See the :ref:`double <lang-double>` reference for details about the
+precision and limitations of ``double`` values on the Maple.
+
+See Also
+--------
+
+- :ref:`double <lang-double>`
+- :ref:`float <lang-float>`
+- :ref:`float() <lang-floatcast>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/dowhile.rst b/docs/source/lang/cpp/dowhile.rst
new file mode 100644
index 0000000..d229122
--- /dev/null
+++ b/docs/source/lang/cpp/dowhile.rst
@@ -0,0 +1,26 @@
+.. highlight:: cpp
+
+.. _lang-dowhile:
+
+``do``/``while``
+================
+
+A ``do`` loop works in the same manner as a :ref:`while
+<lang-while>` loop, with the exception that the condition is tested
+at the end of the loop, so the ``do`` loop will *always* run at least
+once.
+
+This is the basic syntax::
+
+ do {
+ // statement block
+ } while (test condition);
+
+Example::
+
+ do {
+ delay(50); // wait for sensors to stabilize
+ x = readSensors(); // check the sensors
+ } while (x < 100);
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/enum.rst b/docs/source/lang/cpp/enum.rst
new file mode 100644
index 0000000..b6409eb
--- /dev/null
+++ b/docs/source/lang/cpp/enum.rst
@@ -0,0 +1,52 @@
+.. highlight:: cpp
+
+.. _lang-enum:
+
+``enum``
+========
+
+The ``enum`` keyword is used to specify an enumeration type. An
+enumeration type is a type whose values are taken from a specified,
+fixed list of constant values.
+
+Example
+-------
+
+Here's an example defining an enumeration type called ``weather``,
+which has values ``HOT``, ``COMFY``, and ``COLD``::
+
+ enum weather {HOT, COMFY, COLD};
+
+Once you've defined this type, you can create variables of type
+``weather``, in the same way you would with an :ref:`int <lang-int>`::
+
+ // create a weather variable named theWeather, with value COMFY:
+ weather theWeather = COMFY;
+
+Enumeration types are useful within :ref:`switch statements
+<lang-switchcase>`. If you know that an argument is of an enumeration
+type, you can make ``case`` statements for all of that type's possible
+values, so you know you won't miss anything::
+
+ void describeWeather(weather currentWeather) {
+ switch(currentWeather) {
+ case HOT:
+ SerialUSB.println("it's hot out");
+ break;
+ case COMFY:
+ SerialUSB.println("it's nice today");
+ break;
+ case COLD:
+ SerialUSB.println("it's freezing!");
+ break;
+ }
+ }
+
+Such a ``switch`` statement would need no :ref:`default
+<lang-switchcase-default>`, since we know that ``currentWeather`` must
+be either ``HOT``, ``COMFY``, or ``COLD``.
+
+See Also
+--------
+
+- :ref:`lang-switchcase`
diff --git a/docs/source/lang/cpp/float.rst b/docs/source/lang/cpp/float.rst
new file mode 100644
index 0000000..5195fac
--- /dev/null
+++ b/docs/source/lang/cpp/float.rst
@@ -0,0 +1,50 @@
+.. highlight:: cpp
+
+.. _lang-float:
+
+``float``
+=========
+
+Single-precision floating point number. Occupies 4 bytes. On Maple,
+the ``float`` type has a range of approximately -3.40282×10^38 to
+3.40282×10^38; the ``float`` type is subject to the same
+:ref:`overflow issues <lang-variables-rollover>` as any numeric data
+type.
+
+``float``\ s have only 6-7 decimal digits of precision. That means the
+total number of digits, not the number to the right of the decimal
+point. You can get more precision by using a :ref:`double
+<lang-double>` (which has a precision of about 16 decimal digits).
+
+The following example declares a ``float`` value named ``myfloat``::
+
+ float myfloat;
+
+This example declares a ``float`` value named ``sensorCalibrate``,
+with value 1.117::
+
+ float sensorCalibrate = 1.117;
+
+The general syntax for declaring a float named ``var`` with value
+``val`` is::
+
+ float var = val;
+
+Here is a more extended example involving a :ref:`float cast
+<lang-floatcast>`::
+
+ int x;
+ int y;
+ float z;
+
+ x = 1;
+ y = x / 2; // y now contains 0, ints can't hold fractions
+ z = float(x) / 2; // z now contains .5
+
+See Also
+--------
+
+- :ref:`double <lang-double>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/floatcast.rst b/docs/source/lang/cpp/floatcast.rst
new file mode 100644
index 0000000..af92543
--- /dev/null
+++ b/docs/source/lang/cpp/floatcast.rst
@@ -0,0 +1,28 @@
+.. highlight:: cpp
+
+.. _lang-floatcast:
+
+``float()`` (cast)
+==================
+
+Converts a value to the :ref:`float <lang-float>` data type. Here is
+an example (see the :ref:`constants reference <lang-constants-fp>` for
+an explanation of the "2.0f")::
+
+ int x = 2;
+ float f = float(x); // f now holds 2.0f, a float value
+
+The value ``x`` can be of any type. However, if ``x`` is not a number
+(like an ``int``), you will get strange results.
+
+See the :ref:`float <lang-float>` reference for details about the
+precision and limitations of ``float`` values on the Maple.
+
+See Also
+--------
+
+- :ref:`float <lang-float>`
+- :ref:`double <lang-double>`
+- :ref:`double() <lang-doublecast>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/for.rst b/docs/source/lang/cpp/for.rst
new file mode 100644
index 0000000..78ea562
--- /dev/null
+++ b/docs/source/lang/cpp/for.rst
@@ -0,0 +1,142 @@
+.. highlight:: cpp
+
+.. _lang-for:
+
+``for``
+=======
+
+A ``for`` loop is used to repeat a block of statements enclosed in
+curly braces. ``for`` loops are useful for performing repetitive
+operations, and are often used in combination with :ref:`arrays
+<lang-array>` to operate on collections of data or multiple
+:ref:`pins <gpio>`. A ``for`` loop is composed of two parts: first, a
+*header*, which sets up the for loop, and then a *body*, which is made
+up of lines of code enclosed in curly braces.
+
+.. contents:: Contents
+ :local:
+
+Syntax
+------
+
+There are three parts to the ``for`` loop header: an *initialization*
+expression, *loop condition* expression, and a *post-loop*
+expression. The general syntax looks like this::
+
+ for (initialization; condition; post-loop) {
+ // all of these lines inside the curly braces are part
+ // of the loop body.
+ statement 1;
+ statement 2;
+ ...
+ }
+
+(Note that there is no semicolon after the post-loop). The
+initialization happens first and exactly once, before the loop begins.
+Each time through the loop, the condition is tested. The condition is
+a :ref:`boolean <lang-boolean>` expression. If it is true, then the
+list of statements inside the curly braces are executed. Next, the
+post-loop is executed. The loop then begins again by evaluating the
+condition again, entering the loop body if it is true. This proceeds
+until the condition becomes false.
+
+Examples
+--------
+
+Here's an example::
+
+ // Dim an LED using a PWM pin
+ int pwmPin = 9; // LED in series with 470 ohm resistor on pin 9
+
+ void setup() {
+ pinMode(pwmPin, PWM);
+ }
+
+ void loop() {
+ for (int i=0; i <= 65535; i++) {
+ pwmWrite(pwmPin, i);
+ delay(1);
+ }
+ }
+
+There is a ``for`` loop In the :ref:`loop() <lang-loop>` function of
+the above example. This loop starts by declaring an ``int`` variable
+named ``i``, whose value starts out at zero. The loop proceeds by
+checking if ``i`` is less than or equal to 65535. Since ``i`` is
+zero, this is true, and so the calls to :ref:`pwmWrite()
+<lang-pwmwrite>` and :ref:`delay() <lang-delay>` happen next. At this
+point, the post-loop expression ``i++`` is evaluated, which
+:ref:`increments <lang-increment>` ``i``, so that ``i`` becomes one.
+That concludes the first time through the loop. Each "time through
+the loop" is referred to as an *iteration*.
+
+The loop then jumps back to the beginning, checking the condition as
+the beginning of its second iteration (initialization is skipped,
+since this only happens once, before the first iteration). One is
+less than 65535, so the loop statements are executed again. This
+proceeds over and over until the iteration when ``i`` finally
+reaches 65536. At that point, the condition is no longer true, so the
+loop stops executing, and the ``loop()`` function returns.
+
+Here's another example, using a ``for`` loop to brighten and fade an
+LED (see the :ref:`pwmWrite() <lang-pwmwrite>` reference for more
+information)::
+
+ int pwmPin = 9; // hook up the LED to pin 9
+ void loop() {
+ int x = 1;
+ for (int i = 0; i >= 0; i += x) {
+ analogWrite(pwmPin, i); // controls the brightness of the LED
+ if (i == 65535) {
+ x = -1; // switch direction, so i starts decreasing
+ }
+ delay(1);
+ }
+ }
+
+Coding Tips
+-----------
+
+The C ``for`` loop is more flexible than ``for`` loops found in some
+other computer languages, including BASIC. Any or all of the three
+header elements may be left blank, although the semicolons are
+required. Also the statements for initialization, condition, and
+post-loop can be any valid C statements, and use any C datatypes,
+including :ref:`floating point numbers <lang-double>`. These types
+of unusual ``for`` loops sometimes provide solutions to less-common
+programming problems.
+
+For example, using a multiplication in the post-loop line will
+generate a `geometric progression
+<http://en.wikipedia.org/wiki/Geometric_progression>`_::
+
+ for(int x = 1; x <= 100; x = x * 2) {
+ SerialUSB.println(x);
+ }
+
+
+This loop prints out the numbers 1, 2, 4, 8, ..., 64. Check
+your understanding of ``for`` loops by answering the following two
+questions (answers are in footnote [#fanswers]_\ ):
+
+1. How many iterations occur before the loop finishes?
+
+2. Why does it stop at 64?
+
+See Also
+--------
+
+- :ref:`while <lang-while>` loops
+- :ref:`do <lang-dowhile>` loops
+
+.. rubric:: Footnotes
+
+.. [#fanswers]
+ 1. Seven.
+
+ 2. After the seventh iteration, the post-loop causes ``x`` to
+ equal 128. This is larger than 100, so the loop condition is
+ false, and the loop stops.
+
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/goto.rst b/docs/source/lang/cpp/goto.rst
new file mode 100644
index 0000000..2c0b3b0
--- /dev/null
+++ b/docs/source/lang/cpp/goto.rst
@@ -0,0 +1,129 @@
+.. highlight:: cpp
+
+.. _lang-goto:
+
+Labels and ``goto``
+===================
+
+A *label* gives a name to a line of code within a function. You can
+label a line by writing a name for it, then a colon (``:``), before
+the line starts. The ``goto`` keyword allows program flow to transfer
+to a labeled line from anywhere within the same function.
+
+.. warning:: The use of ``goto`` is discouraged in C and C++
+ programming. It is *never necessary* to use ``goto`` to write a
+ program.
+
+ Unless you know what you're doing, using ``goto`` tends to
+ encourage code which is harder to debug and understand than
+ programs without ``goto`` that do the same thing. That said,
+ however, it's sometimes useful; :ref:`see below <goto-when-to-use>`
+ for a concrete example.
+
+Using Labels and goto
+---------------------
+
+Labels and ``goto`` are probably best explained through example.
+Let's start with an example of how to label lines. The first line
+(``int x = analogRead(some_pin);``) in the :ref:`loop <lang-loop>`
+function below has label ``readpin``. The third line (``delay(x);``)
+has label ``startdelay``. The second line (``SerialUSB.println(x);``)
+does not have a label::
+
+ void loop() {
+ readpin:
+ int x = analogRead(some_pin);
+ SerialUSB.println(x); // for debugging
+ startdelay:
+ delay(x);
+ // ... more code ...
+ }
+
+Anything which can be a :ref:`variable <lang-variables>` name can
+be a label.
+
+Let's say that we wanted to print ``x`` only if it was very large, say
+at least 2000. We might want to do this just so anybody watching on a
+:ref:`serial monitor <ide-serial-monitor>` would know they were in for
+a longer wait than usual. We can accomplish this through the use of a
+``goto`` statement that skips the printing if ``x`` is less than
+2000::
+
+ void loop() {
+ readpin:
+ int x = analogRead(some_pin);
+ if (x < 2000) {
+ goto startdelay;
+ }
+ SerialUSB.println(x); // for debugging
+ startdelay:
+ delay(x);
+ // ... more code ...
+ }
+
+In this modified program, whenever ``x`` is less than 2000, the body
+of the :ref:`if <lang-if>` statement in the second line is
+executed. The ``goto`` statement inside the ``if`` body skips
+straight to the line labeled ``startdelay``, passing over the line
+doing the printing.
+
+A ``goto`` does not have to "move forwards"; it can go "backwards",
+too. For example, the following program prints "5" forever (why?)::
+
+ void loop() {
+ printfive:
+ SerialUSB.println(5);
+ goto printfive;
+ SerialUSB.println(6);
+ }
+
+.. _goto-when-to-use:
+
+When to Use goto
+----------------
+
+As mentioned above, use of ``goto`` is `generally discouraged
+<http://en.wikipedia.org/wiki/Goto#Criticism_and_decline>`_. However,
+when used with care, ``goto`` can simplify certain programs. One
+important use case for ``goto`` is breaking out of deeply nested
+:ref:`for <lang-for>` loops or :ref:`if <lang-if>` logic blocks.
+Here's an example::
+
+ for(int r = 0; r < 255; r++) {
+ for(int g = 255; g > -1; g--) {
+ for(int b = 0; b < 255; b++) {
+ if (analogRead(0) > 250) {
+ goto bailout;
+ }
+ // more statements ...
+ }
+ // innermost loop ends here
+ }
+ }
+ bailout:
+ // more code here
+
+In the above example, whenever the :ref:`analog reading
+<lang-analogread>` on pin 0 was greater than 250, the program would
+jump to the line labeled ``bailout``, exiting all three loops at once.
+
+While there is already a :ref:`break <lang-break>` keyword for
+breaking out of a loop, it will only break out of the *innermost*
+loop. So, if instead of saying "``goto bailout;``", there was a
+"``break;``" instead, the program would only exit from the loop with
+header "``for(int b = 0; b < 255; b++)``". The program would continue
+at the line which reads "``// innermost loop ends here``", which is
+clearly undesirable if you wanted to leave all three loops at once.
+
+More examples of when ``goto`` is a good choice are given in Donald
+Knuth's paper, "Structured Programming with go to Statements"; see
+below for a link.
+
+See Also
+--------
+
+- Dijkstra, Edsger W. `Go To Statement Considered Harmful <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.4846&rep=rep1&type=pdf>`_ (PDF)
+
+- Knuth, Donald. `Structured Programming with go to Statements <http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf>`_ (PDF)
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/if.rst b/docs/source/lang/cpp/if.rst
new file mode 100644
index 0000000..f248b05
--- /dev/null
+++ b/docs/source/lang/cpp/if.rst
@@ -0,0 +1,121 @@
+.. highlight:: cpp
+
+.. _lang-if:
+
+``if``/``else``
+===============
+
+An ``if`` statement is used to execute code when certain conditions
+are met. The general syntax for an ``if`` statement is::
+
+ if (condition) {
+ body
+ }
+
+An ``if`` statement first tests whether its *condition* is true (such
+as an input being above a certain number). If the condition is true,
+the ``if`` statement executes its *body*, which is made up of lines of
+code inside :ref:`curly braces <lang-curly-braces>`. If the condition
+is false, the body is not executed. Here's a more concrete example::
+
+ if (someVariable > 50) {
+ // do something here
+ }
+
+The program tests to see if ``someVariable`` is greater than 50. If it
+is, the program executes every line in the curly braces (which in the
+above example does nothing, since the body is just the :ref:`comment
+<lang-comments>` line "``// do something here``").
+
+Put another way, if the statement in parentheses is true, the
+statements inside the braces are run. If not, the program skips over
+the code.
+
+An ``if`` statement's condition (which is inside the parentheses after
+``if``) often uses one or more :ref:`boolean <lang-boolean>` or
+:ref:`comparison <lang-comparison>` operators.
+
+Writing the if Body
+-------------------
+
+The brackets may be omitted after an ``if`` statement's
+conditional. If this is done, the next line (which ends in a
+semicolon) becomes the only line in the body. The following three
+``if`` statements all do the same thing::
+
+ if (x > 120) digitalWrite(pin, HIGH);
+
+ if (x > 120)
+ digitalWrite(pin, HIGH);
+
+ if (x > 120) {
+ digitalWrite(pin, HIGH);
+ }
+
+However, the following two examples are different::
+
+ // example 1: two lines of code in the if body
+ if (x > 120) {
+ digitalWrite(pin1, HIGH);
+ digitalWrite(pin2, HIGH);
+ }
+
+ // example 2: one line of code in the if body, and
+ // another line of code after the if statement
+ if (x > 120)
+ digitalWrite(pin1, HIGH); // this is in the if body
+ digitalWrite(pin2, HIGH); // this is NOT in the if body
+
+In the first example, since the body is enclosed in curly braces, both
+lines are included. In the second example, since the curly braces are
+missing, only the first line is in the ``if`` body.
+
+``else``
+--------
+
+``if``/\ ``else`` allows greater control over the flow of code than
+the basic :ref:`if <lang-if>` statement, by allowing multiple tests to
+be grouped together. For example, an :ref:`analog input
+<lang-analogread>` could be tested, with one action taken if the input
+was less than 500, and another action taken if the input was 500 or
+greater. The code would look like this::
+
+ if (pinFiveInput < 500) {
+ // action A
+ } else {
+ // action B
+ }
+
+``else`` can precede another ``if`` test, so that multiple, mutually
+exclusive tests can be run at the same time.
+
+Each test will proceed to the next one until a true test is
+encountered. When a true test is found, its associated block of code
+is run, and the program then skips to the line following the entire
+if/else construction. If no test proves to be true, the default
+``else`` block is executed, if one is present, and sets the default
+behavior.
+
+Note that an ``else if`` block may be used with or without a
+terminating ``else`` block, and vice-versa. An unlimited number of
+such ``else if`` branches is allowed. Here is a code example::
+
+ if (pinFiveInput < 500) {
+ // do Thing A
+ } else if (pinFiveInput >= 1000) {
+ // do Thing B
+ } else {
+ // do Thing C
+ }
+
+Another way to express branching, mutually exclusive tests, is with a
+:ref:`switch/case <lang-switchcase>` statement.
+
+
+See Also
+--------
+
+- :ref:`boolean operators <lang-boolean>`
+- :ref:`comparison operators <lang-comparison>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/include.rst b/docs/source/lang/cpp/include.rst
new file mode 100644
index 0000000..163509d
--- /dev/null
+++ b/docs/source/lang/cpp/include.rst
@@ -0,0 +1,70 @@
+.. highlight:: cpp
+
+.. _lang-include:
+
+``#include``
+============
+
+``#include`` is used to include outside libraries in your sketch.
+This gives the programmer access to a large group of standard C
+libraries (groups of pre-made functions and data types), and also
+libraries written especially for Maple.
+
+Example
+-------
+
+This example (from the `Arduino LiquidCrystal Tutorial
+<http://arduino.cc/en/Tutorial/LiquidCrystal>`_) includes a library
+that is used to control :ref:`LCD displays
+<libraries-liquid-crystal>`::
+
+ // include the library code:
+ #include <LiquidCrystal.h>
+
+ // initialize the library with the numbers of the interface pins
+ LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
+
+ void setup() {
+ // set up the LCD's number of columns and rows:
+ lcd.begin(16, 2);
+ // Print a message to the LCD.
+ lcd.print("hello, world!");
+ }
+
+ void loop() {
+ // set the cursor to column 0, line 1
+ // (note: line 1 is the second row, since counting begins with 0):
+ lcd.setCursor(0, 1);
+ // print the number of seconds since reset:
+ lcd.print(millis()/1000);
+ }
+
+Note that a ``#include`` line, like :ref:`#define <lang-define>`,
+has **no semicolon**. The compiler will print strange error messages
+if you add one.
+
+C Standard Library
+------------------
+
+The standard C library that comes with Maple is called `newlib
+<http://sourceware.org/newlib/>`_. Its main sources of documentation
+are its `main reference <http://sourceware.org/newlib/libc.html>`_
+page and its `math functions
+<http://sourceware.org/newlib/libm.html>`_ reference page. Here's an
+example that imports the math.h library in order to take the `cube
+root <http://en.wikipedia.org/wiki/Cube_root>`_ of a number::
+
+ #include <math.h>
+
+ void setup() {
+ // no setup necessary
+ }
+
+ void loop() {
+ // "cbrt" stands for "cube root"
+ double cubeRootOf3 = cbrt(3.0);
+ // prints a number that is approximately the cube root of 3:
+ SerialUSB.println(cubeRootOf3);
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/increment.rst b/docs/source/lang/cpp/increment.rst
new file mode 100644
index 0000000..c423d1a
--- /dev/null
+++ b/docs/source/lang/cpp/increment.rst
@@ -0,0 +1,37 @@
+.. highlight:: cpp
+
+.. _lang-increment:
+
+Increment and Decrement Operators (``++``, ``--``)
+==================================================
+
+These operators increment (add one to) or decrement (subtract one
+from) a variable. If they come before the variable, they return its
+new value; otherwise, they return its old value.
+
+Some quick examples::
+
+ x++; // adds one to x, and returns the old value of x
+ ++x; // adds one to x, and returns the new value of x
+
+ x--; // decrement x by one and returns the old value of x
+ --x; // decrement x by one and returns the new value of x
+
+A more extended example::
+
+ x = 2;
+ y = ++x; // x now contains 3, y contains 3
+ y = x--; // x contains 2 again, y still contains 3
+
+.. warning:: Be careful! You cannot put a space in between the two
+ ``+`` or ``-`` signs. This example is broken::
+
+ // this line won't compile (notice the extra space):
+ int y = x+ +;
+
+See Also
+--------
+
+- :ref:`lang-compoundarithmetic`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/int.rst b/docs/source/lang/cpp/int.rst
new file mode 100644
index 0000000..fa63946
--- /dev/null
+++ b/docs/source/lang/cpp/int.rst
@@ -0,0 +1,68 @@
+.. highlight:: cpp
+
+.. _lang-int:
+
+``int``
+=======
+
+The ``int`` data type represents integers. Integers are your primary
+data type for number storage, and store a 4 byte value. This yields a
+range of -2,147,483,648 to 2,147,483,647 (minimum value of -2^31 and a
+maximum value of (2^31) - 1; that's about negative 2 billion to
+positive 2 billion).
+
+An ``int`` stores a negative number with a technique called `two's
+complement math
+<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_\ .
+The highest bit in an ``int``, sometimes refered to as the "sign" bit,
+flags the number as a negative number. (See the linked article on
+two's complement for more information).
+
+The Maple takes care of dealing with negative numbers for you, so that
+arithmetic operations work mostly as you'd expect. There can be an
+:ref:`unexpected complication <lang-bitshift-signbit-gotcha>` in
+dealing with the :ref:`bitshift right operator (>>)
+<lang-bitshift>`, however.
+
+.. _lang-long:
+
+The ``long`` type is a synonym for ``int``.
+
+Here is an example of declaring an ``int`` variable named ``pin``,
+then giving it value 13::
+
+ int pin = 13;
+
+The general syntax for declaring an ``int`` variable named ``var``,
+then giving it value ``val``, looks like::
+
+ int var = val;
+
+.. _lang-int-overflow:
+
+Integer Overflow
+----------------
+
+When ``int`` variables leave the range specified above, they
+:ref:`roll over <lang-variables-rollover>` in the other direction.
+Here are some examples::
+
+ int x;
+ x = -2,147,483,648;
+ x--; // x now contains 2,147,483,647; rolled over "left to right"
+
+ x = 2,147,483,647;
+ x++; // x now contains -2,147,483,648; rolled over "right to left"
+
+See Also
+--------
+
+- :ref:`unsigned int <lang-unsignedint>`
+- :ref:`char <lang-char>`
+- :ref:`unsigned char <lang-unsignedchar>`
+- :ref:`long long <lang-longlong>`
+- :ref:`unsigned long long <lang-unsignedlonglong>`
+- :ref:`Integer Constants <lang-constants-integers>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: cc-attribution.txt
diff --git a/docs/source/lang/cpp/intcast.rst b/docs/source/lang/cpp/intcast.rst
new file mode 100644
index 0000000..da838c7
--- /dev/null
+++ b/docs/source/lang/cpp/intcast.rst
@@ -0,0 +1,26 @@
+.. highlight:: cpp
+
+.. _lang-intcast:
+
+``int()`` (cast)
+================
+
+Converts a value to the :ref:`int <lang-int>` data type. Here is
+an example::
+
+ double d = 2.5;
+ int i = int(d); // i holds "2", an int value
+
+The value inside of the parentheses (``int(...)``) can be of any type.
+However, if it is not a numeric type (like ``double``, ``char``,
+etc.), you will get strange results.
+
+See the :ref:`int <lang-int>` reference for details about the
+precision and limitations of ``int`` variables on the Maple.
+
+See Also
+--------
+
+- :ref:`int <lang-int>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/keywords.rst b/docs/source/lang/cpp/keywords.rst
new file mode 100644
index 0000000..f21cd0d
--- /dev/null
+++ b/docs/source/lang/cpp/keywords.rst
@@ -0,0 +1,204 @@
+.. _lang-keywords:
+
+Keywords
+========
+
+This page lists all of the C++ keywords, and either links to a
+reference page explaining their use, or provides a brief description.
+
+List of Keywords
+----------------
+
+The C++ keywords are:
+
+``and``, ``and_eq``, ``asm``, ``auto``, ``bitand``, ``bitor``,
+``bool``, ``break``, ``case``, ``catch``, ``char``, ``class``,
+``compl``, ``const``, ``const_cast``, ``continue``, ``default``,
+``delete``, ``do``, ``double``, ``dynamic_cast``, ``else``, ``enum``,
+``explicit``, ``export``, ``extern``, ``false``, ``float``, ``for``,
+``friend``, ``goto``, ``if``, ``inline``, ``int``, ``long``,
+``mutable``, ``namespace``, ``new``, ``not``, ``not_eq``,
+``operator``, ``or``, ``or_eq``, ``private``, ``protected``,
+``public``, ``register``, ``reinterpret_cast``, ``return``, ``short``,
+``signed``, ``sizeof``, ``static``, ``static_cast``, ``struct``,
+``switch``, ``template``, ``this``, ``throw``, ``true``, ``try``,
+``typedef``, ``typeid``, ``typename``, ``union``, ``unsigned``,
+``using``, ``virtual``, ``void``, ``volatile``, ``wchar_t``,
+``while``, ``xor``, ``xor_eq``
+
+Boolean Operator Synonyms
+-------------------------
+
+- ``and`` is a synonym for :ref:`&& <lang-boolean-and>`.
+- ``not`` is a synonym for :ref:`\! <lang-boolean-not>`.
+- ``not_eq`` is a synonym for :ref:`\!= <lang-comparison>`.
+- ``or`` is a synonym for :ref:`|| <lang-boolean-or>`.
+
+Bitwise Operator Synonyms
+-------------------------
+
+- ``and_eq`` is a synonym for :ref:`&= <lang-compoundbitwise-and>`.
+- ``bitand`` is a synonym for (bitwise) :ref:`& <lang-bitwisemath-and>`.
+- ``bitor`` is a synonym for :ref:`\| <lang-bitwisemath-or>`.
+- ``compl`` is a synonym for :ref:`~ <lang-bitwisemath-not>`.
+- ``or_eq`` is a synonym for :ref:`|= <lang-compoundbitwise-or>`.
+- ``xor`` is a synonym for :ref:`^ <lang-bitwisemath-xor>`.
+- ``xor_eq`` is a synonym for :ref:`^= <lang-compoundbitwise-xor>`.
+
+Constants
+---------
+
+- ``true`` and ``false`` are the :ref:`boolean constants
+ <lang-booleanvariables>`.
+
+Control Flow
+------------
+
+- ``break`` can exit out of a :ref:`switch statement
+ <lang-switchcase>` or a :ref:`for <lang-for>`, :ref:`do
+ <lang-dowhile>`, or :ref:`while <lang-while>` loop.
+
+- ``case`` defines alternatives in a :ref:`switch statement <lang-switchcase>`.
+
+- ``continue`` will move control flow to the next iteration of the
+ enclosing :ref:`for <lang-for>`, :ref:`do <lang-dowhile>`, or
+ :ref:`while <lang-while>` loop.
+
+- ``default`` defines the default alternative in a :ref:`switch
+ statement <lang-switchcase>`.
+
+- ``do`` introduces a :ref:`do <lang-dowhile>` loop.
+
+- ``else`` is used in :ref:`if statements <lang-if>`.
+
+- ``for`` introduces a :ref:`for <lang-for>` loop.
+
+- ``goto`` :ref:`jumps <lang-goto>` to a label.
+
+- ``if`` introduces an :ref:`if statement <lang-if>`.
+
+- ``return`` :ref:`transfers flow to a function's caller <lang-return>`.
+
+- ``switch`` introduces a :ref:`switch statement <lang-switchcase>`.
+
+- ``while`` introduces a :ref:`while <lang-while>` loop.
+
+Types
+-----
+
+The following keywords are used for built-in types.
+
+- :ref:`bool <lang-booleanvariables>`
+- :ref:`char <lang-char>`
+- :ref:`double <lang-double>`
+- :ref:`float <lang-float>`
+- :ref:`int <lang-int>`
+- :ref:`long <lang-long>`
+- :ref:`short <lang-built-in-types-integral>`
+- :ref:`void <lang-void>` (not really a type, but used in the absence
+ of one)
+
+The following keywords are used to introduce new types.
+
+- :ref:`enum <lang-enum>`
+
+Qualifiers
+----------
+
+- :ref:`static <lang-static>` can be used to declare persistent local
+ variables; it has other uses not documented here.
+
+- ``unsigned`` is used to specify an unsigned integral type.
+ Examples: :ref:`lang-unsignedint`, :ref:`lang-unsignedchar`.
+
+- :ref:`volatile <lang-volatile>` is useful when declaring variables
+ that may be modified by external interrupts.
+
+- :ref:`const <lang-const>` is used to define constants.
+
+Other
+-----
+
+These keywords are not described in the Maple documentation. For more
+information, consult a C++ reference.
+
+- ``asm`` is used to insert literal assembly language.
+
+- ``auto`` is used to declare that a variable has automatic storage.
+
+- ``catch`` is used in exception handling. Note that the default
+ flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``.
+
+- ``class`` is used to define classes.
+
+- ``const_cast`` is used in typecasting.
+
+- ``delete`` is used to free ``new``\ -allocated storage. Note that
+ dynamic memory allocation is not available by default on the Maple,
+ so you'll have to bring your own ``new`` and ``delete`` if you want
+ this.
+
+- ``dynamic_cast`` is used in typecasting.
+
+- ``explicit`` is used to declare constructors that can be called only
+ explicitly.
+
+- ``export`` declares a template definition accessible to other
+ compilation units.
+
+- ``extern`` can mark a declaration as a declaration and not a
+ definition, and also grant external linkage to a ``const`` or
+ ``typedef``.
+
+- ``friend`` is used to declare that certain functions have access to
+ a class's private variables.
+
+- ``inline`` is a compiler hint to inline a function.
+
+- ``mutable`` specifies that a member can be updated, even when a
+ member of a ``const`` object.
+
+- ``namespace`` declares a new namespace.
+
+- ``new`` dynamically allocates space for a value. Note that dynamic
+ memory allocation is not available by default on the Maple, so
+ you'll have to bring your own ``new`` and ``delete`` if you want
+ this.
+
+- ``operator`` is used to define type-specific operator overrides.
+
+- ``private`` declares a private class member.
+
+- ``protected`` declares a protected class member.
+
+- ``public`` declares a public class member.
+
+- ``register`` is a compiler hint to store a variable in a register.
+
+- ``reinterpret_cast`` is used in typecasting.
+
+- ``signed`` is the opposite of ``unsigned``.
+
+- ``static_cast`` is used in typecasting.
+
+- ``struct`` declares a new struct.
+
+- ``template`` introduces a template class, function, etc.
+
+- ``this`` is a pointer to the receiver object.
+
+- ``throw`` is used in exception handling. Note that the default
+ flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``.
+
+- ``try`` is used in exception handling. Note that the default
+ flags we pass to :ref:`GCC <arm-gcc>` include ``-fno-exceptions``.
+
+- ``typedef`` defines a type synonym.
+
+- ``union`` defines an untagged union.
+
+- ``using`` is a directive related to namespaces.
+
+- ``virtual`` declares a method which may be overridden.
+
+- ``wchar_t`` is the wide character type.
diff --git a/docs/source/lang/cpp/longcast.rst b/docs/source/lang/cpp/longcast.rst
new file mode 100644
index 0000000..493ad67
--- /dev/null
+++ b/docs/source/lang/cpp/longcast.rst
@@ -0,0 +1,27 @@
+.. highlight:: cpp
+
+.. _lang-longcast:
+
+``long()`` (cast)
+=================
+
+Converts a value to the :ref:`long <lang-long>` data type. Here is
+an example::
+
+ double d = 2.5;
+ long i = long(d); // i holds "2L", an long value
+
+The value inside of the parentheses (``long(...)``) can be of any type.
+However, if it is not a numeric type (like ``double``, ``char``,
+etc.), you will get strange results.
+
+See the :ref:`long <lang-long>` reference for details about the
+precision and limitations of ``long`` variables on the Maple.
+
+See Also
+--------
+
+- :ref:`long <lang-long>`
+- :ref:`long long <lang-longlong>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/longlong.rst b/docs/source/lang/cpp/longlong.rst
new file mode 100644
index 0000000..d942cb4
--- /dev/null
+++ b/docs/source/lang/cpp/longlong.rst
@@ -0,0 +1,56 @@
+.. highlight:: cpp
+
+.. _lang-longlong:
+
+``long long``
+=============
+
+The ``long long`` data type stores extended size integer values. You
+can use a ``long long`` when your values are too large to fit into an
+:ref:`int <lang-int>`. A ``long long`` occupies 8 bytes of memory.
+This yields a range of approximately -9.2×10^18 to 9.2×10^18 (that's
+9.2 billion billion, or about 92 million times the number of stars in
+the Milky Way galaxy). The exact range of a ``long long`` on the
+Maple is from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807,
+or -2^63 to (2^63-1). A ``long long`` it is subject to the same
+:ref:`overflow issues <lang-variables-rollover>` as any numeric data
+type.
+
+A synonym for the ``long long`` type is ``int64``.
+
+Here's an example of declaring a long long (see :ref:`integer
+constants <lang-constants-integers-u-l>` for an explanation of the
+"LL" at the end of the number)::
+
+ // Speed of light in nanometers per second (approximate).
+ long long c = 299792458000000000LL;
+
+The general syntax for declaring an ``long long`` variable named ``var``,
+then giving it value ``val``, looks like::
+
+ long long var = val;
+
+This is identical to the ``int`` syntax, with ``long long`` (or, at
+your option, ``int64``) replacing ``int``.
+
+Note that ``long long`` values will still :ref:`overflow
+<lang-int-overflow>`, just like ``int`` values, but their much larger
+range makes this less likely to happen.
+
+The downside to using a ``long long`` instead of an ``int`` (besides
+the extra storage) is that :ref:`arithmetic <lang-arithmetic>`
+operations on ``long long``\ s will take slightly longer than on
+``int``\ s.
+
+See Also
+--------
+
+- :ref:`char <lang-char>`
+- :ref:`unsigned char <lang-unsignedchar>`
+- :ref:`int <lang-int>`
+- :ref:`unsigned int <lang-unsignedint>`
+- :ref:`unsigned long long <lang-unsignedlonglong>`
+- :ref:`Integer Constants <lang-constants-integers>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/modulo.rst b/docs/source/lang/cpp/modulo.rst
new file mode 100644
index 0000000..013d07e
--- /dev/null
+++ b/docs/source/lang/cpp/modulo.rst
@@ -0,0 +1,70 @@
+.. highlight:: cpp
+
+.. _lang-modulo:
+
+Modulo Operator (``%``)
+=======================
+
+Calculates the `remainder <http://en.wikipedia.org/wiki/Remainder>`_
+when one integer is divided by another. It is useful for keeping a
+variable within a particular range (e.g. the size of an array).
+
+Syntax
+------
+
+::
+
+ dividend % divisor
+
+Parameters
+----------
+
+**dividend**: the number to be divided
+
+**divisor**: the number to divide by
+
+Returns
+-------
+
+The remainder of **dividend**\ /\ **divisor**\ .
+
+Examples
+--------
+
+::
+
+ int x;
+ x = 7 % 5; // x now contains 2
+ x = 9 % 5; // x now contains 4
+ x = 5 % 5; // x now contains 0
+ x = 4 % 5; // x now contains 4
+
+::
+
+ /* update one value in an array each time through a loop */
+
+ int values[10];
+ int i = 0;
+
+ void setup() {
+ // no setup necessary
+ }
+
+ void loop() {
+ values[i] = analogRead(0);
+ i = (i + 1) % 10; // modulo operator makes sure i stays between 0 and 9
+ }
+
+Tip
+---
+
+The modulo operator does not work on floats. For that, you can use
+the C standard library function `fmod()
+<http://sourceware.org/newlib/libm.html#fmod>`_.
+
+See Also
+--------
+
+- :ref:`Arithmetic <lang-arithmetic>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/pointer.rst b/docs/source/lang/cpp/pointer.rst
new file mode 100644
index 0000000..ff4ec32
--- /dev/null
+++ b/docs/source/lang/cpp/pointer.rst
@@ -0,0 +1,31 @@
+.. _lang-pointer:
+
+Pointer Operators (``&``, ``*``)
+================================
+
+The pointer operators ``&`` (reference) and ``*`` (dereference) are
+different from the bitwise math operator :ref:`&
+<lang-bitwisemath-and>` and the arithmetic operator :ref:`*
+<lang-arithmetic>`.
+
+Pointers are one of the more complicated subjects for beginners in
+learning C, and it is possible to write many useful Arduino sketches
+without ever encountering pointers. However, for manipulating certain
+data structures, the use of pointers can simplify the code, improve
+its efficiency, and generally provide many benefits that would be
+difficult to achieve without the use of pointers.
+
+Introducing pointers is somewhat outside the scope of this
+documentation. However, a good `pointer tutorial
+<http://www.cplusplus.com/doc/tutorial/pointers/>`_ is available.
+Also see the `Wikipedia article on pointers
+<http://en.wikipedia.org/wiki/Pointer_%28computing%29>`_, especially
+the section on `pointers in C
+<http://en.wikipedia.org/wiki/Pointer_%28computing%29#C_pointers>`_.
+
+See Also
+--------
+
+- http://xkcd.com/138/
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/return.rst b/docs/source/lang/cpp/return.rst
new file mode 100644
index 0000000..d9aecbe
--- /dev/null
+++ b/docs/source/lang/cpp/return.rst
@@ -0,0 +1,60 @@
+.. highlight:: cpp
+
+.. _lang-return:
+
+``return``
+==========
+
+Terminates a function and return a value from a function to the
+calling function, if the function has non-``void`` return type.
+
+Syntax:
+-------
+
+::
+
+ // from within a "void" function:
+ return;
+
+ // from within a non-"void" function:
+ return value;
+
+In the second case, ``value`` should have a type which is the same as
+the return type of the function, or be convertible to it (like an
+``int`` to a ``double``, etc.; see :ref:`this note
+<lang-arithmetic-typeconversion>` for some references).
+
+Examples:
+---------
+
+A function to compare a sensor input to a threshold::
+
+ // converts analog readings between 0 and 400 to 0, and 400 up to 1.
+ int checkSensor() {
+ if (analogRead(0) > 400) {
+ return 1;
+ else {
+ return 0;
+ }
+ }
+
+An early ``return`` is also useful when testing a section of code
+without having to "comment out" large sections of possibly buggy code,
+like so::
+
+ void loop() {
+
+ // brilliant code idea to test here
+
+ return;
+
+ // the rest of a dysfunctional sketch here
+ // this code will never be executed
+ }
+
+See Also
+--------
+
+- :ref:`comments <lang-comments>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/scope.rst b/docs/source/lang/cpp/scope.rst
new file mode 100644
index 0000000..a270428
--- /dev/null
+++ b/docs/source/lang/cpp/scope.rst
@@ -0,0 +1,120 @@
+.. highlight:: cpp
+
+.. _lang-scope:
+
+Scope
+=====
+
+Variables in the C++ programming language, which Maple uses (all of
+your sketches are C++ programs in disguise), have a property called
+*scope*. Simply put, a variable's scope is made up of all of the
+lines where the variable can be used.
+
+Scope in C++ is a fairly complex topic, so we won't try to describe it
+in full here. Instead, we present a simplified view, describing two
+different kinds of scopes, *global* and *local*. For more detailed
+information, consult a C++ reference.
+
+Global and Local Variables
+--------------------------
+
+A global variable is one that can be "seen" by every function in a
+program. In the :ref:`Maple IDE <ide>`, any variable declared outside
+of a function (like :ref:`setup() <lang-setup>` and :ref:`loop()
+<lang-loop>`) is a global variable.
+
+A local variable can only be "seen" inside of a particular function.
+You can declare a variable to be local to a function by declaring it
+inside of the :ref:`curly braces <lang-curly-braces>` which enclose
+that function.
+
+When programs start to get larger and more complex, local variables
+are a useful way to ensure that a function has exclusive access to its
+own variables. This prevents programming errors when one function
+mistakenly modifies variables used by another function.
+
+It is also sometimes useful to declare and initialize a variable
+inside a :ref:`for <lang-for>` loop. This creates a variable that
+can only be accessed from inside the loop body.
+
+Example
+-------
+
+Here is an example sketch (which you can copy into the Maple IDE and
+run on your Maple) that illustrates the use of global and local
+variables, as well as declaring variables inside of a ``for`` loop.
+Be sure to open a :ref:`serial monitor <ide-serial-monitor>` after you
+:ref:`verify <ide-verify>` and :ref:`upload <ide-upload>` the sketch::
+
+ int globalVar; // any function will see this variable
+
+ void setup() {
+ // since "globalVar" is declared outside of any function,
+ // every function can "see" and use it:
+ globalVar = 50;
+
+ // the variables "i" and "d" declared inside the "loop" function
+ // can't be seen here. see what happens when you uncomment the
+ // following lines, and try to Verify (compile) the sketch:
+ //
+ // i = 16;
+ // SerialUSB.print("i = ");
+ // SerialUSB.println(i);
+ // d = 26.5;
+ // SerialUSB.print("d = ");
+ // SerialUSB.println(d);
+ }
+
+ void loop() {
+ // since "i" and "d" are declared inside of the "loop" function,
+ // they can only be seen and used from inside of it:
+ int i;
+ double d;
+
+ for (int j = 0; j < 5; j++) {
+ // variable i can be used anywhere inside the "loop" function;
+ // variable j can only be accessed inside the for-loop brackets:
+ i = j * j;
+ SerialUSB.print("i = ");
+ SerialUSB.println(i);
+ }
+
+ // globalVar can be accessed from anywhere. note how even
+ // though we set globalVar = 50 in the "setup" function, we can
+ // see that value here:
+ SerialUSB.print("globalVar = ");
+ SerialUSB.println(globalVar);
+
+ // d can be accessed from anywhere inside the "loop" function:
+ d = 26.5;
+ SerialUSB.print("d = ");
+ SerialUSB.print(d);
+ SerialUSB.println(" (before separateFunction())");
+
+ separateFunction();
+
+ // notice how even though separateFunction() has a variable
+ // named "d", it didn't touch our (local) variable which has
+ // the same name:
+ SerialUSB.print("d = ");
+ SerialUSB.print(d);
+ SerialUSB.println(" (after separateFunction())");
+ }
+
+ void separateFunction() {
+ // variable "d" here has the same name as variable "d" inside of
+ // the "loop" function, but since they're both _local_
+ // variables, they don't affect each other:
+ double d = 30.5;
+ SerialUSB.print("d = ");
+ SerialUSB.print(d);
+ SerialUSB.println(" (inside of separateFunction())");
+ }
+
+See Also
+--------
+
+- `C++ programming Wikibook <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Scope>`_.
+- Wikipedia article on `scope <http://en.wikipedia.org/wiki/Scope_%28programming%29>`_
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/semicolon.rst b/docs/source/lang/cpp/semicolon.rst
new file mode 100644
index 0000000..05e6218
--- /dev/null
+++ b/docs/source/lang/cpp/semicolon.rst
@@ -0,0 +1,22 @@
+.. highlight:: cpp
+
+.. _lang-semicolon:
+
+Semicolon (``;``)
+=================
+
+Used to end a line of code. Example::
+
+ int a = 13;
+
+Tip
+---
+
+Forgetting to end a line in a semicolon will result in a compiler
+error. The error text may be obvious, and refer to a missing
+semicolon, or it may not. If an impenetrable or seemingly illogical
+compiler error comes up, one of the first things to check is a
+missing semicolon, in the immediate vicinity, preceding the line at
+which the compiler complained.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/sizeof.rst b/docs/source/lang/cpp/sizeof.rst
new file mode 100644
index 0000000..ec2dea6
--- /dev/null
+++ b/docs/source/lang/cpp/sizeof.rst
@@ -0,0 +1,64 @@
+.. highlight:: cpp
+
+.. _lang-sizeof:
+
+``sizeof()``
+============
+
+The ``sizeof`` operator on the Maple returns the number of bytes
+needed to store a value of a given type\ [#fcharsize]_. This can be
+an ordinary numeric type, like ``int``. It can be something more
+complicated, like a ``struct`` or ``union``. If the argument to
+``sizeof`` is an array, it returns the total number of bytes occupied
+by the array.
+
+The general syntax looks like this::
+
+ sizeof(type)
+ sizeof(var)
+
+Example
+-------
+
+The ``sizeof`` operator is useful for dealing with arrays (such as
+strings) where it is convenient to be able to change the size of the
+array without breaking other parts of the program.
+
+This program prints out a text string one character at a time. Try
+changing the text phrase::
+
+ char myStr[] = "this is a test";
+ int i;
+
+ void setup() {
+ Serial.begin(9600);
+ }
+
+ void loop() {
+ for (i = 0; i < sizeof(myStr) - 1; i++) {
+ Serial.print(i, DEC);
+ Serial.print(" = ");
+ Serial.println(myStr[i], BYTE);
+ }
+ }
+
+
+Note that ``sizeof`` returns the total number of bytes. So for larger
+variable types such as ``int``, the :ref:`for loop <lang-for>`
+would look something like this::
+
+ for (i = 0; i < (sizeof(myInts)/sizeof(int)) - 1; i++) {
+ // do something with myInts[i]
+ }
+
+.. rubric:: Footnotes
+
+.. [#fcharsize] Technically (and pedantically) speaking, ``sizeof``
+ returns a multiple of the number of bits a ``char`` occupies in
+ memory. However, on the Maple (this goes for most C++
+ implementations), a ``char`` occupies 8 bits = 1 byte. All the C++
+ standard guarantees, however, is that a ``char`` occupies at
+ *least* 8 bits.
+
+.. include:: /arduino-cc-attribution.txt
+
diff --git a/docs/source/lang/cpp/sqrt.rst b/docs/source/lang/cpp/sqrt.rst
new file mode 100644
index 0000000..fbabf82
--- /dev/null
+++ b/docs/source/lang/cpp/sqrt.rst
@@ -0,0 +1,24 @@
+.. _lang-sqrt:
+
+sqrt()
+======
+
+Calculates the square root of a number.
+
+Library Documentation
+---------------------
+
+.. doxygenfunction:: sqrt
+
+Arduino Compatibility
+---------------------
+
+The Maple versino of ``sqrt()`` is compatible with Arduino.
+
+See Also
+--------
+
+- :ref:`pow <lang-pow>`
+- :ref:`sq <lang-sq>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/static.rst b/docs/source/lang/cpp/static.rst
new file mode 100644
index 0000000..8c52ba0
--- /dev/null
+++ b/docs/source/lang/cpp/static.rst
@@ -0,0 +1,56 @@
+.. highlight:: cpp
+
+.. _lang-static:
+
+``static``
+==========
+
+The ``static`` keyword can be used to create variables that are
+visible to only one function. However, unlike local variables that get
+created and destroyed every time a function is called, ``static``
+variables persist beyond the function call, preserving their data
+between function calls.
+
+Variables declared as ``static`` will only be created and initialized
+the first time a function is called.
+
+.. note:: This is only one use of the ``static`` keyword in C++. It
+ has some other important uses that are not documented here; consult
+ a reliable C++ reference for details.
+
+Example
+-------
+
+One use case for ``static`` variables is implementing counters that
+last longer than the functions which need them, but shouldn't be
+shared to other functions. Here's an example::
+
+ void setup() {
+ SerialUSB.begin();
+ }
+
+ void loop() {
+ int reading;
+ if (timeToReadSensors()) {
+ reading = readSensors();
+ }
+ // do something with reading
+ }
+
+ int readSensors() {
+ static int numSensorReadings = 0;
+ numSensorReadings++;
+ if (numSensorReadings % 100 == 0) {
+ SerialUSB.print("just got to another 100 sensor readings");
+ }
+ return analogRead(...);
+ }
+
+In this example, the static variable ``numSensorReadings`` is
+initialized to zero the first time ``readSensors()`` is called, and
+then incremented, so it starts out at one. Subsequent calls to
+``readSensors()`` won't reset ``numSensorReadings`` to zero, because
+it was declared ``static``. Thus, ``numSensorReadings`` is a count of
+the number of times that ``readSensors()`` has been called.
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/string.rst b/docs/source/lang/cpp/string.rst
new file mode 100644
index 0000000..3497484
--- /dev/null
+++ b/docs/source/lang/cpp/string.rst
@@ -0,0 +1,120 @@
+.. highlight:: cpp
+
+.. _lang-string:
+
+Strings
+=======
+
+Text strings on the Maple can be represented with null-terminated
+arrays of type :ref:`char <lang-char>`.
+
+Examples
+--------
+
+All of the following are valid declarations for strings::
+
+ char str1[15];
+ char str2[6] = {'m', 'a', 'p', 'l', 'e'};
+ char str3[6] = {'m', 'a', 'p', 'l', 'e', '\0'};
+ char str4[ ] = "maple";
+ char str5[6] = "maple";
+ char str6[15] = "maple";
+
+As you can see, there are several methods available for declaring and
+initializing strings:
+
+- Declare an array of ``char`` without initializing it, as with ``str1``.
+
+- Declare an array of ``char`` (with one extra ``char``) and the
+ compiler will add the required null character, as with ``str2``.
+
+- Explicitly add the null character (``'\0'``), as with ``str3``.
+
+- Initialize with a string constant in quotation marks (``"..."``);
+ the compiler will size the array to fit the string constant and a
+ terminating null character (``str4``).
+
+- Initialize the array with an explicit size and string constant,
+ (``str5``).
+
+- Initialize the array, leaving extra space for a larger string
+ (``str6``).
+
+Null Termination
+----------------
+
+Generally, strings are terminated with a null character (`ASCII
+<http://en.wikipedia.org/wiki/ASCII>`_ code 0). This allows functions
+(like ``SerialUSB.print()``) to tell where the end of a string is.
+Otherwise, they would continue reading subsequent bytes of memory that
+aren't actually part of the string.
+
+This means that your string needs to have space for one more character
+than the text you want it to contain. That is why ``str2`` and
+``str5`` need to be six characters, even though "maple" is only five
+-- the last position is automatically filled with a NULL
+character. ``str4`` will be automatically sized to six characters, one
+for the extra null. In the case of ``str3``, we've explicitly included
+the null character (written ``'\0'``) ourselves.
+
+Note that it's possible to have a string without a final null
+character (e.g. if you had specified the length of ``str2`` as five
+instead of six). This will break most functions that use strings, so
+you shouldn't do it intentionally. If you notice something behaving
+strangely (operating on characters not in the string), however, this
+could be the problem.
+
+Single quotes or double quotes?
+-------------------------------
+
+Strings are always defined inside double quotes (``"Abc"``) and
+characters are always defined inside single quotes (``'A'``).
+
+Wrapping long strings
+---------------------
+
+You can wrap long strings like this::
+
+ char myString[] = "This is the first line"
+ " this is the second line"
+ " etcetera";
+
+Arrays of Strings
+-----------------
+
+It is often convenient, when working with large amounts of text,
+such as a project with an LCD display, to setup an array of
+strings. Because strings themselves are arrays, this is in actually
+an example of a two-dimensional array.
+
+In the code below, the asterisk after the datatype char ``char *``
+indicates that this is an array of "pointers". All array names are
+actually pointers, so this is required to make an array of arrays.
+Pointers are one of the more esoteric parts of C for beginners to
+understand, but it isn't necessary to understand pointers in detail to
+use them effectively here::
+
+ char* myStrings[] = {"This is string 1", "This is string 2",
+ "This is string 3", "This is string 4",
+ "This is string 5", "This is string 6"};
+
+ void setup() {
+ SerialUSB.begin();
+ }
+
+ void loop() {
+ for (int i = 0; i < 6; i++) {
+ SerialUSB.println(myStrings[i]);
+ delay(500);
+ }
+ }
+
+
+See Also
+--------
+
+- :ref:`array <lang-array>`
+- :ref:`__attribute__ <arm-gcc-attribute-flash>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/switchcase.rst b/docs/source/lang/cpp/switchcase.rst
new file mode 100644
index 0000000..e31ccf3
--- /dev/null
+++ b/docs/source/lang/cpp/switchcase.rst
@@ -0,0 +1,118 @@
+.. highlight:: cpp
+
+.. _lang-switchcase:
+
+``switch``\ /\ ``case``
+=======================
+
+Like :ref:`if <lang-if>` statements, A ``switch`` statement controls
+program flow by allowing you to specify different code that should be
+executed under various cases.
+
+The general syntax looks like this::
+
+ switch (var) {
+ case val1:
+ // statements
+ break;
+ case val2:
+ // statements
+ break;
+ ...
+ default:
+ // statements
+ }
+
+Where ``var`` is a variable whose value to investigate, and the
+``val1``, ``val2`` after each ``case`` are constant values that
+``var`` might be.
+
+Description
+-----------
+
+A ``switch`` statement compares the value of a variable to the values
+specified in ``case`` statements. When a ``case`` statement is found
+whose value matches that of the variable, the code in that case
+statement is run.
+
+Here's a more concrete example::
+
+ switch (var) {
+ case 1:
+ doThing1();
+ break;
+ case 2:
+ doThing2();
+ break;
+ }
+ afterTheSwitch();
+
+In the above example, if ``var == 1``, then the code beginning on the
+line after ``case 1`` gets executed. That is, if ``var`` is one,
+``doThing1()`` gets called first, and then the ``break`` statement is
+executed.
+
+The ``break`` keyword exits the ``switch`` statement, and is typically
+used at the end of each ``case``. Since there is a ``break`` at the
+end of ``case 1``, the ``switch`` statement exits, and the next line
+to be run is the one which calls ``afterTheSwitch()``.
+
+Without a ``break``, the ``switch`` statement will continue executing
+the following ``case`` expressions ("falling-through") until a
+``break`` (or the end of the switch statement) is reached. Let's
+pretend the ``switch`` looked like this instead::
+
+ switch (var) {
+ case 1:
+ doThing1();
+ // no break statement anymore
+ case 2:
+ doThing2();
+ break;
+ }
+ afterTheSwitch();
+
+Now, if ``var`` is one, ``doThing1()`` gets executed like before.
+However, without a ``break``, the code would continue to be executed
+line-by-line, so ``doThing2()`` would be called next. At this point,
+a ``break`` has been reached, so the program continues by calling
+``afterTheSwitch()``. This is usually not what you want, which is why
+each ``case`` usually has a ``break`` at the end.
+
+.. _lang-switchcase-default:
+
+Writing "``default:``" instead of a ``case`` statement allows you to
+specify what to do if none of the ``case`` statements matches. Having
+a ``default`` is optional (you can leave it out), but if you have one,
+it must appear after all of the ``case`` statements. Let's add a
+``default`` to the ``switch`` we've been discussing::
+
+ switch (var) {
+ case 1:
+ doThing1();
+ break;
+ case 2:
+ doThing2();
+ break;
+ default:
+ doSomethingElse();
+ }
+ afterTheSwitch();
+
+If ``var`` is one, then ``doThing1()`` gets called. If ``var`` is
+two, ``doThing2()`` gets called. If ``var`` is anything else,
+``doSomethingElse()`` gets called. As stated above, a ``default`` is
+optional. If you're missing one and none of the ``case`` statements
+match, the ``switch`` does nothing at all, as if it weren't there.
+
+``switch`` statements are often used with an :ref:`enum <lang-enum>`
+value as the variable to compare. In this case, you can write down
+all of the values the ``enum`` takes as ``case`` statements, and be
+sure you've covered all the possibilities.
+
+See Also:
+---------
+
+- :ref:`if/else <lang-if>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/unsignedchar.rst b/docs/source/lang/cpp/unsignedchar.rst
new file mode 100644
index 0000000..45fedeb
--- /dev/null
+++ b/docs/source/lang/cpp/unsignedchar.rst
@@ -0,0 +1,32 @@
+.. highlight:: cpp
+
+.. _lang-unsignedchar:
+
+``unsigned char``
+=================
+
+An unsigned version of the :ref:`char <lang-char>` data type. An
+``unsigned char`` occupies 1 byte of memory; it stores an integer from
+0 to 255.
+
+Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned char``
+won't store negative numbers; it is also subject to the same
+:ref:`overflow issues <lang-int-overflow>` as any integral data type.
+
+Example
+-------
+
+ ::
+
+ unsigned char c = 240;
+
+See Also
+--------
+
+- :ref:`byte <lang-byte>`
+- :ref:`int <lang-int>`
+- :ref:`array <lang-array>`
+- :ref:`SerialUSB.println() <lang-serialusb-println>`
+- :ref:`Serial.println() <lang-serial-println>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/unsignedint.rst b/docs/source/lang/cpp/unsignedint.rst
new file mode 100644
index 0000000..f8ea473
--- /dev/null
+++ b/docs/source/lang/cpp/unsignedint.rst
@@ -0,0 +1,59 @@
+.. highlight:: cpp
+
+.. _lang-unsignedint:
+
+``unsigned int``
+================
+
+An ``unsigned int`` (unsigned integer) is the same as an :ref:`int
+<lang-int>` in that it stores a 4 byte integer value. However,
+Instead of storing both negative and positive numbers, an ``unsigned
+int`` can only store nonnegative values, yielding a range of 0 to
+4,294,967,295 (the positive value is 2^32 - 1).
+
+The difference between an ``unsigned int`` and a (signed) ``int`` lies
+in the way the highest bit, sometimes referred to as the "sign" bit,
+is interpreted. In the case of the Maple ``int`` type (which is
+signed), if the high bit is a "1", the number is interpreted as a
+negative number, using a technique known as `two's complement math
+<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_. The
+bits in an an ``unsigned int`` are interpreted according to the usual
+rules for converting `binary to decimal
+<http://en.wikipedia.org/wiki/Binary_numeral_system#Counting_in_binary>`_.
+
+An ``unsigned int`` is subject to the same :ref:`overflow issues
+<lang-int-overflow>` as a regular ``int``; the only difference is
+that an ``unsigned int`` will "underflow" at 0, and "overflow" at
+4,294,967,295. Here is some example code which illustrates this::
+
+ unsigned int x;
+ x = 0;
+ x--; // x now contains 4,294,967,295; rolled over "left to right"
+ x++; // x now contains 0; rolled over "right to left"
+
+.. _lang-unsignedlong:
+
+The ``unsigned long`` type is a synonym for ``unsigned int``.
+
+Here is an example of declaring an ``unsigned int`` variable named
+``pin``, then giving it value 13::
+
+ unsigned int pin = 13;
+
+The general syntax for declaring an ``unsigned int`` variable named
+``var``, then giving it value ``val``, looks like::
+
+ unsigned int var = val;
+
+See Also
+--------
+
+- :ref:`int <lang-int>`
+- :ref:`char <lang-char>`
+- :ref:`unsigned char <lang-unsignedchar>`
+- :ref:`long long <lang-longlong>`
+- :ref:`unsigned long long <lang-unsignedlonglong>`
+- :ref:`Integer Constants <lang-constants-integers>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/unsignedlonglong.rst b/docs/source/lang/cpp/unsignedlonglong.rst
new file mode 100644
index 0000000..a1143f0
--- /dev/null
+++ b/docs/source/lang/cpp/unsignedlonglong.rst
@@ -0,0 +1,43 @@
+.. highlight:: cpp
+
+.. _lang-unsignedlonglong:
+
+``unsigned long long``
+======================
+
+An unsigned version of the :ref:`long long <lang-longlong>` data type.
+An ``unsigned long long`` occupies 8 bytes of memory; it stores an
+integer from 0 to 2^64-1, which is approximately 1.8×10^19 (18
+quintillion, or 18 billion billion).
+
+A synonym for the ``unsigned long long`` type is ``uint64``.
+
+Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned long
+long`` won't store negative numbers; it is also subject to the same
+:ref:`overflow issues <lang-int-overflow>` as any integral data type.
+
+Here is an example of declaring an ``unsigned long long`` variable
+named ``c``, then giving it value 299,792,458,000,000,000 (see
+:ref:`integer constants <lang-constants-integers-u-l>` for an
+explanation of the "ULL" at the end of the number)::
+
+ // Speed of light in nanometers per second (approximate).
+ unsigned long long c = 299792458000000000ULL;
+
+The general syntax for declaring an ``unsigned long long`` variable named
+``var``, then giving it value ``val``, looks like::
+
+ unsigned long long var = val;
+
+See Also
+--------
+
+- :ref:`long long <lang-longlong>`
+- :ref:`int <lang-int>`
+- :ref:`unsigned <lang-unsignedint>`
+- :ref:`char <lang-char>`
+- :ref:`unsigned char <lang-unsignedchar>`
+- :ref:`Integer Constants <lang-constants-integers>`
+- :ref:`Variables <lang-variables>`
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/variables.rst b/docs/source/lang/cpp/variables.rst
new file mode 100644
index 0000000..9ffdd1d
--- /dev/null
+++ b/docs/source/lang/cpp/variables.rst
@@ -0,0 +1,169 @@
+.. highlight:: cpp
+
+.. _lang-variables:
+
+Variables
+=========
+
+A variable is a way of naming and storing a value for later use by
+the program, such as data from a sensor or an intermediate value
+used in a calculation.
+
+.. contents:: Contents
+ :local:
+
+.. _lang-variables-declaring:
+
+Declaring Variables
+-------------------
+
+Before they are used, all variables have to be *declared*. Declaring a
+variable means defining its type, giving it a name, and (optionally)
+giving it an initial value (this is often referred to as
+*initializing* the variable). Variables do not have to be initialized
+(given a value) when they are declared, but it is good style to give
+them an initial value whenever possible.
+
+Here is an example of declaring a variable named ``inputVariable1``
+with type :ref:`int <lang-int>` (the ``int`` type is used to store
+integers, like -2, -1, 0, 1, etc.)::
+
+ int inputVariable1;
+
+In the above declaration, we did not give the variable an initial
+value. Here is another example, where we declare an ``int`` variable
+named ``inputVariable2``, with an initial value of ``0``::
+
+ int inputVariable2 = 0;
+
+The Maple environment comes ready to use with many useful types of
+variables. See the :ref:`built-in types <lang-built-in-types>` page
+for more information.
+
+Here are a few examples of declaring variables of different types::
+
+ int lightSensVal;
+ char currentLetter;
+ unsigned long long speedOfLight = 186000ULL;
+ char errorMessage = {"choose another option"}; // see string
+
+Naming Variables
+----------------
+
+The rules for naming a variable are simple. Names for variables can
+contain letters, numbers, and underscores (the underscore is the
+:kbd:`_` character), and cannot begin with a number. So
+``temperature_reading``, ``tempReading``, ``tempReading1``, and
+``tempReading2`` are all valid variable names, but ``4_temp_readings``
+is not, because it begins with a number.
+
+You cannot choose a name for a variable that is one of the C++
+:ref:`keywords <lang-keywords>`.
+
+Variable names are case-sensitive, so "tempreading" and "tempReading"
+are different variables. However, it is very bad style to write code
+that chooses variables which are the same up to case.
+
+You should give your variables descriptive names, so as to make your
+code more readable. Variable names like ``tiltSensor`` or
+``pushButton`` help you (and anyone else reading your code) understand
+what the variable represents. Variable names like ``var`` or
+``value``, on the other hand, do little to make your code readable.
+
+.. _lang-variables-scope:
+
+Variable Scope
+--------------
+
+An important choice that programmers face is where (in the program
+text) to declare variables. The specific place that variables are
+declared influences how various functions in a program will "see" the
+variable. This is called variable *scope*. See the :ref:`scope
+reference <lang-scope>` for more information.
+
+.. _lang-variables-initializing:
+
+Initializing Variables
+----------------------
+
+Variables may be *initialized* (assigned a starting value) when they
+are declared or not. It is always good programming practice however to
+double check that a variable has valid data in it before it is used.
+Using a variable before you give it a value is a common source of
+bugs.
+
+.. _lang-variables-rollover:
+
+Variable Rollover
+-----------------
+
+Every (numeric) type has a valid *range*. The range of a type is the
+smallest and largest value that a variable of that type can store.
+For example, the :ref:`int <lang-int>` type has a range of
+-2,147,483,648 to 2,147,483,647 [#frange]_.
+
+When variables are made to exceed their range's maximum value, they
+"roll over" back to their minimum value. Note that this happens in
+both directions. It's like in the game *Pac-Man* -- when Pac-Man goes
+past the right edge of the screen, he reappears on the left, and when
+he goes past the left side of the screen, he reappears on the right::
+
+ int x;
+ x = -2,147,483,648;
+ x = x - 1; // x now contains -2,147,483,647; rolled over "left to right"
+
+ x = 2,147,483,647;
+ x = x + 1; // x now contains -2,147,483,648; rolled over "right to left"
+
+Each numeric type's reference page includes its range. See the
+:ref:`built-in types <lang-built-in-types>` reference for links to each
+type's reference page.
+
+Using Variables
+---------------
+
+Once variables have been declared, they are given values using the
+:ref:`assignment operator <lang-assignment>`, which is a single equals
+sign, ``=``. The assignment operator tells the program to store the
+value on the right side of the equals sign into the variable on the
+left side::
+
+ inputVariable1 = 7; // sets variable named inputVariable1 to 7
+ inputVariable2 = analogRead(2); // sets variable named inputVariable2 to
+ // the (digitized) input voltage read from
+ // analog pin #2
+
+Once a variable has been set (assigned a value), you can test its
+value to see if it meets certain conditions, or you can use its value
+directly. For instance, the following code tests whether the
+inputVariable2 is less than 100, then sets a delay based on
+inputVariable2 (which, at that point, is at least 100)::
+
+ if (inputVariable2 < 100) {
+ inputVariable2 = 100;
+ }
+
+ delay(inputVariable2);
+
+See Also
+--------
+
+- :ref:`lang-scope`
+- :ref:`lang-built-in-types`
+
+.. rubric:: Footnotes
+
+.. [#frange] This range might seem a little weird at first. The
+ reasons for this range of values have to do with the fact that an
+ ``int`` occupies 32 bits of memory, and the facts ::
+
+ 2^31 = -2,147,483,648
+ 2^31 - 1 = 2,147,483,647
+
+
+ Why 2^31 instead of 2^32? Well, that has to do with `how ints are
+ (usually) stored
+ <http://en.wikipedia.org/wiki/Two%27s_complement>`_ on computers.
+
+.. include:: /arduino-cc-attribution.txt
+
diff --git a/docs/source/lang/cpp/void.rst b/docs/source/lang/cpp/void.rst
new file mode 100644
index 0000000..7af0acd
--- /dev/null
+++ b/docs/source/lang/cpp/void.rst
@@ -0,0 +1,31 @@
+.. highlight:: cpp
+
+.. _lang-void:
+
+``void``
+========
+
+.. cpp:type:: void
+
+ The ``void`` keyword is used in function declarations. It indicates
+ that the function is expected to return no information to the
+ function from which it was called, or that it expects no arguments
+ from its caller.
+
+Example
+-------
+
+::
+
+ // actions are performed in the functions "setup" and "loop"
+ // but no information is reported to the larger program
+
+ void setup() {
+ // ...
+ }
+
+ void loop() {
+ // ...
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/cpp/while.rst b/docs/source/lang/cpp/while.rst
new file mode 100644
index 0000000..e66e0aa
--- /dev/null
+++ b/docs/source/lang/cpp/while.rst
@@ -0,0 +1,38 @@
+.. highlight:: cpp
+
+.. _lang-while:
+
+``while``
+=========
+
+Syntax
+------
+
+::
+
+ while (expression) {
+ // block of code
+ }
+
+Description
+-----------
+
+``while`` loops will repeat the statements inside their associated
+block of code until the expression inside the parentheses becomes
+:ref:`false <lang-constants-false>`. Something must change the tested
+expressions' value, or the ``while`` loop will never exit. This could
+be in your code, such as an incremented variable, or an external
+condition, such as testing a sensor.
+
+Example
+-------
+
+::
+
+ var = 0;
+ while(var < 200) {
+ // do something repetitive 200 times
+ var++;
+ }
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/lang/unimplemented/notone.rst b/docs/source/lang/unimplemented/notone.rst
new file mode 100644
index 0000000..8af878b
--- /dev/null
+++ b/docs/source/lang/unimplemented/notone.rst
@@ -0,0 +1,37 @@
+.. _lang-notone:
+
+noTone()
+========
+
+Description
+-----------
+
+Stops the generation of a square wave triggered by
+`tone <http://arduino.cc/en/Reference/Tone>`_\ (). Has no effect if
+no tone is being generated.
+
+**NOTE:** if you want to play different pitches on multiple pins,
+you need to call noTone() on one pin before calling tone() on the
+next pin.
+
+Syntax
+------
+
+noTone(pin)
+
+Parameters
+----------
+
+pin: the pin on which to stop generating the tone
+
+Returns
+-------
+
+Nothing.
+
+See Also
+--------
+
+- `tone <http://arduino.cc/en/Reference/Tone>`_ ()
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/unimplemented/pulsein.rst b/docs/source/lang/unimplemented/pulsein.rst
new file mode 100644
index 0000000..2b52428
--- /dev/null
+++ b/docs/source/lang/unimplemented/pulsein.rst
@@ -0,0 +1,82 @@
+.. _lang-pulsein:
+
+pulseIn()
+=========
+
+Description
+-----------
+
+Reads a pulse (either HIGH or LOW) on a pin. For example, if
+**value** is **HIGH**, **pulseIn()** waits for the pin to go
+**HIGH**, starts timing, then waits for the pin to go **LOW** and
+stops timing. Returns the length of the pulse in microseconds.
+Gives up and returns 0 if no pulse starts within a specified time
+out.
+
+
+
+The timing of this function has been determined empirically and
+will probably show errors in longer pulses. Works on pulses from 10
+microseconds to 3 minutes in length.
+
+
+
+Syntax
+------
+
+pulseIn(pin, value)
+pulseIn(pin, value, timeout)
+
+
+
+Parameters
+----------
+
+pin: the number of the pin on which you want to read the pulse.
+(*int*)
+
+
+
+value: type of pulse to read: either
+`HIGH <http://arduino.cc/en/Reference/Constants>`_ or
+`LOW <http://arduino.cc/en/Reference/Constants>`_. (*int*)
+
+
+
+timeout (optional): the number of microseconds to wait for the
+pulse to start; default is one second (*unsigned long*)
+
+
+
+Returns
+-------
+
+the length of the pulse (in microseconds) or 0 if no pulse started
+before the timeout (*unsigned long*)
+
+
+
+Example
+-------
+
+::
+
+
+
+ int pin = 7;
+ unsigned long duration;
+
+ void setup()
+ {
+ pinMode(pin, INPUT);
+ }
+
+ void loop()
+ {
+ duration = pulseIn(pin, HIGH);
+ }
+
+
+
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/unimplemented/stringclass.rst b/docs/source/lang/unimplemented/stringclass.rst
new file mode 100644
index 0000000..b893e83
--- /dev/null
+++ b/docs/source/lang/unimplemented/stringclass.rst
@@ -0,0 +1,6 @@
+.. _lang-stringclass:
+
+String Class
+============
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/unimplemented/stringobject.rst b/docs/source/lang/unimplemented/stringobject.rst
new file mode 100644
index 0000000..e47ed7e
--- /dev/null
+++ b/docs/source/lang/unimplemented/stringobject.rst
@@ -0,0 +1,89 @@
+.. _lang-stringobject:
+
+String
+======
+
+Description
+-----------
+
+The String class, part of the core as of version 0019, allows you to
+use and manipulate strings of text in more complex ways than character
+arrays do. You can concatenate Strings, append to them, search for and
+replace substrings, and more. It takes more memory than a simple
+character array, but it is also more useful.
+
+
+
+For reference, character arrays are referred to as strings with a
+small s, and instances of the String class are referred to as
+Strings with a capital S. Note that constant strings, specified in
+"double quotes" are treated as char arrays, not instances of the
+String class.
+
+
+
+Functions
+---------
+
+
+- `String <http://arduino.cc/en/Reference/StringConstructor>`_\ ()
+- `charAt <http://arduino.cc/en/Reference/StringCharAt>`_\ ()
+- `compareTo <http://arduino.cc/en/Reference/StringCompareTo>`_\ ()
+- `concat <http://arduino.cc/en/Reference/StringConcat>`_\ ()
+- `endsWith <http://arduino.cc/en/Reference/StringEndsWith>`_\ ()
+- `equals <http://arduino.cc/en/Reference/StringEquals>`_\ ()
+- `equalsIgnoreCase <http://arduino.cc/en/Reference/StringEqualsIgnoreCase>`_\ ()
+- `getBytes <http://arduino.cc/en/Reference/StringGetBytes>`_\ ()
+- `indexOf <http://arduino.cc/en/Reference/StringIndexOf>`_\ ()
+- `lastIndexOf <http://arduino.cc/en/Reference/StringLastIndexOf>`_\ ()
+- `length <http://arduino.cc/en/Reference/StringLength>`_\ ()
+- `replace <http://arduino.cc/en/Reference/StringReplace>`_\ ()
+- `setCharAt <http://arduino.cc/en/Reference/StringSetCharAt>`_\ ()
+- `startsWith <http://arduino.cc/en/Reference/StringStartsWith>`_\ ()
+- `substring <http://arduino.cc/en/Reference/StringSubstring>`_\ ()
+- `toCharArray <http://arduino.cc/en/Reference/StringToCharArray>`_\ ()
+- `toLowerCase <http://arduino.cc/en/Reference/StringToLowerCase>`_\ ()
+- `toUpperCase <http://arduino.cc/en/Reference/StringToUpperCase>`_\ ()
+- `trim <http://arduino.cc/en/Reference/StringTrim>`_\ ()
+
+
+
+Operators
+---------
+
+
+- `[] (element access) <http://arduino.cc/en/Reference/StringBrackets>`_
+- `+ (concatenation) <http://arduino.cc/en/Reference/StringPlus>`_
+- `== (comparison) <http://arduino.cc/en/Reference/StringComparison>`_
+
+
+
+Examples
+--------
+
+
+- `StringConstructors <http://arduino.cc/en/Tutorial/StringConstructors>`_
+- `StringAdditionOperator <http://arduino.cc/en/Tutorial/StringAdditionOperator>`_
+- `StringIndexOf <http://arduino.cc/en/Tutorial/StringIndexOf>`_
+- `StringAppendOperator <http://arduino.cc/en/Tutorial/StringAppendOperator>`_
+- `StringLengthTrim <http://arduino.cc/en/Tutorial/StringLengthTrim>`_
+- `StringCaseChanges <http://arduino.cc/en/Tutorial/StringCaseChanges>`_
+- `StringReplace <http://arduino.cc/en/Tutorial/StringReplace>`_
+- `StringCharacters <http://arduino.cc/en/Tutorial/StringCharacters>`_
+- `StringStartsWithEndsWith <http://arduino.cc/en/Tutorial/StringStartsWithEndsWith>`_
+- `StringComparisonOperators <http://arduino.cc/en/Tutorial/StringComparisonOperators>`_
+- `StringSubstring <http://arduino.cc/en/Tutorial/StringSubstring>`_
+
+
+
+See Also
+--------
+
+
+- `Character array strings <http://arduino.cc/en/Reference/String>`_
+- `Variable Declaration <http://arduino.cc/en/Reference/VariableDeclaration>`_
+
+
+
+
+.. include:: /lang/cc-attribution.txt
diff --git a/docs/source/lang/unimplemented/tone.rst b/docs/source/lang/unimplemented/tone.rst
new file mode 100644
index 0000000..13d581e
--- /dev/null
+++ b/docs/source/lang/unimplemented/tone.rst
@@ -0,0 +1,58 @@
+.. _lang-tone:
+
+tone()
+======
+
+Description
+-----------
+
+Generates a square wave of the specified frequency (and 50% duty
+cycle) on a pin. A duration can be specified, otherwise the wave
+continues until a call to
+`noTone <http://arduino.cc/en/Reference/NoTone>`_\ (). The pin can be
+connected to a piezo buzzer or other speaker to play tones.
+
+Only one tone can be generated at a time. If a tone is already
+playing on a different pin, the call to tone() will have no effect.
+If the tone is playing on the same pin, the call will set its
+frequency.
+
+Use of the tone() function will interfere with PWM output on pins 3
+and 11 (on boards other than the Mega).
+
+**NOTE:** if you want to play different pitches on multiple pins,
+you need to call noTone() on one pin before calling tone() on the
+next pin.
+
+Syntax
+------
+
+tone(pin, frequency)
+tone(pin, frequency, duration)
+
+Parameters
+----------
+
+pin: the pin on which to generate the tone
+
+frequency: the frequency of the tone in hertz
+
+duration: the duration of the tone in milliseconds (optional)
+
+Returns
+-------
+
+nothing
+
+See Also
+--------
+
+- `noTone <http://arduino.cc/en/Reference/NoTone>`_\ ()
+- `analogWrite <http://arduino.cc/en/Reference/AnalogWrite>`_\ ()
+- `Tutorial:Tone <http://arduino.cc/en/Tutorial/Tone>`_
+- `Tutorial:Pitch follower <http://arduino.cc/en/Tutorial/Tone2>`_
+- `Tutorial:Simple Keyboard <http://arduino.cc/en/Tutorial/Tone3>`_
+- `Tutorial: multiple tones <http://arduino.cc/en/Tutorial/Tone4>`_
+- `Tutorial: PWM <http://arduino.cc/en/Tutorial/PWM>`_
+
+.. include:: /arduino-cc-attribution.txt
diff --git a/docs/source/language-index.rst b/docs/source/language-index.rst
new file mode 100644
index 0000000..5e4c609
--- /dev/null
+++ b/docs/source/language-index.rst
@@ -0,0 +1,50 @@
+.. _language-index:
+
+=======================
+Complete Language Index
+=======================
+
+This is the index of Maple's :ref:`language reference
+<language-lang-docs>` documentation. The "Maple API" column provides
+API references for documented libmaple functionality. The "C++ for
+Maple" pages are intended as a minimal reference/refresher for
+programmers familiar with the Arduino language.
+
+.. admonition:: **Looking for Something Else?**
+
+ - See the :ref:`libraries` for extra built-in libraries for dealing
+ with different kinds of hardware.
+
+ - If you're looking for something from the C standard library (like
+ ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`.
+
+ - If you're looking for pointers to low-level details, see the
+ :ref:`Language Recommended Reading
+ <language-recommended-reading>` and :ref:`libmaple` pages.
+
+.. _index-language-index-cpp:
+.. _index-language-index-api:
+
++----------------------------------+------------------------------------+
+| Maple API | C++ for Maple |
+| | |
++==================================+====================================+
+| | |
+| .. toctree:: | .. toctree:: |
+| :maxdepth: 1 | :maxdepth: 1 |
+| :glob: | :glob: |
+| | |
+| lang/api/* | lang/cpp/* |
+| | |
++----------------------------------+------------------------------------+
+
+.. Unimplemented or not part of current release:
+
+.. toctree::
+ :hidden:
+
+ lang/unimplemented/tone.rst
+ lang/unimplemented/notone.rst
+ lang/unimplemented/pulsein.rst
+ lang/unimplemented/stringclass.rst
+ lang/unimplemented/stringobject.rst
diff --git a/docs/source/language.rst b/docs/source/language.rst
new file mode 100644
index 0000000..a24bb5f
--- /dev/null
+++ b/docs/source/language.rst
@@ -0,0 +1,431 @@
+.. highlight:: c++
+
+.. _language:
+
+====================
+ Language Reference
+====================
+
+The Maple can be programmed in the `Wiring
+<http://www.wiring.org.co/reference/>`_ language, which is the same
+language used to program the `Arduino <http://arduino.cc/>`_ boards.
+C or C++ programmers who are new to Wiring may wish to skip to the
+:ref:`arduino_c_for_c_hackers`.
+
+.. contents:: Contents
+ :local:
+
+.. admonition:: Looking for something else? Try these
+
+ - See the :ref:`libraries` for extra built-in libraries.
+
+ - If you prefer C or C++ over Wiring, see :ref:`libmaple` and the
+ :ref:`unix-toolchain`.
+
+ - If you're looking for something from the C standard library (like
+ ``atoi()``, for instance), see :ref:`this FAQ <faq-atoi>`.
+
+ - An :ref:`stm32` and other :ref:`language-recommended-reading` are
+ also available.
+
+.. _language-lang-docs:
+
+Maple Language Reference
+------------------------
+
+This table is a summary of the most important language features. See
+the :ref:`language-index` for a complete listing.
+
++--------------------------------------------+----------------------------------------------+---------------------------------------------------+
+| Structure | Variables | Functions |
+| | | |
++============================================+==============================================+===================================================+
+|* :ref:`setup() <lang-setup>` |**Constants** |**Digital I/O** |
+| | | |
+|* :ref:`loop() <lang-loop>` |* :ref:`HIGH <lang-constants-high>` | |* :ref:`pinMode() <lang-pinmode>` |
+| | :ref:`LOW <lang-constants-low>` | |
+| | |* :ref:`digitalWrite() <lang-digitalwrite>` |
+|**Control Structures** |* :ref:`INPUT <lang-constants-input>` | | |
+| | :ref:`OUTPUT <lang-constants-output>` |* :ref:`digitalRead() <lang-digitalread>` |
+|* :ref:`if/else <lang-if>` | | |
+| |* :ref:`true <lang-constants-true>` | |* :ref:`togglePin() <lang-togglepin>` |
+|* :ref:`for <lang-for>` | :ref:`false <lang-constants-false>` | |
+| | |* :ref:`toggleLED() <lang-toggleled>` |
+|* :ref:`switch/case <lang-switchcase>` |* :ref:`Constants | |
+| | <lang-constants>` (:ref:`integers |* :ref:`isButtonPressed() <lang-isbuttonpressed>` |
+|* :ref:`while <lang-while>` | <lang-constants-integers>`, :ref:`floating | |
+| | point <lang-constants-fp>`) |* :ref:`waitForButtonPress() |
+|* :ref:`do...while <lang-dowhile>` | | <lang-waitforbuttonpress>` |
+| |* :ref:`Board-specific values | |
+|* :ref:`break <lang-break>` | <lang-board-values>` |**Analog I/O** |
+| | | |
+|* :ref:`continue <lang-continue>` |**Data Types** |* :ref:`analogRead() <lang-analogread>` |
+| | | |
+|* :ref:`return <lang-return>` | The size of each data type, in bytes, is |* :ref:`pwmWrite() <lang-pwmwrite>` |
+| | given in parentheses where appropriate. | (:ref:`analogWrite() <lang-analogwrite>` is |
+|* :ref:`goto <lang-goto>` | | also available, though its use is discouraged) |
+| | *Note*: The ``word`` type is (deliberately) | |
+| | :ref:`not supported <language-no-word>`. | |
+|**Further syntax** | |**Advanced I/O** |
+| |* :ref:`void <lang-void>` | |
+|* :ref:`; (semicolon) <lang-semicolon>` | |* tone(): TODO |
+| |* :ref:`boolean <lang-boolean>` (1 byte) | |
+|* :ref:`{} (curly braces) | |* noTone(): TODO |
+| <lang-curly-braces>` |* :ref:`char <lang-char>` (1 byte) | |
+| | |* :ref:`shiftOut() <lang-shiftout>` |
+|* :ref:`// (single-line comment) |* :ref:`unsigned char | |
+| <lang-comments-singleline>` | <lang-unsignedchar>` (1 byte) |* pulseIn(): TODO |
+| | | |
+|* :ref:`/\* \*/ (multi-line comment) |* :ref:`byte <lang-byte>` (1 byte) | |
+| <lang-comments-multiline>` | |**Time** |
+| |* :ref:`int <lang-int>` (4 bytes) | |
+|* :ref:`#define <lang-define>` | |* :ref:`millis() <lang-millis>` |
+| |* :ref:`unsigned int <lang-unsignedint>` | |
+|* :ref:`#include <lang-include>` | (4 bytes) |* :ref:`micros() <lang-micros>` |
+| | | |
+| |* ``long`` (4 bytes), synonym for :ref:`int |* :ref:`delay() <lang-delay>` |
+|**Arithmetic Operators** | <lang-int>` | |
+| | |* :ref:`delayMicroseconds() |
+|* :ref:`= <lang-assignment>` |* ``unsigned long`` (4 bytes), synonym for | <lang-delaymicroseconds>` |
+| (assignment) | :ref:`unsigned int <lang-unsignedint>` | |
+| | | |
+|* :ref:`+ <lang-arithmetic>` (addition) |* :ref:`long long <lang-longlong>` (8 bytes) |**Math** |
+| | | |
+|* :ref:`- <lang-arithmetic>` |* :ref:`unsigned long |* :ref:`min() <lang-min>` |
+| (subtraction) | long <lang-unsignedlonglong>` (8 bytes) | |
+| | |* :ref:`max() <lang-max>` |
+|* :ref:`* <lang-arithmetic>` |* :ref:`float <lang-float>` (4 bytes) | |
+| (multiplication) | |* :ref:`abs() <lang-abs>` |
+| |* :ref:`double <lang-double>` (8 bytes) | |
+|* :ref:`/ <lang-arithmetic>` (division) | |* :ref:`constrain() <lang-constrain>` |
+| |* :ref:`strings <lang-string>` | |
+|* :ref:`% <lang-modulo>` (modulo) | |* :ref:`map() <lang-map>` |
+| |* :ref:`arrays <lang-array>` | |
+| | |* :ref:`pow() <lang-pow>` |
+|**Comparison Operators** |* :ref:`enum <lang-enum>` | |
+| | |* :ref:`sqrt() <lang-sqrt>` |
+|* :ref:`== <lang-comparison>` (equal to) |* :ref:`numeric types <lang-built-in-types>` | |
+| | | |
+|* :ref:`\!= <lang-comparison>` |**Conversion** |**Trigonometry** |
+| (not equal to) | | |
+| |* :ref:`char() <lang-charcast>` |* :ref:`sin() <lang-sin>` |
+|* :ref:`< <lang-comparison>` (less than) | | |
+| |* :ref:`byte() <lang-bytecast>` |* :ref:`cos() <lang-cos>` |
+|* :ref:`> <lang-comparison>` | | |
+| (greater than) |* :ref:`int() <lang-intcast>` |* :ref:`tan() <lang-tan>` |
+| | | |
+|* :ref:`<= <lang-comparison>` |* :ref:`long() <lang-longcast>` | |
+| (less than or equal to) | |**Random Numbers** |
+| |* :ref:`float() <lang-floatcast>` | |
+|* :ref:`>= <lang-comparison>` | |* :ref:`randomSeed() <lang-randomseed>` |
+| (greater than or equal to) |* :ref:`double() <lang-doublecast>` | |
+| | |* :ref:`random() <lang-random>` |
+| | | |
+|**Boolean Operators** |**Variable Scope & Qualifiers** | |
+| | |**Bits and Bytes** |
+|* :ref:`&& <lang-boolean-and>` (and) |* :ref:`variables <lang-variables>`, | |
+| | :ref:`scope <lang-variables-scope>` |* :ref:`lowByte() <lang-lowbyte>` |
+|* :ref:`|| <lang-boolean-or>` (or) | | |
+| |* :ref:`static <lang-static>` |* :ref:`highByte() <lang-highbyte>` is |
+|* :ref:`\! <lang-boolean-not>` (not) | | provided, though its use is discouraged. |
+| |* :ref:`volatile <lang-volatile>` | |
+| | |* :ref:`bitRead() <lang-bitread>` |
+|**Pointer Operators** |* :ref:`const <lang-const>` | |
+| | |* :ref:`bitWrite() <lang-bitwrite>` |
+|* :ref:`* dereference operator | | |
+| <lang-pointer>` |**Utilities** |* :ref:`bitSet() <lang-bitset>` |
+| | | |
+|* :ref:`& reference operator |* :ref:`sizeof() <lang-sizeof>` |* :ref:`bitClear() <lang-bitclear>` |
+| <lang-pointer>` | | |
+| |* :ref:`ASSERT() <lang-assert>` |* :ref:`bit() <lang-bit>` |
+| | | |
+|**Bitwise Operators** | | |
+| | |**External Interrupts** |
+|* :ref:`& <lang-bitwisemath-and>` | | |
+| (bitwise and) | |* :ref:`Reference Page <external-interrupts>` |
+| | | |
+|* :ref:`| <lang-bitwisemath-or>` | |* :ref:`attachInterrupt() |
+| (bitwise or) | | <lang-attachinterrupt>` |
+| | | |
+|* :ref:`^ <lang-bitwisemath-xor>` | |* :ref:`detachInterrupt() |
+| (bitwise xor) | | <lang-detachinterrupt>` |
+| | | |
+|* :ref:`~ <lang-bitwisemath-not>` | | |
+| (bitwise not) | |**Interrupts** |
+| | | |
+|* :ref:`\<\< <lang-bitshift>` | |* :ref:`interrupts() <lang-interrupts>` |
+| (shift left) | | |
+| | |* :ref:`noInterrupts() <lang-nointerrupts>` |
+|* :ref:`>> <lang-bitshift>` | | |
+| (shift right) | | |
+| | |**Communication** |
+| | | |
+|**Compound Operators** | |* :ref:`SerialUSB <lang-serialusb>` |
+| | | |
+|* :ref:`++ <lang-increment>` | |* :ref:`Serial <lang-serial>` |
+| (increment) | | |
+| | | |
+|* :ref:`- - <lang-increment>` | | |
+| (decrement) | | |
+| | | |
+|* :ref:`+= <lang-compoundarithmetic>` | | |
+| (compound add) | | |
+| | | |
+|* :ref:`-= | | |
+| <lang-compoundarithmetic>` (compound | | |
+| subtract) | | |
+| | | |
+|* :ref:`*= | | |
+| <lang-compoundarithmetic>` (compound | | |
+| multiply) | | |
+| | | |
+|* :ref:`/= | | |
+| <lang-compoundarithmetic>` (compound | | |
+| divide) | | |
+| | | |
+|* :ref:`&= | | |
+| <lang-compoundbitwise>` (compound | | |
+| bitwise and) | | |
+| | | |
+|* :ref:`|= | | |
+| <lang-compoundbitwise>` (compound | | |
+| bitwise or) | | |
+| | | |
+|**Keywords** | | |
+| | | |
+|* :ref:`C++ Keywords <lang-keywords>` | | |
+| | | |
+| | | |
++--------------------------------------------+----------------------------------------------+---------------------------------------------------+
+
+.. _language-missing-features:
+
+Missing Arduino Features
+------------------------
+
+.. _langage-missing-analogreference:
+
+**analogReference()**
+
+ It is not possible to implement this function on the Maple
+ hardware. It will be possible on the upcoming Maple Native.
+
+.. _language-no-word:
+
+**word**
+
+ Readers familiar with the Arduino environment may notice that the
+ ``word`` datatype is missing from the above table's list of data
+ types. We chose **not to provide** the ``word`` data type on the
+ Maple. If you want a 16-bit unsigned integer, use the ``uint16``
+ type instead.
+
+ While the Maple has 32-bit words, the word size on an Arduino
+ board is only 16 bits, and code that uses the ``word`` type is
+ likely to rely on that fact.
+
+ By not supporting ``word``, you'll get a compile error when
+ porting Arduino code to the Maple instead of potentially weird,
+ hard-to-debug runtime behavior.
+
+ If you really must have ``word``, you can include the following
+ ``typedef`` in your program::
+
+ typedef uint16 word;
+
+Unimplemented Arduino Features
+------------------------------
+
+The following Wiring/Arduino features are currently unimplemented on
+the Maple.
+
+- `tone() <http://www.arduino.cc/en/Reference/Tone>`_
+- `noTone() <http://www.arduino.cc/en/Reference/NoTone>`_
+- `pulseIn() <http://www.arduino.cc/en/Reference/PulseIn>`_
+- `String <http://arduino.cc/en/Reference/StringObject>`_
+
+.. _our reference page: http://leaflabs.com/docs/external-interrupts/
+
+.. _newlib: http://sourceware.org/newlib/
+
+.. _cpp-for-maple:
+
+C++ for Maple
+--------------
+
+If you haven't programmed in C++, or if you just need to jog your
+memory, you may want to check out our :ref:`Language Index
+<language-index>`. It provides some introductory coverage of
+programming ideas and C++.
+
+.. _arduino_c_for_c_hackers:
+
+Note for C/C++ Hackers
+----------------------
+
+This is a note for programmers comfortable with C or C++ who want a
+better understanding of the differences between C++ and the Wiring
+language.
+
+The good news is that the differences are relatively few; Wiring is
+just a thin wrapper around C++. Some potentially better news is that
+the Maple can be programmed using a :ref:`standard Unix toolchain
+<unix-toolchain>`, so if you'd rather stick with :command:`gcc`,
+:command:`make`, and friends, you can. If you're using the Unix
+toolchain and want to skip past the Wiring conveniences and get
+straight to the details, you are encouraged to move on to the
+:ref:`libmaple` documentation.
+
+A *sketch* is the IDE's notion of a project; it consists of one or
+more files written in the Wiring language, which is mostly the same as
+C++. The major difference between the two is that in Wiring, it's not
+necessary to declare global functions before they are used. That is,
+the following is valid Wiring, and ``f()`` returns ``5``::
+
+ int f() {
+ return g();
+ }
+
+ int g() {
+ return 5;
+ }
+
+All of the files in a sketch share the same (global) namespace. That
+is, the behavior is as if all of a sketch's files were part of the
+same translation unit, so they don't have to include one another in
+order to access each other's definitions.
+
+The Wiring language also does not require you to define your own
+``main`` method (in fact, we currently forbid you from doing so).
+Instead, you are required to define two functions, ``setup`` and
+``loop``, whose prototypes are ::
+
+ void setup(void);
+ void loop(void);
+
+Once a sketch is uploaded to a Maple and begins to run, ``setup()`` is
+called once, and then ``loop()`` is called repeatedly, forever. The
+IDE compilation process proceeds via a source-to-source translation
+from the files in a sketch to C++.
+
+This translation process first concatenates the sketch files, then
+parses the result to produce a list of all functions defined in the
+global scope. (We borrow this stage from the Arduino IDE, which in
+turn borrows it from Wiring. It uses regular expressions to parse
+C++, which is, of course, `Bad and Wrong
+<http://www.retrologic.com/jargon/B/Bad-and-Wrong.html>`_. In the
+future, we'll do this correctly, using a better parser. Until then,
+you have our apologies.) The order in which the individual sketch
+files are concatenated is not defined; it is unwise to write code that
+depends on a particular ordering.
+
+The concatenated sketch files are then appended onto a file which
+includes `WProgram.h
+<https://github.com/leaflabs/libmaple/blob/master/wirish/WProgram.h>`_
+(which includes the Wirish and libmaple proper libraries, and declares
+``setup()`` and ``loop()``), and then provides declarations for all
+the function definitions found in the previous step. At this point,
+we have a file that is a valid C++ translation unit, but lacks
+``main()``. The final step of compilation provides ``main()``, which
+behaves roughly like::
+
+ int main(void) {
+ // Call libmaple's built-in initialization routines
+ init();
+
+ // Perform the user's initialization
+ setup();
+
+ // Call user loop() forever.
+ while (true) {
+ loop();
+ }
+ }
+
+(The truth is a little bit more complicated, but not by much).
+
+As an example, consider a sketch with two files. The first file
+contains ``setup()`` and ``loop()``::
+
+ int the_pin;
+
+ void setup() {
+ the_pin = choose_a_pin();
+ pinMode(the_pin, OUTPUT);
+ }
+
+ void loop() {
+ togglePin(the_pin);
+ }
+
+The second file contains the (not very useful) implementation for
+``choose_a_pin()``::
+
+ int choose_a_pin() {
+ return random(5, 15);
+ }
+
+Then the results of the concatenation process might be ::
+
+ int the_pin;
+
+ void setup() {
+ the_pin = choose_a_pin();
+ pinMode(the_pin, OUTPUT);
+ }
+
+ void loop() {
+ togglePin(the_pin);
+ }
+
+ int choose_a_pin(void);
+
+ int choose_a_pin() {
+ return random(5, 15);
+ }
+
+Which could plausibly be turned into the final source file ::
+
+ #include "WProgram.h"
+
+ void setup(void);
+ void loop(void);
+ int choose_a_pin(void);
+
+ int the_pin;
+
+ void setup() {
+ the_pin = choose_a_pin();
+ pinMode(the_pin, OUTPUT);
+ }
+
+ void loop() {
+ togglePin(the_pin);
+ }
+
+ int choose_a_pin(void);
+
+ int choose_a_pin() {
+ return random(5, 15);
+ }
+
+ int main() {
+ init();
+ setup();
+ while (true) loop();
+ }
+
+.. _language-recommended-reading:
+
+Recommended Reading
+-------------------
+
+* :ref:`Your board's documentation <index-boards>` page, which
+ includes references to the relevant ST materials (reference manual,
+ datashseet, etc.) for your board.
+* `ARM Cortex-M3 Technical Reference Manual, Revision r1p1 <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf>`_
+ (PDF). This ARM manual specifies the Cortex-M3 architecture,
+ including instruction timings.
+* :ref:`libmaple`
+* `newlib's Documentation <http://sourceware.org/newlib/>`_
+ (see :ref:`arm-gcc-libc`)
diff --git a/docs/source/libmaple.rst b/docs/source/libmaple.rst
new file mode 100644
index 0000000..458241e
--- /dev/null
+++ b/docs/source/libmaple.rst
@@ -0,0 +1,48 @@
+.. highlight:: sh
+
+.. _libmaple:
+
+``libmaple``
+============
+
+LeafLabs' libmaple is the open source library we have developed for
+programming the `STM32 <http://www.st.com/stonline>`_ line of
+microcontrollers. Libmaple's `source is on GitHub
+<https://github.com/leaflabs/libmaple>`_; :ref:`patches are welcome
+<libmaple-contributing>`.
+
+.. _libmaple-vs-wirish:
+
+Libmaple is split into two pieces:
+
+- A low-level layer, written in C, called *libmaple proper*, located
+ in the `libmaple/
+ <https://github.com/leaflabs/libmaple/tree/master/libmaple>`_
+ subdirectory of the source repository.
+
+- A high-level layer, written in C++, called *wirish*, in the `wirish/
+ <https://github.com/leaflabs/libmaple/tree/master/wirish>`_
+ subdirectory.
+
+Wirish is :ref:`largely compatible <arduino-compatibility>` with the
+AVR libraries written for the `Arduino <http://arduino.cc>`_ and
+`Wiring <http://wiring.org.co/>`_ development boards. The Wirish
+:ref:`language` page is a good summary of what Wirish provides; a
+:ref:`complete Wirish API index <language-index>` is also
+available. :ref:`Wirish libraries <libraries>` are documented
+separately.
+
+libmaple is bundled with the :ref:`Maple IDE <ide>`. However, we
+develop it separately, and :ref:`release it standalone
+<unix-toolchain>` for users who might chafe at the "sketch"
+programming model of the IDE. The following pages document libmaple
+proper. As such, they're intended for advanced users who know how to
+write C.
+
+.. toctree::
+ :maxdepth: 1
+
+ libmaple/overview
+ libmaple/apis
+ libmaple/contributing
+ libmaple/coding-standard
diff --git a/docs/source/libmaple/api/adc.rst b/docs/source/libmaple/api/adc.rst
new file mode 100644
index 0000000..2f06926
--- /dev/null
+++ b/docs/source/libmaple/api/adc.rst
@@ -0,0 +1,231 @@
+.. highlight:: c
+.. _libmaple-adc:
+
+``<libmaple/adc.h>``
+====================
+
+:ref:`Analog to Digital Conversion <adc>` (ADC) support.
+
+A common API for basic ADC functionality is available, but the
+characteristics of the ADC peripherals vary slightly across
+targets. To manage this, each target defines a small set of datatypes
+expressing its capabilities (namely :ref:`adc_extsel_event
+<adc-adc_extsel_event>`, :ref:`adc_smp_rate <adc-adc_smp_rate>`, and
+:ref:`adc_prescaler <adc-adc_prescaler>`).
+
+.. contents:: Contents
+ :local:
+ :depth: 2
+
+Devices
+-------
+
+The individual ADC peripherals have the following device struct.
+
+.. doxygenstruct:: adc_dev
+
+The available ADC peripherals vary by target. The complete list is
+``ADC1``, ``ADC2``, and ``ADC3``.
+
+.. doxygenvariable:: ADC1
+.. doxygenvariable:: ADC2
+.. doxygenvariable:: ADC3
+
+Functions
+---------
+
+Activation and Deactivation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``adc_enable_single_swstart()`` is simple, portable function, which
+enables an ADC and sets it up for its basic usage: performing single
+conversions using :ref:`adc_read() <adc-adc_read>`.
+
+.. _adc-adc_enable_single_swstart:
+.. doxygenfunction:: adc_enable_single_swstart
+
+The precise software sequence used varies by target, so this is a good
+function to use if your program needs to support multiple MCUs. By
+default, Wirish calls ``adc_enable_single_swstart()`` on all available
+ADCs at ``init()`` time, so Wirish users don't have to call this
+function.
+
+There are several other lower-level routines used for activating and
+deactivating ADCs:
+
+.. _adc-adc_init:
+.. doxygenfunction:: adc_init
+.. _adc-adc_enable:
+.. doxygenfunction:: adc_enable
+.. _adc-adc_disable:
+.. doxygenfunction:: adc_disable
+.. _adc-adc_disable_all:
+.. doxygenfunction:: adc_disable_all
+
+ADC Conversion
+~~~~~~~~~~~~~~
+
+``adc_read()`` is a simple function which starts conversion on a
+single ADC channel, blocks until it has completed, and returns the
+converted result. Don't use the ADC device for any other purpose while
+it's running.
+
+.. _adc-adc_read:
+.. doxygenfunction:: adc_read
+
+To use ``adc_read()``, the device must be configured appropriately.
+You can do this with :ref:`adc_enable_single_swstart()
+<adc-adc_enable_single_swstart>`.
+
+Note that for an ADC device to perform conversion on a GPIO input
+(which is the usual case; the notable exception being taking
+temperature reading), the pin must be configured for analog
+conversion. Do this with :ref:`adc_config_gpio()
+<adc-adc_config_gpio>`.
+
+Other routines helpful for ADC conversion:
+
+.. _adc-adc_set_reg_seqlen:
+.. doxygenfunction:: adc_set_reg_seqlen
+.. _adc-adc_set_extsel:
+.. doxygenfunction:: adc_set_extsel
+
+.. _adc-adc_extsel_event:
+
+The last of these, :ref:`adc_set_extsel() <adc-adc_set_extsel>`, takes
+a target-dependent ``adc_extsel_event`` argument.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_extsel_event
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_extsel_event
+
+ADC Clock Prescaler
+~~~~~~~~~~~~~~~~~~~
+
+``adc_set_prescaler()`` is available for setting the prescaler which
+determines the common ADC clock rate. (Wirish sets a sensible default
+for this, so Wirish users ordinarily don't need to call this
+function.)
+
+.. warning:: Increasing the ADC clock rate does speed conversion time,
+ but the ADC peripherals have a maximum clock rate which must not be
+ exceeded. Make sure to configure your system and ADC clocks to
+ respect your device's maximum rate.
+
+.. _adc_adc_set_prescaler:
+.. doxygenfunction:: adc_set_prescaler
+
+.. _adc-adc_prescaler:
+
+ADC prescaler values are target-dependent.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_prescaler
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_prescaler
+
+.. _adc-adc_set_sample_rate:
+
+ADC Sample Time
+~~~~~~~~~~~~~~~
+
+You can control the sampling time (in ADC cycles) for an entire ADC
+device using ``adc_set_sample_rate()`` [#fchansamp]_. This function
+**only controls the sample rate**; the total conversion time is equal
+to the sample time plus an additional number of ADC cycles. Consult
+the reference manual for your chip for more details.
+
+.. warning:: Decreasing ADC sample time speeds conversion, but it also
+ decreases the maximum allowable impedance of the voltage source you
+ are measuring. If your voltage source has a high impedance
+ (e.g. you're measuring Vcc through a potentiometer), and your
+ sample time is too low, you will get inaccurate results. Consult
+ the datasheet for your target for more details.
+
+.. note:: Wirish sets a sensible default sample rate to allow for
+ high-impedance inputs at ``init()`` time, but Wirish users who know
+ what they're doing may want to call this function to speed up ADC
+ conversion.
+
+.. doxygenfunction:: adc_set_sample_rate
+
+.. _adc-adc_smp_rate:
+
+The ``adc_smp_rate`` argument to :ref:`adc_set_sample_rate()
+<adc-adc_set_sample_rate>` is target-dependent.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_smp_rate
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_smp_rate
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+.. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up?
+
+.. _adc-adc_foreach:
+.. doxygenfunction:: adc_foreach
+
+.. _adc-adc_config_gpio:
+.. doxygenfunction:: adc_config_gpio
+
+STM32F1 only
+~~~~~~~~~~~~
+
+The following routines are available only on STM32F1 targets.
+
+.. _adc-adc_set_exttrig:
+.. doxygenfunction:: adc_set_exttrig
+
+``adc_calibrate()`` performs calibration necessary on STM32F1 before
+using an ADC. Note that on STM32F1 targets,
+:ref:`adc_enable_single_swstart() <adc-adc_enable_single_swstart>`
+calls ``adc_calibrate()``, so there's no need to do it separately.
+
+.. _adc-adc_calibrate:
+.. doxygenfunction:: adc_calibrate
+
+Register Maps
+-------------
+
+Individual ADC peripherals have the following register map. The base
+pointers are ``ADC1_BASE``, ``ADC2_BASE``, and ``ADC3_BASE``.
+
+.. _adc-adc_reg_map:
+.. doxygenstruct:: adc_reg_map
+
+On **STM32F2 targets**, there is an additional common set of registers
+shared by all ADC peripherals. Its base pointer is
+``ADC_COMMON_BASE``.
+
+.. _adc-adc_common_reg_map:
+.. doxygenstruct:: stm32f2::adc_common_reg_map
+
+Register Bit Definitions
+------------------------
+
+.. TODO [0.0.13]
+
+TODO
+
+.. rubric:: Footnotes
+
+.. [#fchansamp] Per-channel sample time configuration is possible,
+ but currently unsupported.
diff --git a/docs/source/libmaple/api/bitband.rst b/docs/source/libmaple/api/bitband.rst
new file mode 100644
index 0000000..768f678
--- /dev/null
+++ b/docs/source/libmaple/api/bitband.rst
@@ -0,0 +1,15 @@
+.. highlight:: c
+.. _libmaple-bitband:
+
+``<libmaple/bitband.h>``
+========================
+
+Bit-banding support.
+
+Functions
+---------
+
+.. doxygenfunction:: bb_sram_get_bit
+.. doxygenfunction:: bb_sram_set_bit
+.. doxygenfunction:: bb_peri_get_bit
+.. doxygenfunction:: bb_peri_set_bit
diff --git a/docs/source/libmaple/api/bkp.rst b/docs/source/libmaple/api/bkp.rst
new file mode 100644
index 0000000..4f0115b
--- /dev/null
+++ b/docs/source/libmaple/api/bkp.rst
@@ -0,0 +1,79 @@
+.. highlight:: c
+.. _libmaple-bkp:
+
+``bkp.h``
+=========
+
+Backup register (BKP) suport.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: bkp_dev
+.. doxygenstruct:: bkp_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: BKP
+
+Convenience Functions
+---------------------
+
+.. doxygenfunction:: bkp_init
+.. doxygenfunction:: bkp_enable_writes
+.. doxygenfunction:: bkp_disable_writes
+.. doxygenfunction:: bkp_read
+.. doxygenfunction:: bkp_write
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: BKP_BASE
+
+Register Bit Definitions
+------------------------
+
+Data Registers
+~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_DR_D
+
+RTC Clock Calibration Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_RTCCR_ASOS_BIT
+.. doxygendefine:: BKP_RTCCR_ASOE_BIT
+.. doxygendefine:: BKP_RTCCR_CCO_BIT
+
+.. doxygendefine:: BKP_RTCCR_ASOS
+.. doxygendefine:: BKP_RTCCR_ASOE
+.. doxygendefine:: BKP_RTCCR_CCO
+.. doxygendefine:: BKP_RTCCR_CAL
+
+Backup control register
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_CR_TPAL_BIT
+.. doxygendefine:: BKP_CR_TPE_BIT
+
+.. doxygendefine:: BKP_CR_TPAL
+.. doxygendefine:: BKP_CR_TPE
+
+Backup control/status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_CSR_TIF_BIT
+.. doxygendefine:: BKP_CSR_TEF_BIT
+.. doxygendefine:: BKP_CSR_TPIE_BIT
+.. doxygendefine:: BKP_CSR_CTI_BIT
+.. doxygendefine:: BKP_CSR_CTE_BIT
+
+.. doxygendefine:: BKP_CSR_TIF
+.. doxygendefine:: BKP_CSR_TEF
+.. doxygendefine:: BKP_CSR_TPIE
+.. doxygendefine:: BKP_CSR_CTI
+.. doxygendefine:: BKP_CSR_CTE
diff --git a/docs/source/libmaple/api/dac.rst b/docs/source/libmaple/api/dac.rst
new file mode 100644
index 0000000..55c8faf
--- /dev/null
+++ b/docs/source/libmaple/api/dac.rst
@@ -0,0 +1,123 @@
+.. highlight:: c
+.. _libmaple-dac:
+
+``dac.h``
+=========
+
+Digital to Analog Conversion (DAC) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: dac_dev
+.. doxygenstruct:: dac_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: DAC
+
+Functions
+---------
+
+.. doxygenfunction:: dac_init
+.. doxygenfunction:: dac_write_channel
+.. doxygenfunction:: dac_enable_channel
+.. doxygenfunction:: dac_disable_channel
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: DAC_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register
+~~~~~~~~~~~~~~~~
+
+**Channel 1**:
+
+.. doxygendefine:: DAC_CR_EN1
+.. doxygendefine:: DAC_CR_BOFF1
+.. doxygendefine:: DAC_CR_TEN1
+.. doxygendefine:: DAC_CR_TSEL1
+.. doxygendefine:: DAC_CR_WAVE1
+.. doxygendefine:: DAC_CR_MAMP1
+.. doxygendefine:: DAC_CR_DMAEN1
+
+**Channel 2**:
+
+.. doxygendefine:: DAC_CR_EN2
+.. doxygendefine:: DAC_CR_BOFF2
+.. doxygendefine:: DAC_CR_TEN2
+.. doxygendefine:: DAC_CR_TSEL2
+.. doxygendefine:: DAC_CR_WAVE2
+.. doxygendefine:: DAC_CR_MAMP2
+.. doxygendefine:: DAC_CR_DMAEN2
+
+Software trigger register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_SWTRIGR_SWTRIG1
+.. doxygendefine:: DAC_SWTRIGR_SWTRIG2
+
+Channel 1 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12R1_DACC1DHR
+
+Channel 1 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12L1_DACC1DHR
+
+Channel 1 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8R1_DACC1DHR
+
+Channel 2 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12R2_DACC2DHR
+
+Channel 2 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12L2_DACC2DHR
+
+Channel 2 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8R2_DACC2DHR
+
+Dual DAC 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12RD_DACC1DHR
+.. doxygendefine:: DAC_DHR12RD_DACC2DHR
+
+Dual DAC 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12LD_DACC1DHR
+.. doxygendefine:: DAC_DHR12LD_DACC2DHR
+
+Dual DAC 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8RD_DACC1DHR
+.. doxygendefine:: DAC_DHR8RD_DACC2DHR
+
+Channel 1 data output register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DOR1_DACC1DOR
+
+Channel 1 data output register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. doxygendefine:: DAC_DOR2_DACC2DOR
diff --git a/docs/source/libmaple/api/delay.rst b/docs/source/libmaple/api/delay.rst
new file mode 100644
index 0000000..d11496b
--- /dev/null
+++ b/docs/source/libmaple/api/delay.rst
@@ -0,0 +1,11 @@
+.. highlight:: c
+.. _libmaple-delay:
+
+``<libmaple/delay.h>``
+======================
+
+Provides a simple busy-loop delay function. Note that this function
+does not account for time spent in interrupts, so actual delay times
+may vary depending on your application.
+
+.. doxygenfunction:: delay_us
diff --git a/docs/source/libmaple/api/dma.rst b/docs/source/libmaple/api/dma.rst
new file mode 100644
index 0000000..a9893e2
--- /dev/null
+++ b/docs/source/libmaple/api/dma.rst
@@ -0,0 +1,215 @@
+.. highlight:: c
+.. _libmaple-dma:
+
+``dma.h``
+=========
+
+Direct Memory Access (DMA) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: dma_reg_map
+.. doxygenstruct:: dma_dev
+.. doxygenstruct:: dma_handler_config
+.. doxygenenum:: dma_mode_flags
+.. doxygenenum:: dma_xfer_size
+.. doxygenenum:: dma_channel
+.. doxygenenum:: dma_priority
+.. doxygenenum:: dma_irq_cause
+.. doxygenstruct:: dma_channel_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: DMA1
+.. doxygenvariable:: DMA2
+
+Functions
+---------
+
+.. doxygenfunction:: dma_init
+.. doxygenfunction:: dma_setup_transfer
+.. doxygenfunction:: dma_set_num_transfers
+.. doxygenfunction:: dma_set_priority
+.. doxygenfunction:: dma_attach_interrupt
+.. doxygenfunction:: dma_detach_interrupt
+.. doxygenfunction:: dma_get_irq_cause
+.. doxygenfunction:: dma_enable
+.. doxygenfunction:: dma_disable
+.. doxygenfunction:: dma_set_mem_addr
+.. doxygenfunction:: dma_set_per_addr
+.. doxygenfunction:: dma_channel_regs
+.. doxygenfunction:: dma_is_channel_enabled
+.. doxygenfunction:: dma_get_isr_bits
+.. doxygenfunction:: dma_clear_isr_bits
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: DMA1_BASE
+.. doxygendefine:: DMA2_BASE
+
+Register Bit Definitions
+------------------------
+
+Interrupt status register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_ISR_TEIF7_BIT
+.. doxygendefine:: DMA_ISR_HTIF7_BIT
+.. doxygendefine:: DMA_ISR_TCIF7_BIT
+.. doxygendefine:: DMA_ISR_GIF7_BIT
+.. doxygendefine:: DMA_ISR_TEIF6_BIT
+.. doxygendefine:: DMA_ISR_HTIF6_BIT
+.. doxygendefine:: DMA_ISR_TCIF6_BIT
+.. doxygendefine:: DMA_ISR_GIF6_BIT
+.. doxygendefine:: DMA_ISR_TEIF5_BIT
+.. doxygendefine:: DMA_ISR_HTIF5_BIT
+.. doxygendefine:: DMA_ISR_TCIF5_BIT
+.. doxygendefine:: DMA_ISR_GIF5_BIT
+.. doxygendefine:: DMA_ISR_TEIF4_BIT
+.. doxygendefine:: DMA_ISR_HTIF4_BIT
+.. doxygendefine:: DMA_ISR_TCIF4_BIT
+.. doxygendefine:: DMA_ISR_GIF4_BIT
+.. doxygendefine:: DMA_ISR_TEIF3_BIT
+.. doxygendefine:: DMA_ISR_HTIF3_BIT
+.. doxygendefine:: DMA_ISR_TCIF3_BIT
+.. doxygendefine:: DMA_ISR_GIF3_BIT
+.. doxygendefine:: DMA_ISR_TEIF2_BIT
+.. doxygendefine:: DMA_ISR_HTIF2_BIT
+.. doxygendefine:: DMA_ISR_TCIF2_BIT
+.. doxygendefine:: DMA_ISR_GIF2_BIT
+.. doxygendefine:: DMA_ISR_TEIF1_BIT
+.. doxygendefine:: DMA_ISR_HTIF1_BIT
+.. doxygendefine:: DMA_ISR_TCIF1_BIT
+.. doxygendefine:: DMA_ISR_GIF1_BIT
+
+.. doxygendefine:: DMA_ISR_TEIF7
+.. doxygendefine:: DMA_ISR_HTIF7
+.. doxygendefine:: DMA_ISR_TCIF7
+.. doxygendefine:: DMA_ISR_GIF7
+.. doxygendefine:: DMA_ISR_TEIF6
+.. doxygendefine:: DMA_ISR_HTIF6
+.. doxygendefine:: DMA_ISR_TCIF6
+.. doxygendefine:: DMA_ISR_GIF6
+.. doxygendefine:: DMA_ISR_TEIF5
+.. doxygendefine:: DMA_ISR_HTIF5
+.. doxygendefine:: DMA_ISR_TCIF5
+.. doxygendefine:: DMA_ISR_GIF5
+.. doxygendefine:: DMA_ISR_TEIF4
+.. doxygendefine:: DMA_ISR_HTIF4
+.. doxygendefine:: DMA_ISR_TCIF4
+.. doxygendefine:: DMA_ISR_GIF4
+.. doxygendefine:: DMA_ISR_TEIF3
+.. doxygendefine:: DMA_ISR_HTIF3
+.. doxygendefine:: DMA_ISR_TCIF3
+.. doxygendefine:: DMA_ISR_GIF3
+.. doxygendefine:: DMA_ISR_TEIF2
+.. doxygendefine:: DMA_ISR_HTIF2
+.. doxygendefine:: DMA_ISR_TCIF2
+.. doxygendefine:: DMA_ISR_GIF2
+.. doxygendefine:: DMA_ISR_TEIF1
+.. doxygendefine:: DMA_ISR_HTIF1
+.. doxygendefine:: DMA_ISR_TCIF1
+.. doxygendefine:: DMA_ISR_GIF1
+
+Interrupt flag clear register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_IFCR_CTEIF7_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF7_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF7_BIT
+.. doxygendefine:: DMA_IFCR_CGIF7_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF6_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF6_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF6_BIT
+.. doxygendefine:: DMA_IFCR_CGIF6_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF5_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF5_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF5_BIT
+.. doxygendefine:: DMA_IFCR_CGIF5_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF4_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF4_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF4_BIT
+.. doxygendefine:: DMA_IFCR_CGIF4_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF3_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF3_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF3_BIT
+.. doxygendefine:: DMA_IFCR_CGIF3_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF2_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF2_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF2_BIT
+.. doxygendefine:: DMA_IFCR_CGIF2_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF1_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF1_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF1_BIT
+.. doxygendefine:: DMA_IFCR_CGIF1_BIT
+
+.. doxygendefine:: DMA_IFCR_CTEIF7
+.. doxygendefine:: DMA_IFCR_CHTIF7
+.. doxygendefine:: DMA_IFCR_CTCIF7
+.. doxygendefine:: DMA_IFCR_CGIF7
+.. doxygendefine:: DMA_IFCR_CTEIF6
+.. doxygendefine:: DMA_IFCR_CHTIF6
+.. doxygendefine:: DMA_IFCR_CTCIF6
+.. doxygendefine:: DMA_IFCR_CGIF6
+.. doxygendefine:: DMA_IFCR_CTEIF5
+.. doxygendefine:: DMA_IFCR_CHTIF5
+.. doxygendefine:: DMA_IFCR_CTCIF5
+.. doxygendefine:: DMA_IFCR_CGIF5
+.. doxygendefine:: DMA_IFCR_CTEIF4
+.. doxygendefine:: DMA_IFCR_CHTIF4
+.. doxygendefine:: DMA_IFCR_CTCIF4
+.. doxygendefine:: DMA_IFCR_CGIF4
+.. doxygendefine:: DMA_IFCR_CTEIF3
+.. doxygendefine:: DMA_IFCR_CHTIF3
+.. doxygendefine:: DMA_IFCR_CTCIF3
+.. doxygendefine:: DMA_IFCR_CGIF3
+.. doxygendefine:: DMA_IFCR_CTEIF2
+.. doxygendefine:: DMA_IFCR_CHTIF2
+.. doxygendefine:: DMA_IFCR_CTCIF2
+.. doxygendefine:: DMA_IFCR_CGIF2
+.. doxygendefine:: DMA_IFCR_CTEIF1
+.. doxygendefine:: DMA_IFCR_CHTIF1
+.. doxygendefine:: DMA_IFCR_CTCIF1
+.. doxygendefine:: DMA_IFCR_CGIF1
+
+Channel configuration register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_CCR_MEM2MEM_BIT
+.. doxygendefine:: DMA_CCR_MINC_BIT
+.. doxygendefine:: DMA_CCR_PINC_BIT
+.. doxygendefine:: DMA_CCR_CIRC_BIT
+.. doxygendefine:: DMA_CCR_DIR_BIT
+.. doxygendefine:: DMA_CCR_TEIE_BIT
+.. doxygendefine:: DMA_CCR_HTIE_BIT
+.. doxygendefine:: DMA_CCR_TCIE_BIT
+.. doxygendefine:: DMA_CCR_EN_BIT
+
+.. doxygendefine:: DMA_CCR_MEM2MEM
+.. doxygendefine:: DMA_CCR_PL
+.. doxygendefine:: DMA_CCR_PL_LOW
+.. doxygendefine:: DMA_CCR_PL_MEDIUM
+.. doxygendefine:: DMA_CCR_PL_HIGH
+.. doxygendefine:: DMA_CCR_PL_VERY_HIGH
+.. doxygendefine:: DMA_CCR_MSIZE
+.. doxygendefine:: DMA_CCR_MSIZE_8BITS
+.. doxygendefine:: DMA_CCR_MSIZE_16BITS
+.. doxygendefine:: DMA_CCR_MSIZE_32BITS
+.. doxygendefine:: DMA_CCR_PSIZE
+.. doxygendefine:: DMA_CCR_PSIZE_8BITS
+.. doxygendefine:: DMA_CCR_PSIZE_16BITS
+.. doxygendefine:: DMA_CCR_PSIZE_32BITS
+.. doxygendefine:: DMA_CCR_MINC
+.. doxygendefine:: DMA_CCR_PINC
+.. doxygendefine:: DMA_CCR_CIRC
+.. doxygendefine:: DMA_CCR_DIR
+.. doxygendefine:: DMA_CCR_TEIE
+.. doxygendefine:: DMA_CCR_HTIE
+.. doxygendefine:: DMA_CCR_TCIE
+.. doxygendefine:: DMA_CCR_EN
diff --git a/docs/source/libmaple/api/exti.rst b/docs/source/libmaple/api/exti.rst
new file mode 100644
index 0000000..1038fbf
--- /dev/null
+++ b/docs/source/libmaple/api/exti.rst
@@ -0,0 +1,37 @@
+.. highlight:: c
+.. _libmaple-exti:
+
+``exti.h``
+==========
+
+:ref:`External interrupt <external-interrupts>` support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: exti_reg_map
+.. doxygenenum:: exti_trigger_mode
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. doxygenfunction:: exti_attach_interrupt
+.. doxygenfunction:: exti_detach_interrupt
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: EXTI_BASE
+
+Register Bit Definitions
+------------------------
+
+None at this time.
diff --git a/docs/source/libmaple/api/flash.rst b/docs/source/libmaple/api/flash.rst
new file mode 100644
index 0000000..52ff4d2
--- /dev/null
+++ b/docs/source/libmaple/api/flash.rst
@@ -0,0 +1,249 @@
+.. highlight:: c
+.. _libmaple-flash:
+
+``<libmaple/flash.h>``
+======================
+
+Flash memory support.
+
+The built-in Flash on different STM32 MCUs varies in terms of its
+eraseable page/sector size and read/write protections. There isn't
+currently much support for dealing with this. This header is mostly
+useful for its functions that control Flash features which affect
+system performance, like wait states and prefetch buffers.
+
+.. contents:: Contents
+ :local:
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+The following functions can be used to portably manipulate Flash memory.
+
+.. doxygenfunction:: flash_set_latency
+.. doxygenfunction:: flash_enable_features
+.. doxygenfunction:: flash_enable_prefetch
+
+Register Maps
+-------------
+
+Register maps vary by target. The base pointer is always ``FLASH_BASE``.
+
+Base Pointer
+~~~~~~~~~~~~
+
+.. doxygendefine:: FLASH_BASE
+
+STM32F1 targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f1::flash_reg_map
+
+STM32F2 targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f2::flash_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code. Available register bit definitions
+vary by target.
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+::
+
+ /* Access control register */
+
+ #define FLASH_ACR_PRFTBS_BIT 5
+ #define FLASH_ACR_PRFTBE_BIT 4
+ #define FLASH_ACR_HLFCYA_BIT 3
+
+ #define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT)
+ #define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT)
+ #define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT)
+ #define FLASH_ACR_LATENCY 0x7
+
+ /* Status register */
+
+ #define FLASH_SR_EOP_BIT 5
+ #define FLASH_SR_WRPRTERR_BIT 4
+ #define FLASH_SR_PGERR_BIT 2
+ #define FLASH_SR_BSY_BIT 0
+
+ #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
+ #define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT)
+ #define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT)
+ #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
+
+ /* Control register */
+
+ #define FLASH_CR_EOPIE_BIT 12
+ #define FLASH_CR_ERRIE_BIT 10
+ #define FLASH_CR_OPTWRE_BIT 9
+ #define FLASH_CR_LOCK_BIT 7
+ #define FLASH_CR_STRT_BIT 6
+ #define FLASH_CR_OPTER_BIT 5
+ #define FLASH_CR_OPTPG_BIT 4
+ #define FLASH_CR_MER_BIT 2
+ #define FLASH_CR_PER_BIT 1
+ #define FLASH_CR_PG_BIT 0
+
+ #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
+ #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
+ #define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT)
+ #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
+ #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
+ #define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT)
+ #define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT)
+ #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
+ #define FLASH_CR_PER (1U << FLASH_CR_PER_BIT)
+ #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
+
+ /* Option byte register */
+
+ #define FLASH_OBR_nRST_STDBY_BIT 4
+ #define FLASH_OBR_nRST_STOP_BIT 3
+ #define FLASH_OBR_WDG_SW_BIT 2
+ #define FLASH_OBR_RDPRT_BIT 1
+ #define FLASH_OBR_OPTERR_BIT 0
+
+ #define FLASH_OBR_DATA1 (0xFF << 18)
+ #define FLASH_OBR_DATA0 (0xFF << 10)
+ #define FLASH_OBR_USER 0x3FF
+ #define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT)
+ #define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT)
+ #define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT)
+ #define FLASH_OBR_RDPRT (1U << FLASH_OBR_RDPRT_BIT)
+ #define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT)
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+::
+
+ /* Access control register */
+
+ #define FLASH_ACR_DCRST_BIT 12
+ #define FLASH_ACR_ICRST_BIT 11
+ #define FLASH_ACR_DCEN_BIT 10
+ #define FLASH_ACR_ICEN_BIT 9
+ #define FLASH_ACR_PRFTEN_BIT 8
+
+ #define FLASH_ACR_DCRST (1U << FLASH_ACR_DCRST_BIT)
+ #define FLASH_ACR_ICRST (1U << FLASH_ACR_ICRST_BIT)
+ #define FLASH_ACR_DCEN (1U << FLASH_ACR_DCEN_BIT)
+ #define FLASH_ACR_ICEN (1U << FLASH_ACR_ICEN_BIT)
+ #define FLASH_ACR_PRFTEN (1U << FLASH_ACR_PRFTEN_BIT)
+ #define FLASH_ACR_LATENCY 0x7
+ #define FLASH_ACR_LATENCY_0WS 0x0
+ #define FLASH_ACR_LATENCY_1WS 0x1
+ #define FLASH_ACR_LATENCY_2WS 0x2
+ #define FLASH_ACR_LATENCY_3WS 0x3
+ #define FLASH_ACR_LATENCY_4WS 0x4
+ #define FLASH_ACR_LATENCY_5WS 0x5
+ #define FLASH_ACR_LATENCY_6WS 0x6
+ #define FLASH_ACR_LATENCY_7WS 0x7
+
+ /* Key register */
+
+ #define FLASH_KEYR_KEY1 0x45670123
+ #define FLASH_KEYR_KEY2 0xCDEF89AB
+
+ /* Option key register */
+
+ #define FLASH_OPTKEYR_OPTKEY1 0x08192A3B
+ #define FLASH_OPTKEYR_OPTKEY2 0x4C5D6E7F
+
+ /* Status register */
+
+ #define FLASH_SR_BSY_BIT 16
+ #define FLASH_SR_PGSERR_BIT 7
+ #define FLASH_SR_PGPERR_BIT 6
+ #define FLASH_SR_PGAERR_BIT 5
+ #define FLASH_SR_WRPERR_BIT 4
+ #define FLASH_SR_OPERR_BIT 1
+ #define FLASH_SR_EOP_BIT 0
+
+ #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
+ #define FLASH_SR_PGSERR (1U << FLASH_SR_PGSERR_BIT)
+ #define FLASH_SR_PGPERR (1U << FLASH_SR_PGPERR_BIT)
+ #define FLASH_SR_PGAERR (1U << FLASH_SR_PGAERR_BIT)
+ #define FLASH_SR_WRPERR (1U << FLASH_SR_WRPERR_BIT)
+ #define FLASH_SR_OPERR (1U << FLASH_SR_OPERR_BIT)
+ #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
+
+ /* Control register */
+
+ #define FLASH_CR_LOCK_BIT 31
+ #define FLASH_CR_ERRIE_BIT 25
+ #define FLASH_CR_EOPIE_BIT 24
+ #define FLASH_CR_STRT_BIT 16
+ #define FLASH_CR_MER_BIT 2
+ #define FLASH_CR_SER_BIT 1
+ #define FLASH_CR_PG_BIT 0
+
+ #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
+ #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
+ #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
+ #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
+
+ #define FLASH_CR_PSIZE (0x3 << 8)
+ #define FLASH_CR_PSIZE_MUL8 (0x0 << 8)
+ #define FLASH_CR_PSIZE_MUL16 (0x1 << 8)
+ #define FLASH_CR_PSIZE_MUL32 (0x2 << 8)
+ #define FLASH_CR_PSIZE_MUL64 (0x3 << 8)
+
+ #define FLASH_CR_SNB (0xF << 3)
+ #define FLASH_CR_SNB_0 (0x0 << 3)
+ #define FLASH_CR_SNB_1 (0x1 << 3)
+ #define FLASH_CR_SNB_2 (0x2 << 3)
+ #define FLASH_CR_SNB_3 (0x3 << 3)
+ #define FLASH_CR_SNB_4 (0x4 << 3)
+ #define FLASH_CR_SNB_5 (0x5 << 3)
+ #define FLASH_CR_SNB_6 (0x6 << 3)
+ #define FLASH_CR_SNB_7 (0x7 << 3)
+ #define FLASH_CR_SNB_8 (0x8 << 3)
+ #define FLASH_CR_SNB_9 (0x9 << 3)
+ #define FLASH_CR_SNB_10 (0xA << 3)
+ #define FLASH_CR_SNB_11 (0xB << 3)
+
+ #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
+ #define FLASH_CR_SER (1U << FLASH_CR_SER_BIT)
+ #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
+
+ /* Option control register */
+
+ #define FLASH_OPTCR_NRST_STDBY_BIT 7
+ #define FLASH_OPTCR_NRST_STOP_BIT 6
+ #define FLASH_OPTCR_WDG_SW_BIT 5
+ #define FLASH_OPTCR_OPTSTRT_BIT 1
+ #define FLASH_OPTCR_OPTLOCK_BIT 0
+
+ #define FLASH_OPTCR_NWRP (0x3FF << 16)
+
+ /* Excluded: The many level 1 values */
+ #define FLASH_OPTCR_RDP (0xFF << 8)
+ #define FLASH_OPTCR_RDP_LEVEL0 (0xAA << 8)
+ #define FLASH_OPTCR_RDP_LEVEL2 (0xCC << 8)
+
+ #define FLASH_OPTCR_USER (0x7 << 5)
+ #define FLASH_OPTCR_nRST_STDBY (1U << FLASH_OPTCR_nRST_STDBY_BIT)
+ #define FLASH_OPTCR_nRST_STOP (1U << FLASH_OPTCR_nRST_STOP_BIT)
+ #define FLASH_OPTCR_WDG_SW (1U << FLASH_OPTCR_WDG_SW_BIT)
+
+ #define FLASH_OPTCR_BOR_LEV (0x3 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL3 (0x0 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL2 (0x1 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL1 (0x2 << 2)
+ #define FLASH_OPTCR_BOR_OFF (0x3 << 2)
+
+ #define FLASH_OPTCR_OPTSTRT (1U << FLASH_OPTCR_OPTSTRT_BIT)
+ #define FLASH_OPTCR_OPTLOCK (1U << FLASH_OPTCR_OPTLOCK_BIT)
diff --git a/docs/source/libmaple/api/fsmc.rst b/docs/source/libmaple/api/fsmc.rst
new file mode 100644
index 0000000..e2bf87a
--- /dev/null
+++ b/docs/source/libmaple/api/fsmc.rst
@@ -0,0 +1,235 @@
+.. highlight:: c
+.. _libmaple-fsmc:
+
+``<libmaple/fsmc.h>``
+=====================
+
+Flexible Static Memory Controller (FSMC) support. The FSMC peripheral
+is only available on some targets. Including this header on a target
+without an FSMC will cause a compilation error. Check your target's
+documentation to determine if it's available. You can also use
+:ref:`STM32_HAVE_FSMC <libmaple-stm32-STM32_HAVE_FSMC>` from
+``<libmaple/stm32.h>`` to determine whether your target has an FSMC at
+build time.
+
+All functionality documented here is portable.
+
+.. contents:: Contents
+ :local:
+
+Usage Note
+----------
+
+FSMC support is fairly limited at this time. Current Leaflabs boards
+only use the FSMC to interface with external SRAM chips, so that's
+what there's the most support for (:ref:`patches welcome!
+<libmaple-contributing>`). Even for use with SRAM, you will still need
+to program some registers directly.
+
+To use the FSMC with an SRAM chip, first call
+:ref:`fsmc_sram_init_gpios() <libmaple-fsmc-fsmc_sram_init_gpios>` to
+configure its data, address, and control lines. Then, turn on the
+FSMC clock (by calling :ref:`rcc_clk_enable(RCC_FSMC)
+<libmaple-rcc-rcc_clk_enable>`). You can then configure the relevant
+:ref:`fsmc_nor_psram_reg_map <libmaple-fsmc-fsmc_nor_psram_reg_map>`
+``BCR`` register yourself for the SRAM chip you are using.
+
+You can additionally use :ref:`fsmc_nor_psram_set_datast()
+<libmaple-fsmc-fsmc_nor_psram_set_datast>` and
+:ref:`fsmc_nor_psram_set_datast() <libmaple-fsmc-fsmc_nor_psram_set_datast>`
+to control read/write timing.
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. _libmaple-fsmc-fsmc_sram_init_gpios:
+.. doxygenfunction:: fsmc_sram_init_gpios
+.. _libmaple-fsmc-fsmc_nor_psram_set_datast:
+.. doxygenfunction:: fsmc_nor_psram_set_datast
+.. _libmaple-fsmc-fsmc_nor_psram_set_addset:
+.. doxygenfunction:: fsmc_nor_psram_set_addset
+
+Register Maps
+-------------
+
+The general purpose register map type is ``fsmc_reg_map``; its base
+pointer is ``FSMC_BASE``. The ``fsmc_nor_psram_reg_map`` type is for
+use configuring the registers for an individual NOR/PSRAM region
+(``FSMC_BCRx``, ``FSMC_BTRx``, and ``FSMC_BWTRx``); the relevant base
+pointers are ``FSMC_NOR_PSRAM_REGION1`` through
+``FSMC_NOR_PSRAM_REGION4``.
+
+.. doxygendefine:: FSMC_BASE
+
+.. doxygendefine:: FSMC_NOR_PSRAM1_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM2_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM3_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM4_BASE
+
+.. doxygenstruct:: fsmc_reg_map
+.. _libmaple-fsmc-fsmc_nor_psram_reg_map:
+.. doxygenstruct:: fsmc_nor_psram_reg_map
+
+Memory Bank Boundary Addresses
+------------------------------
+
+Reading and writing data on an external memory chip using FSMC is done
+by reading and writing from addresses in special memory-mapped
+sections of the address space called *memory banks*.
+
+This is convenient, since it implies that the usual load and store
+instructions used for I/O with the internal SRAM are also used to
+perform bus transactions with the external memory chip. (Which means
+you can use ``memcpy()`` etc. on external memory.)
+
+Pointers to the memory banks' base addresses are given by the
+following macros.
+
+.. doxygendefine:: FSMC_BANK1
+.. doxygendefine:: FSMC_BANK2
+.. doxygendefine:: FSMC_BANK3
+.. doxygendefine:: FSMC_BANK4
+
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION1
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION2
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION3
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION4
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* NOR/PSRAM chip-select control registers */
+
+ #define FSMC_BCR_CBURSTRW_BIT 19
+ #define FSMC_BCR_ASYNCWAIT_BIT 15
+ #define FSMC_BCR_EXTMOD_BIT 14
+ #define FSMC_BCR_WAITEN_BIT 13
+ #define FSMC_BCR_WREN_BIT 12
+ #define FSMC_BCR_WAITCFG_BIT 11
+ #define FSMC_BCR_WRAPMOD_BIT 10
+ #define FSMC_BCR_WAITPOL_BIT 9
+ #define FSMC_BCR_BURSTEN_BIT 8
+ #define FSMC_BCR_FACCEN_BIT 6
+ #define FSMC_BCR_MUXEN_BIT 1
+ #define FSMC_BCR_MBKEN_BIT 0
+
+ #define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT)
+ #define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT)
+ #define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT)
+ #define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT)
+ #define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT)
+ #define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT)
+ #define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT)
+ #define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT)
+ #define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT)
+ #define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT)
+ #define FSMC_BCR_MWID (0x3 << 4)
+ #define FSMC_BCR_MWID_8BITS (0x0 << 4)
+ #define FSMC_BCR_MWID_16BITS (0x1 << 4)
+ #define FSMC_BCR_MTYP (0x3 << 2)
+ #define FSMC_BCR_MTYP_SRAM (0x0 << 2)
+ #define FSMC_BCR_MTYP_PSRAM (0x1 << 2)
+ #define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2)
+ #define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT)
+ #define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT)
+
+ /* SRAM/NOR-Flash chip-select timing registers */
+
+ #define FSMC_BTR_ACCMOD (0x3 << 28)
+ #define FSMC_BTR_ACCMOD_A (0x0 << 28)
+ #define FSMC_BTR_ACCMOD_B (0x1 << 28)
+ #define FSMC_BTR_ACCMOD_C (0x2 << 28)
+ #define FSMC_BTR_ACCMOD_D (0x3 << 28)
+ #define FSMC_BTR_DATLAT (0xF << 24)
+ #define FSMC_BTR_CLKDIV (0xF << 20)
+ #define FSMC_BTR_BUSTURN (0xF << 16)
+ #define FSMC_BTR_DATAST (0xFF << 8)
+ #define FSMC_BTR_ADDHLD (0xF << 4)
+ #define FSMC_BTR_ADDSET 0xF
+
+ /* SRAM/NOR-Flash write timing registers */
+
+ #define FSMC_BWTR_ACCMOD (0x3 << 28)
+ #define FSMC_BWTR_ACCMOD_A (0x0 << 28)
+ #define FSMC_BWTR_ACCMOD_B (0x1 << 28)
+ #define FSMC_BWTR_ACCMOD_C (0x2 << 28)
+ #define FSMC_BWTR_ACCMOD_D (0x3 << 28)
+ #define FSMC_BWTR_DATLAT (0xF << 24)
+ #define FSMC_BWTR_CLKDIV (0xF << 20)
+ #define FSMC_BWTR_DATAST (0xFF << 8)
+ #define FSMC_BWTR_ADDHLD (0xF << 4)
+ #define FSMC_BWTR_ADDSET 0xF
+
+ /* NAND Flash/PC Card controller registers */
+
+ #define FSMC_PCR_ECCEN_BIT 6
+ #define FSMC_PCR_PTYP_BIT 3
+ #define FSMC_PCR_PBKEN_BIT 2
+ #define FSMC_PCR_PWAITEN_BIT 1
+
+ #define FSMC_PCR_ECCPS (0x7 << 17)
+ #define FSMC_PCR_ECCPS_256B (0x0 << 17)
+ #define FSMC_PCR_ECCPS_512B (0x1 << 17)
+ #define FSMC_PCR_ECCPS_1024B (0x2 << 17)
+ #define FSMC_PCR_ECCPS_2048B (0x3 << 17)
+ #define FSMC_PCR_ECCPS_4096B (0x4 << 17)
+ #define FSMC_PCR_ECCPS_8192B (0x5 << 17)
+ #define FSMC_PCR_TAR (0xF << 13)
+ #define FSMC_PCR_TCLR (0xF << 9)
+ #define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT)
+ #define FSMC_PCR_PWID (0x3 << 4)
+ #define FSMC_PCR_PWID_8BITS (0x0 << 4)
+ #define FSMC_PCR_PWID_16BITS (0x1 << 4)
+ #define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT)
+ #define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT)
+
+ /* FIFO status and interrupt registers */
+
+ #define FSMC_SR_FEMPT_BIT 6
+ #define FSMC_SR_IFEN_BIT 5
+ #define FSMC_SR_ILEN_BIT 4
+ #define FSMC_SR_IREN_BIT 3
+ #define FSMC_SR_IFS_BIT 2
+ #define FSMC_SR_ILS_BIT 1
+ #define FSMC_SR_IRS_BIT 0
+
+ #define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT)
+ #define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT)
+ #define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT)
+ #define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT)
+ #define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT)
+ #define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT)
+ #define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT)
+
+ /* Common memory space timing registers */
+
+ #define FSMC_PMEM_MEMHIZ (0xFF << 24)
+ #define FSMC_PMEM_MEMHOLD (0xFF << 16)
+ #define FSMC_PMEM_MEMWAIT (0xFF << 8)
+ #define FSMC_PMEM_MEMSET 0xFF
+
+ /* Attribute memory space timing registers */
+
+ #define FSMC_PATT_ATTHIZ (0xFF << 24)
+ #define FSMC_PATT_ATTHOLD (0xFF << 16)
+ #define FSMC_PATT_ATTWAIT (0xFF << 8)
+ #define FSMC_PATT_ATTSET 0xFF
+
+ /* I/O space timing register 4 */
+
+ #define FSMC_PIO_IOHIZ (0xFF << 24)
+ #define FSMC_PIO_IOHOLD (0xFF << 16)
+ #define FSMC_PIO_IOWAIT (0xFF << 8)
+ #define FSMC_PIO_IOSET 0xF
diff --git a/docs/source/libmaple/api/gpio.rst b/docs/source/libmaple/api/gpio.rst
new file mode 100644
index 0000000..faf0ad2
--- /dev/null
+++ b/docs/source/libmaple/api/gpio.rst
@@ -0,0 +1,243 @@
+.. highlight:: c
+.. _libmaple-gpio:
+
+``gpio.h``
+==========
+
+General Purpose Input/Output (GPIO) port and Alternate Function
+Input/Output (AFIO) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: gpio_reg_map
+.. doxygenstruct:: gpio_dev
+.. doxygenenum:: gpio_pin_mode
+
+.. doxygenstruct:: afio_reg_map
+.. doxygenenum:: afio_exti_port
+.. doxygenenum:: afio_exti_num
+.. doxygenenum:: afio_remap_peripheral
+.. doxygenenum:: afio_debug_cfg
+
+Devices
+-------
+
+.. doxygenvariable:: GPIOA
+.. doxygenvariable:: GPIOB
+.. doxygenvariable:: GPIOC
+.. doxygenvariable:: GPIOD
+.. doxygenvariable:: GPIOE
+.. doxygenvariable:: GPIOF
+.. doxygenvariable:: GPIOG
+
+Functions
+---------
+
+.. doxygenfunction:: gpio_init
+.. doxygenfunction:: gpio_init_all
+.. doxygenfunction:: gpio_set_mode
+.. doxygenfunction:: gpio_exti_port
+.. doxygenfunction:: gpio_write_bit
+.. doxygenfunction:: gpio_read_bit
+.. doxygenfunction:: gpio_toggle_bit
+
+.. doxygenfunction:: afio_init
+.. doxygenfunction:: afio_exti_select
+
+.. _gpio-h-afio-remap:
+.. doxygenfunction:: afio_remap
+.. doxygenfunction:: afio_cfg_debug_ports
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: GPIOA_BASE
+.. doxygendefine:: GPIOB_BASE
+.. doxygendefine:: GPIOC_BASE
+.. doxygendefine:: GPIOD_BASE
+.. doxygendefine:: GPIOE_BASE
+.. doxygendefine:: GPIOF_BASE
+.. doxygendefine:: GPIOG_BASE
+
+.. doxygendefine:: AFIO_BASE
+
+Register Bit Definitions
+------------------------
+
+GPIO Control Registers
+~~~~~~~~~~~~~~~~~~~~~~
+
+These values apply to both the low and high configuration registers
+(ST RM0008: GPIOx_CRL and GPIOx_CRH). You can shift them right by the
+appropriate number of bits for the GPIO port bit you're interested in
+to obtain a bit mask.
+
+For example, to mask out just the value of GPIOA_CRH_CNF12, note that
+GPIO port bit 12's configuration starts at bit 18 in the corresponding
+CRH. Thus, an appropriate mask is ``GPIOA_BASE->CRH & (GPIO_CR_CNF <<
+18)``.
+
+.. doxygendefine:: GPIO_CR_CNF_INPUT_ANALOG
+.. doxygendefine:: GPIO_CR_CNF_INPUT_FLOATING
+.. doxygendefine:: GPIO_CR_CNF_INPUT_PU_PD
+.. doxygendefine:: GPIO_CR_CNF_OUTPUT_PP
+.. doxygendefine:: GPIO_CR_CNF_OUTPUT_OD
+.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_PP
+.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_OD
+.. doxygendefine:: GPIO_CR_MODE_INPUT
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_10MHZ
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_2MHZ
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_50MHZ
+
+Event Control Register
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EVCR_EVOE
+.. doxygendefine:: AFIO_EVCR_PORT_PA
+.. doxygendefine:: AFIO_EVCR_PORT_PB
+.. doxygendefine:: AFIO_EVCR_PORT_PC
+.. doxygendefine:: AFIO_EVCR_PORT_PD
+.. doxygendefine:: AFIO_EVCR_PORT_PE
+.. doxygendefine:: AFIO_EVCR_PIN_0
+.. doxygendefine:: AFIO_EVCR_PIN_1
+.. doxygendefine:: AFIO_EVCR_PIN_2
+.. doxygendefine:: AFIO_EVCR_PIN_3
+.. doxygendefine:: AFIO_EVCR_PIN_4
+.. doxygendefine:: AFIO_EVCR_PIN_5
+.. doxygendefine:: AFIO_EVCR_PIN_6
+.. doxygendefine:: AFIO_EVCR_PIN_7
+.. doxygendefine:: AFIO_EVCR_PIN_8
+.. doxygendefine:: AFIO_EVCR_PIN_9
+.. doxygendefine:: AFIO_EVCR_PIN_10
+.. doxygendefine:: AFIO_EVCR_PIN_11
+.. doxygendefine:: AFIO_EVCR_PIN_12
+.. doxygendefine:: AFIO_EVCR_PIN_13
+.. doxygendefine:: AFIO_EVCR_PIN_14
+.. doxygendefine:: AFIO_EVCR_PIN_15
+
+AF Remap and Debug I/O Configuration Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_SW
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW
+.. doxygendefine:: AFIO_MAPR_ADC2_ETRGREG_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC2_ETRGINJ_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC1_ETRGREG_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC1_ETRGINJ_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM5CH4_IREMAP
+.. doxygendefine:: AFIO_MAPR_PD01_REMAP
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PB8_PB9
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PD0_PD1
+.. doxygendefine:: AFIO_MAPR_TIM4_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_USART2_REMAP
+.. doxygendefine:: AFIO_MAPR_USART1_REMAP
+.. doxygendefine:: AFIO_MAPR_I2C1_REMAP
+.. doxygendefine:: AFIO_MAPR_SPI1_REMAP
+
+External Interrupt Configuration Register 1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EXTICR1_EXTI3
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI2
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI1
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI0
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PG
+
+External Interrupt Configuration Register 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EXTICR2_EXTI7
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI6
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI5
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI4
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PG
+
+AF Remap and Debug I/O Configuration Register 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_MAPR2_FSMC_NADV
+.. doxygendefine:: AFIO_MAPR2_TIM14_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM13_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM11_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM10_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM9_REMAP
diff --git a/docs/source/libmaple/api/i2c.rst b/docs/source/libmaple/api/i2c.rst
new file mode 100644
index 0000000..ff380cc
--- /dev/null
+++ b/docs/source/libmaple/api/i2c.rst
@@ -0,0 +1,124 @@
+.. highlight:: c
+.. _libmaple-i2c:
+
+``i2c.h``
+=========
+
+Inter-Integrated Circuit (|i2c|) peripheral support.
+
+.. contents:: Contents
+ :local:
+
+Important Note
+--------------
+
+There are some important known problems with the built-in I2C
+peripherals. For more information, see STM32F10xx8 and STM32F10xxB
+Errata sheet (ST Doc ID 14574 Rev 8), Section 2.11.1, 2.11.2. An
+important consequence of these problems is that the |i2c| interrupt
+must not be preempted. Consequently, (by default) Wirish uses an
+|i2c| interrupt priority which is the highest in the system (priority
+level 0). Other interrupt priorities are set lower.
+
+Types
+-----
+
+.. doxygenstruct:: i2c_reg_map
+.. doxygenenum:: i2c_state
+.. doxygenstruct:: i2c_msg
+.. doxygenstruct:: i2c_dev
+
+Devices
+-------
+
+.. doxygenvariable:: I2C1
+.. doxygenvariable:: I2C2
+
+Functions
+---------
+
+.. doxygenfunction:: i2c_init
+.. doxygenfunction:: i2c_master_enable
+.. doxygenfunction:: i2c_master_xfer
+.. doxygenfunction:: i2c_bus_reset
+.. doxygenfunction:: i2c_disable
+.. doxygenfunction:: i2c_peripheral_enable
+.. doxygenfunction:: i2c_peripheral_disable
+.. doxygenfunction:: i2c_write
+.. doxygenfunction:: i2c_set_input_clk
+.. doxygenfunction:: i2c_set_clk_control
+.. doxygenfunction:: i2c_set_trise
+.. doxygenfunction:: i2c_start_condition
+.. doxygenfunction:: i2c_stop_condition
+.. doxygenfunction:: i2c_enable_irq
+.. doxygenfunction:: i2c_disable_irq
+.. doxygenfunction:: i2c_enable_ack
+.. doxygenfunction:: i2c_disable_ack
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: I2C1_BASE
+.. doxygendefine:: I2C2_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CR1_SWRST
+.. doxygendefine:: I2C_CR1_ALERT
+.. doxygendefine:: I2C_CR1_PEC
+.. doxygendefine:: I2C_CR1_POS
+.. doxygendefine:: I2C_CR1_ACK
+.. doxygendefine:: I2C_CR1_START
+.. doxygendefine:: I2C_CR1_STOP
+.. doxygendefine:: I2C_CR1_PE
+
+Control register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CR2_LAST
+.. doxygendefine:: I2C_CR2_DMAEN
+.. doxygendefine:: I2C_CR2_ITBUFEN
+.. doxygendefine:: I2C_CR2_ITEVTEN
+.. doxygendefine:: I2C_CR2_ITERREN
+.. doxygendefine:: I2C_CR2_FREQ
+
+Clock control register
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CCR_FS
+.. doxygendefine:: I2C_CCR_DUTY
+.. doxygendefine:: I2C_CCR_CCR
+
+Status register 1
+~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_SR1_SB
+.. doxygendefine:: I2C_SR1_ADDR
+.. doxygendefine:: I2C_SR1_BTF
+.. doxygendefine:: I2C_SR1_ADD10
+.. doxygendefine:: I2C_SR1_STOPF
+.. doxygendefine:: I2C_SR1_RXNE
+.. doxygendefine:: I2C_SR1_TXE
+.. doxygendefine:: I2C_SR1_BERR
+.. doxygendefine:: I2C_SR1_ARLO
+.. doxygendefine:: I2C_SR1_AF
+.. doxygendefine:: I2C_SR1_OVR
+.. doxygendefine:: I2C_SR1_PECERR
+.. doxygendefine:: I2C_SR1_TIMEOUT
+.. doxygendefine:: I2C_SR1_SMBALERT
+
+Status register 2
+~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_SR2_MSL
+.. doxygendefine:: I2C_SR2_BUSY
+.. doxygendefine:: I2C_SR2_TRA
+.. doxygendefine:: I2C_SR2_GENCALL
+.. doxygendefine:: I2C_SR2_SMBDEFAULT
+.. doxygendefine:: I2C_SR2_SMBHOST
+.. doxygendefine:: I2C_SR2_DUALF
+.. doxygendefine:: I2C_SR2_PEC
diff --git a/docs/source/libmaple/api/iwdg.rst b/docs/source/libmaple/api/iwdg.rst
new file mode 100644
index 0000000..65f9f7b
--- /dev/null
+++ b/docs/source/libmaple/api/iwdg.rst
@@ -0,0 +1,80 @@
+.. highlight:: c
+.. _libmaple-iwdg:
+
+``<libmaple/iwdg.h>``
+=====================
+
+Independent Watchdog (IWDG) support. The IWDG peripheral is common
+across supported targets, so everything documented here is portable.
+
+.. contents:: Contents
+ :local:
+
+Usage Note
+----------
+
+To use the independent watchdog, first call :ref:`iwdg_init()
+<libmaple-iwdg-iwdg_init>` with the appropriate prescaler and IWDG
+counter reload values for your application. Afterwards, you must
+periodically call :ref:`iwdg_feed() <libmaple-iwdg-iwdg_feed>` before
+the IWDG counter reaches zero to reset the counter to its reload
+value. If you do not, the chip will reset.
+
+Once started, the independent watchdog cannot be turned off.
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. _libmaple-iwdg-iwdg_init:
+.. doxygenfunction:: iwdg_init
+.. _libmaple-iwdg-iwdg_feed:
+.. doxygenfunction:: iwdg_feed
+
+Types
+-----
+
+.. doxygenenum:: iwdg_prescaler
+
+
+Register Maps
+-------------
+
+.. doxygendefine:: IWDG_BASE
+
+.. doxygenstruct:: iwdg_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* Key register */
+
+ #define IWDG_KR_UNLOCK 0x5555
+ #define IWDG_KR_FEED 0xAAAA
+ #define IWDG_KR_START 0xCCCC
+
+ /* Prescaler register */
+
+ #define IWDG_PR_DIV_4 0x0
+ #define IWDG_PR_DIV_8 0x1
+ #define IWDG_PR_DIV_16 0x2
+ #define IWDG_PR_DIV_32 0x3
+ #define IWDG_PR_DIV_64 0x4
+ #define IWDG_PR_DIV_128 0x5
+ #define IWDG_PR_DIV_256 0x6
+
+ /* Status register */
+
+ #define IWDG_SR_RVU_BIT 1
+ #define IWDG_SR_PVU_BIT 0
+
+ #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT)
+ #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT)
diff --git a/docs/source/libmaple/api/libmaple.rst b/docs/source/libmaple/api/libmaple.rst
new file mode 100644
index 0000000..7deb659
--- /dev/null
+++ b/docs/source/libmaple/api/libmaple.rst
@@ -0,0 +1,11 @@
+.. highlight:: c
+.. _libmaple-libmaple:
+
+``<libmaple/libmaple.h>``
+=========================
+
+Base include file for libmaple.
+
+This file includes :ref:`libmaple-libmaple_types`,
+:ref:`libmaple-stm32`, and :ref:`libmaple-util`. You shouldn't rely
+on it doing anything else, however.
diff --git a/docs/source/libmaple/api/libmaple_types.rst b/docs/source/libmaple/api/libmaple_types.rst
new file mode 100644
index 0000000..5ca446e
--- /dev/null
+++ b/docs/source/libmaple/api/libmaple_types.rst
@@ -0,0 +1,85 @@
+.. highlight:: c
+.. _libmaple-libmaple_types:
+
+``<libmaple/libmaple_types.h>``
+===============================
+
+Defines the base types and type-related macros used throughout the
+rest of libmaple.
+
+.. contents:: Contents
+ :local:
+
+Integral Types
+--------------
+
+.. doxygentypedef:: uint8
+.. doxygentypedef:: uint16
+.. doxygentypedef:: uint32
+.. doxygentypedef:: uint64
+.. doxygentypedef:: int8
+.. doxygentypedef:: int16
+.. doxygentypedef:: int32
+.. doxygentypedef:: int64
+
+Attributes and Type Qualifiers
+------------------------------
+
+In the case of macros for GCC's ``__attribute__``\ s, we have our own
+macros mostly to save typing, but also in hopes that they might be
+expressible using different compiler extensions, or to give them
+different interpretations when running e.g. Doxygen on libmaple.
+
+.. c:macro:: __always_inline
+
+ Macro for ``inline __attribute__((always_inline))``. This can be
+ used to defeat GCC's ``-Os`` when you Really Mean Inline.
+
+.. c:macro:: __attr_flash
+
+ Macro for a GCC ``__attribute__`` which (when using libmaple's
+ linker scripts) will cause the variable being marked to be stored
+ in Flash, rather than SRAM. It's useful for read-only variables
+ like look-up tables.
+
+.. c:macro:: __deprecated
+
+ Macro for ``__attribute__((deprecated))``. Its use causes GCC to
+ emit deprecation warnings when the deprecated functionality is
+ used. It's not used for everything that gets deprecated, so don't
+ rely on it to catch all uses of deprecated APIs.
+
+.. c:macro:: __packed
+
+ Macro for ``__attribute__((packed))``.
+
+.. c:macro:: __io
+
+ Macro for ``volatile`` which denotes that the variable whose type
+ is being qualified is IO-mapped. Its most common use is in the
+ individual members of each :ref:`register map
+ <libmaple-overview-regmaps>` struct.
+
+.. c:macro:: __weak
+
+ Macro for ``__attribute__((weak))``.
+
+.. c:macro:: __unused
+
+ Macro for ``__attribute__((unused))``. This can be used
+ (sparingly!) to silence unused function warnings when GCC is
+ mistaken.
+
+Miscellaneous
+-------------
+
+.. doxygentypedef:: voidFuncPtr
+
+.. c:macro:: offsetof(type, member)
+
+ If left undefined, this is defined to ``__builtin_ofsetof(type,
+ member)``.
+
+.. c:macro:: NULL
+
+ If left undefined, this is defined to ``0``.
diff --git a/docs/source/libmaple/api/nvic.rst b/docs/source/libmaple/api/nvic.rst
new file mode 100644
index 0000000..505e36e
--- /dev/null
+++ b/docs/source/libmaple/api/nvic.rst
@@ -0,0 +1,67 @@
+.. highlight:: c
+.. _libmaple-nvic:
+
+``<libmaple/nvic.h>``
+=====================
+
+Nested Vector Interrupt Controller (NVIC) support.
+
+The same API is used on all targets, but the available interrupts are
+target-dependent. To manage this, each target series defines an
+:ref:`nvic_irq_num <libmaple-nvic-nvic_irq_num>` enumerator for each
+available interrupt.
+
+.. contents:: Contents
+ :local:
+
+Devices
+-------
+
+None at this time.
+
+.. _libmaple-nvic-nvic_irq_num:
+
+``nvic_irq_num``
+----------------
+
+This target-dependent enum is used to identify an interrupt vector
+number. Interrupts which are common across series have the same token
+(though not necessarily the same value) for their ``nvic_irq_num``\ s.
+The available values on each supported target series are as follows.
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenenum:: stm32f1::nvic_irq_num
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenenum:: stm32f2::nvic_irq_num
+
+Functions
+---------
+
+.. doxygenfunction:: nvic_init
+.. doxygenfunction:: nvic_set_vector_table
+.. doxygenfunction:: nvic_irq_set_priority
+.. doxygenfunction:: nvic_globalirq_enable
+.. doxygenfunction:: nvic_globalirq_disable
+.. doxygenfunction:: nvic_irq_enable
+.. doxygenfunction:: nvic_irq_disable
+.. doxygenfunction:: nvic_irq_disable_all
+.. doxygenfunction:: nvic_sys_reset
+
+Register Maps
+-------------
+
+Since the NVIC is part of the ARM core, its registers and base pointer
+are common across all targes.
+
+.. doxygendefine:: NVIC_BASE
+.. doxygenstruct:: nvic_reg_map
+
+Register Bit Definitions
+------------------------
+
+None at this time.
diff --git a/docs/source/libmaple/api/pwr.rst b/docs/source/libmaple/api/pwr.rst
new file mode 100644
index 0000000..6a2cf22
--- /dev/null
+++ b/docs/source/libmaple/api/pwr.rst
@@ -0,0 +1,51 @@
+.. highlight:: c
+.. _libmaple-pwr:
+
+``pwr.h``
+=========
+
+Power control (PWR) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: pwr_reg_map
+
+Devices
+-------
+
+None.
+
+Functions
+---------
+
+.. doxygenfunction:: pwr_init
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: PWR_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register
+~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: PWR_CR_DBP
+.. doxygendefine:: PWR_CR_PVDE
+.. doxygendefine:: PWR_CR_CSBF
+.. doxygendefine:: PWR_CR_CWUF
+.. doxygendefine:: PWR_CR_PDDS
+.. doxygendefine:: PWR_CR_LPDS
+
+Control and status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: PWR_CSR_EWUP
+.. doxygendefine:: PWR_CSR_PVDO
+.. doxygendefine:: PWR_CSR_SBF
+.. doxygendefine:: PWR_CSR_WUF
diff --git a/docs/source/libmaple/api/rcc-reg-bits.txt b/docs/source/libmaple/api/rcc-reg-bits.txt
new file mode 100644
index 0000000..6b1133d
--- /dev/null
+++ b/docs/source/libmaple/api/rcc-reg-bits.txt
@@ -0,0 +1,1017 @@
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+Clock control register
+++++++++++++++++++++++
+
+::
+
+ #define RCC_CR_PLLRDY_BIT 25
+ #define RCC_CR_PLLON_BIT 24
+ #define RCC_CR_CSSON_BIT 19
+ #define RCC_CR_HSEBYP_BIT 18
+ #define RCC_CR_HSERDY_BIT 17
+ #define RCC_CR_HSEON_BIT 16
+ #define RCC_CR_HSIRDY_BIT 1
+ #define RCC_CR_HSION_BIT 0
+
+ #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
+ #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
+ #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
+ #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
+ #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
+ #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
+ #define RCC_CR_HSICAL (0xFF << 8)
+ #define RCC_CR_HSITRIM (0x1F << 3)
+ #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
+ #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
+
+Clock configuration register
+++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CFGR_USBPRE_BIT 22
+ #define RCC_CFGR_PLLXTPRE_BIT 17
+ #define RCC_CFGR_PLLSRC_BIT 16
+
+ #define RCC_CFGR_MCO (0x3 << 24)
+ #define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT)
+ #define RCC_CFGR_PLLMUL (0xF << 18)
+ #define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT)
+ #define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT)
+ #define RCC_CFGR_ADCPRE (0x3 << 14)
+ #define RCC_CFGR_PPRE2 (0x7 << 11)
+ #define RCC_CFGR_PPRE1 (0x7 << 8)
+ #define RCC_CFGR_HPRE (0xF << 4)
+ #define RCC_CFGR_SWS (0x3 << 2)
+ #define RCC_CFGR_SWS_PLL (0x2 << 2)
+ #define RCC_CFGR_SWS_HSE (0x1 << 2)
+ #define RCC_CFGR_SW 0x3
+ #define RCC_CFGR_SW_PLL 0x2
+ #define RCC_CFGR_SW_HSE 0x1
+
+Clock interrupt register
+++++++++++++++++++++++++
+
+::
+
+ #define RCC_CIR_CSSC_BIT 23
+ #define RCC_CIR_PLLRDYC_BIT 20
+ #define RCC_CIR_HSERDYC_BIT 19
+ #define RCC_CIR_HSIRDYC_BIT 18
+ #define RCC_CIR_LSERDYC_BIT 17
+ #define RCC_CIR_LSIRDYC_BIT 16
+ #define RCC_CIR_PLLRDYIE_BIT 12
+ #define RCC_CIR_HSERDYIE_BIT 11
+ #define RCC_CIR_HSIRDYIE_BIT 10
+ #define RCC_CIR_LSERDYIE_BIT 9
+ #define RCC_CIR_LSIRDYIE_BIT 8
+ #define RCC_CIR_CSSF_BIT 7
+ #define RCC_CIR_PLLRDYF_BIT 4
+ #define RCC_CIR_HSERDYF_BIT 3
+ #define RCC_CIR_HSIRDYF_BIT 2
+ #define RCC_CIR_LSERDYF_BIT 1
+ #define RCC_CIR_LSIRDYF_BIT 0
+
+ #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
+ #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
+ #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
+ #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
+ #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
+ #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
+ #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
+ #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
+ #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
+ #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
+ #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
+ #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
+ #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
+ #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
+ #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
+ #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
+ #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
+
+Peripheral reset registers
+++++++++++++++++++++++++++
+
+::
+
+ #define RCC_APB2RSTR_TIM11RST_BIT 21
+ #define RCC_APB2RSTR_TIM10RST_BIT 20
+ #define RCC_APB2RSTR_TIM9RST_BIT 19
+ #define RCC_APB2RSTR_ADC3RST_BIT 15
+ #define RCC_APB2RSTR_USART1RST_BIT 14
+ #define RCC_APB2RSTR_TIM8RST_BIT 13
+ #define RCC_APB2RSTR_SPI1RST_BIT 12
+ #define RCC_APB2RSTR_TIM1RST_BIT 11
+ #define RCC_APB2RSTR_ADC2RST_BIT 10
+ #define RCC_APB2RSTR_ADC1RST_BIT 9
+ #define RCC_APB2RSTR_IOPGRST_BIT 8
+ #define RCC_APB2RSTR_IOPFRST_BIT 7
+ #define RCC_APB2RSTR_IOPERST_BIT 6
+ #define RCC_APB2RSTR_IOPDRST_BIT 5
+ #define RCC_APB2RSTR_IOPCRST_BIT 4
+ #define RCC_APB2RSTR_IOPBRST_BIT 3
+ #define RCC_APB2RSTR_IOPARST_BIT 2
+ #define RCC_APB2RSTR_AFIORST_BIT 0
+
+ #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
+ #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
+ #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
+ #define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT)
+ #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
+ #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
+ #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
+ #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
+ #define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT)
+ #define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT)
+ #define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT)
+ #define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT)
+ #define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT)
+ #define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT)
+ #define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT)
+ #define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT)
+ #define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT)
+ #define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT)
+
+ #define RCC_APB1RSTR_DACRST_BIT 29
+ #define RCC_APB1RSTR_PWRRST_BIT 28
+ #define RCC_APB1RSTR_BKPRST_BIT 27
+ #define RCC_APB1RSTR_CANRST_BIT 25
+ #define RCC_APB1RSTR_USBRST_BIT 23
+ #define RCC_APB1RSTR_I2C2RST_BIT 22
+ #define RCC_APB1RSTR_I2C1RST_BIT 21
+ #define RCC_APB1RSTR_UART5RST_BIT 20
+ #define RCC_APB1RSTR_UART4RST_BIT 19
+ #define RCC_APB1RSTR_USART3RST_BIT 18
+ #define RCC_APB1RSTR_USART2RST_BIT 17
+ #define RCC_APB1RSTR_SPI3RST_BIT 15
+ #define RCC_APB1RSTR_SPI2RST_BIT 14
+ #define RCC_APB1RSTR_WWDRST_BIT 11
+ #define RCC_APB1RSTR_TIM14RST_BIT 8
+ #define RCC_APB1RSTR_TIM13RST_BIT 7
+ #define RCC_APB1RSTR_TIM12RST_BIT 6
+ #define RCC_APB1RSTR_TIM7RST_BIT 5
+ #define RCC_APB1RSTR_TIM6RST_BIT 4
+ #define RCC_APB1RSTR_TIM5RST_BIT 3
+ #define RCC_APB1RSTR_TIM4RST_BIT 2
+ #define RCC_APB1RSTR_TIM3RST_BIT 1
+ #define RCC_APB1RSTR_TIM2RST_BIT 0
+
+ #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
+ #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
+ #define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT)
+ #define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT)
+ #define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT)
+ #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
+ #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
+ #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
+ #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
+ #define RCC_APB1RSTR_USART3RST (1U << RCC_APB1RSTR_USART3RST_BIT)
+ #define RCC_APB1RSTR_USART2RST (1U << RCC_APB1RSTR_USART2RST_BIT)
+ #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
+ #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
+ #define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT)
+ #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
+ #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
+ #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
+ #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
+ #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
+ #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
+ #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
+ #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
+ #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
+
+Peripheral clock enable registers
++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_AHBENR_SDIOEN_BIT 10
+ #define RCC_AHBENR_FSMCEN_BIT 8
+ #define RCC_AHBENR_CRCEN_BIT 7
+ #define RCC_AHBENR_FLITFEN_BIT 4
+ #define RCC_AHBENR_SRAMEN_BIT 2
+ #define RCC_AHBENR_DMA2EN_BIT 1
+ #define RCC_AHBENR_DMA1EN_BIT 0
+
+ #define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT)
+ #define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT)
+ #define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT)
+ #define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT)
+ #define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT)
+ #define RCC_AHBENR_DMA2EN (1U << RCC_AHBENR_DMA2EN_BIT)
+ #define RCC_AHBENR_DMA1EN (1U << RCC_AHBENR_DMA1EN_BIT)
+
+ #define RCC_APB2ENR_TIM11EN_BIT 21
+ #define RCC_APB2ENR_TIM10EN_BIT 20
+ #define RCC_APB2ENR_TIM9EN_BIT 19
+ #define RCC_APB2ENR_ADC3EN_BIT 15
+ #define RCC_APB2ENR_USART1EN_BIT 14
+ #define RCC_APB2ENR_TIM8EN_BIT 13
+ #define RCC_APB2ENR_SPI1EN_BIT 12
+ #define RCC_APB2ENR_TIM1EN_BIT 11
+ #define RCC_APB2ENR_ADC2EN_BIT 10
+ #define RCC_APB2ENR_ADC1EN_BIT 9
+ #define RCC_APB2ENR_IOPGEN_BIT 8
+ #define RCC_APB2ENR_IOPFEN_BIT 7
+ #define RCC_APB2ENR_IOPEEN_BIT 6
+ #define RCC_APB2ENR_IOPDEN_BIT 5
+ #define RCC_APB2ENR_IOPCEN_BIT 4
+ #define RCC_APB2ENR_IOPBEN_BIT 3
+ #define RCC_APB2ENR_IOPAEN_BIT 2
+ #define RCC_APB2ENR_AFIOEN_BIT 0
+
+ #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
+ #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
+ #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
+ #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
+ #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
+ #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
+ #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
+ #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
+ #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
+ #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
+ #define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT)
+ #define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT)
+ #define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT)
+ #define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT)
+ #define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT)
+ #define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT)
+ #define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT)
+ #define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT)
+
+ #define RCC_APB1ENR_DACEN_BIT 29
+ #define RCC_APB1ENR_PWREN_BIT 28
+ #define RCC_APB1ENR_BKPEN_BIT 27
+ #define RCC_APB1ENR_CANEN_BIT 25
+ #define RCC_APB1ENR_USBEN_BIT 23
+ #define RCC_APB1ENR_I2C2EN_BIT 22
+ #define RCC_APB1ENR_I2C1EN_BIT 21
+ #define RCC_APB1ENR_UART5EN_BIT 20
+ #define RCC_APB1ENR_UART4EN_BIT 19
+ #define RCC_APB1ENR_USART3EN_BIT 18
+ #define RCC_APB1ENR_USART2EN_BIT 17
+ #define RCC_APB1ENR_SPI3EN_BIT 15
+ #define RCC_APB1ENR_SPI2EN_BIT 14
+ #define RCC_APB1ENR_WWDEN_BIT 11
+ #define RCC_APB1ENR_TIM14EN_BIT 8
+ #define RCC_APB1ENR_TIM13EN_BIT 7
+ #define RCC_APB1ENR_TIM12EN_BIT 6
+ #define RCC_APB1ENR_TIM7EN_BIT 5
+ #define RCC_APB1ENR_TIM6EN_BIT 4
+ #define RCC_APB1ENR_TIM5EN_BIT 3
+ #define RCC_APB1ENR_TIM4EN_BIT 2
+ #define RCC_APB1ENR_TIM3EN_BIT 1
+ #define RCC_APB1ENR_TIM2EN_BIT 0
+
+ #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
+ #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
+ #define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT)
+ #define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT)
+ #define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT)
+ #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
+ #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
+ #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
+ #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
+ #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
+ #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
+ #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
+ #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
+ #define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT)
+ #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
+ #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
+ #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
+ #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
+ #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
+ #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
+ #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
+ #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
+ #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
+
+Backup domain control register
+++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_BDCR_BDRST_BIT 16
+ #define RCC_BDCR_RTCEN_BIT 15
+ #define RCC_BDCR_LSEBYP_BIT 2
+ #define RCC_BDCR_LSERDY_BIT 1
+ #define RCC_BDCR_LSEON_BIT 0
+
+ #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
+ #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT)
+ #define RCC_BDCR_RTCSEL (0x3 << 8)
+ #define RCC_BDCR_RTCSEL_NONE (0x0 << 8)
+ #define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
+ #define RCC_BDCR_RTCSEL_HSE (0x3 << 8)
+ #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
+ #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
+ #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
+
+Control/status register
++++++++++++++++++++++++
+
+::
+
+ #define RCC_CSR_LPWRRSTF_BIT 31
+ #define RCC_CSR_WWDGRSTF_BIT 30
+ #define RCC_CSR_IWDGRSTF_BIT 29
+ #define RCC_CSR_SFTRSTF_BIT 28
+ #define RCC_CSR_PORRSTF_BIT 27
+ #define RCC_CSR_PINRSTF_BIT 26
+ #define RCC_CSR_RMVF_BIT 24
+ #define RCC_CSR_LSIRDY_BIT 1
+ #define RCC_CSR_LSION_BIT 0
+
+ #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
+ #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
+ #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
+ #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
+ #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
+ #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
+ #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
+ #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
+ #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+Clock control register
+++++++++++++++++++++++
+
+::
+
+ #define RCC_CR_PLLI2SRDY_BIT 27
+ #define RCC_CR_PLLI2SON_BIT 26
+ #define RCC_CR_PLLRDY_BIT 25
+ #define RCC_CR_PLLON_BIT 24
+ #define RCC_CR_CSSON_BIT 19
+ #define RCC_CR_HSEBYP_BIT 18
+ #define RCC_CR_HSERDY_BIT 17
+ #define RCC_CR_HSEON_BIT 16
+ #define RCC_CR_HSIRDY_BIT 1
+ #define RCC_CR_HSION_BIT 0
+
+ #define RCC_CR_PLLI2SRDY (1U << RCC_CR_PLLI2SRDY_BIT)
+ #define RCC_CR_PLLI2SON (1U << RCC_CR_PLLI2SON_BIT)
+ #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
+ #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
+ #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
+ #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
+ #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
+ #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
+ #define RCC_CR_HSICAL (0xFF << 8)
+ #define RCC_CR_HSITRIM (0x1F << 3)
+ #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
+ #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
+
+PLL configuration register
+++++++++++++++++++++++++++
+
+::
+
+ #define RCC_PLLCFGR_PLLSRC_BIT 22
+
+ #define RCC_PLLCFGR_PLLQ (0xF << 24)
+ #define RCC_PLLCFGR_PLLSRC (1U << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLSRC_HSI (0x0 << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLSRC_HSE (0x1 << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLP (0x3 << 16)
+ #define RCC_PLLCFGR_PLLN (0x1FF << 6)
+ #define RCC_PLLCFGR_PLLM 0x1F
+
+Clock configuration register
+++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CFGR_I2SSRC_BIT 23
+
+ #define RCC_CFGR_MCO2 (0x3 << 30)
+ #define RCC_CFGR_MCO2_SYSCLK (0x0 << 30)
+ #define RCC_CFGR_MCO2_PLLI2S (0x1 << 30)
+ #define RCC_CFGR_MCO2_HSE (0x2 << 30)
+ #define RCC_CFGR_MCO2_PLL (0x3 << 30)
+
+ #define RCC_CFGR_MCO2PRE (0x7 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_1 (0x0 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_2 (0x4 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_3 (0x5 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_4 (0x6 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_5 (0x7 << 27)
+
+ #define RCC_CFGR_MCO1PRE (0x7 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_1 (0x0 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_2 (0x4 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_3 (0x5 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_4 (0x6 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_5 (0x7 << 24)
+
+ #define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2SSRC_BIT)
+ #define RCC_CFGR_I2SSRC_PLLI2S (0 << RCC_CFGR_I2SSRC_BIT)
+ #define RCC_CFGR_I2SSRC_I2S_CKIN (1 << RCC_CFGR_I2SSRC_BIT)
+
+ #define RCC_CFGR_MCO1 (0x3 << 21)
+ #define RCC_CFGR_MCO1_HSI (0x0 << 21)
+ #define RCC_CFGR_MCO1_LSE (0x1 << 21)
+ #define RCC_CFGR_MCO1_HSE (0x2 << 21)
+ #define RCC_CFGR_MCO1_PLL (0x3 << 21)
+
+ #define RCC_CFGR_RTCPRE (0x1F << 16)
+
+ /* Skipped: all the 0b0xx values meaning "not divided" */
+ #define RCC_CFGR_PPRE2 (0x7 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_2 (0x4 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_4 (0x5 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_8 (0x6 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_16 (0x7 << 13)
+
+ /* Skipped: all the 0b0xx values meaning "not divided" */
+ #define RCC_CFGR_PPRE1 (0x7 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_2 (0x4 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_4 (0x5 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_8 (0x6 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_16 (0x7 << 10)
+
+ /* Skipped: all the 0b0xxx values meaning "not divided" */
+ #define RCC_CFGR_HPRE (0xF << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_2 (0x8 << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_4 (0x9 << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_8 (0xA << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_16 (0xB << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_64 (0xC << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_128 (0xD << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_256 (0xE << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_512 (0xF << 4)
+
+ #define RCC_CFGR_SWS (0x3 << 2)
+ #define RCC_CFGR_SWS_HSI (0x0 << 2)
+ #define RCC_CFGR_SWS_HSE (0x1 << 2)
+ #define RCC_CFGR_SWS_PLL (0x2 << 2)
+
+ #define RCC_CFGR_SW 0x3
+ #define RCC_CFGR_SW_HSI 0x0
+ #define RCC_CFGR_SW_HSE 0x1
+ #define RCC_CFGR_SW_PLL 0x2
+
+Clock interrupt register
+++++++++++++++++++++++++
+
+::
+
+ #define RCC_CIR_CSSC_BIT 23
+
+ #define RCC_CIR_PLLI2SRDYC_BIT 21
+ #define RCC_CIR_PLLRDYC_BIT 20
+ #define RCC_CIR_HSERDYC_BIT 19
+ #define RCC_CIR_HSIRDYC_BIT 18
+ #define RCC_CIR_LSERDYC_BIT 17
+ #define RCC_CIR_LSIRDYC_BIT 16
+
+ #define RCC_CIR_PLLI2SRDYIE_BIT 13
+ #define RCC_CIR_PLLRDYIE_BIT 12
+ #define RCC_CIR_HSERDYIE_BIT 11
+ #define RCC_CIR_HSIRDYIE_BIT 10
+ #define RCC_CIR_LSERDYIE_BIT 9
+ #define RCC_CIR_LSIRDYIE_BIT 8
+
+ #define RCC_CIR_CSSF_BIT 7
+
+ #define RCC_CIR_PLLI2SRDYF_BIT 5
+ #define RCC_CIR_PLLRDYF_BIT 4
+ #define RCC_CIR_HSERDYF_BIT 3
+ #define RCC_CIR_HSIRDYF_BIT 2
+ #define RCC_CIR_LSERDYF_BIT 1
+ #define RCC_CIR_LSIRDYF_BIT 0
+
+ #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
+
+ #define RCC_CIR_PLLI2SRDYC (1U << RCC_CIR_PLLI2SRDYC_BIT)
+ #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
+ #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
+ #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
+ #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
+ #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
+
+ #define RCC_CIR_PLLI2SRDYIE (1U << RCC_CIR_PLLI2SRDYIE_BIT)
+ #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
+ #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
+ #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
+ #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
+ #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
+
+ #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
+
+ #define RCC_CIR_PLLI2SRDYF (1U << RCC_CIR_PLLI2SRDYF_BIT)
+ #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
+ #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
+ #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
+ #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
+ #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
+
+Peripheral reset registers
+++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1RSTR_OTGHSRST_BIT 29
+ #define RCC_AHB1RSTR_ETHMACRST_BIT 25
+ #define RCC_AHB1RSTR_DMA2RST_BIT 22
+ #define RCC_AHB1RSTR_DMA1RST_BIT 21
+ #define RCC_AHB1RSTR_CRCRST_BIT 12
+ #define RCC_AHB1RSTR_GPIOIRST_BIT 8
+ #define RCC_AHB1RSTR_GPIOHRST_BIT 7
+ #define RCC_AHB1RSTR_GPIOGRST_BIT 6
+ #define RCC_AHB1RSTR_GPIOFRST_BIT 5
+ #define RCC_AHB1RSTR_GPIOERST_BIT 4
+ #define RCC_AHB1RSTR_GPIODRST_BIT 3
+ #define RCC_AHB1RSTR_GPIOCRST_BIT 2
+ #define RCC_AHB1RSTR_GPIOBRST_BIT 1
+ #define RCC_AHB1RSTR_GPIOARST_BIT 0
+
+ #define RCC_AHB1RSTR_OTGHSRST (1U << RCC_AHB1RSTR_OTGHSRST_BIT)
+ #define RCC_AHB1RSTR_ETHMACRST (1U << RCC_AHB1RSTR_ETHMACRST_BIT)
+ #define RCC_AHB1RSTR_DMA2RST (1U << RCC_AHB1RSTR_DMA2RST_BIT)
+ #define RCC_AHB1RSTR_DMA1RST (1U << RCC_AHB1RSTR_DMA1RST_BIT)
+ #define RCC_AHB1RSTR_CRCRST (1U << RCC_AHB1RSTR_CRCRST_BIT)
+ #define RCC_AHB1RSTR_GPIOIRST (1U << RCC_AHB1RSTR_GPIOIRST_BIT)
+ #define RCC_AHB1RSTR_GPIOHRST (1U << RCC_AHB1RSTR_GPIOHRST_BIT)
+ #define RCC_AHB1RSTR_GPIOGRST (1U << RCC_AHB1RSTR_GPIOGRST_BIT)
+ #define RCC_AHB1RSTR_GPIOFRST (1U << RCC_AHB1RSTR_GPIOFRST_BIT)
+ #define RCC_AHB1RSTR_GPIOERST (1U << RCC_AHB1RSTR_GPIOERST_BIT)
+ #define RCC_AHB1RSTR_GPIODRST (1U << RCC_AHB1RSTR_GPIODRST_BIT)
+ #define RCC_AHB1RSTR_GPIOCRST (1U << RCC_AHB1RSTR_GPIOCRST_BIT)
+ #define RCC_AHB1RSTR_GPIOBRST (1U << RCC_AHB1RSTR_GPIOBRST_BIT)
+ #define RCC_AHB1RSTR_GPIOARST (1U << RCC_AHB1RSTR_GPIOARST_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2RSTR_OTGFSRST_BIT 7
+ #define RCC_AHB2RSTR_RNGRST_BIT 6
+ #define RCC_AHB2RSTR_HASHRST_BIT 5
+ #define RCC_AHB2RSTR_CRYPRST_BIT 4
+ #define RCC_AHB2RSTR_DCMIRST_BIT 0
+
+ #define RCC_AHB2RSTR_OTGFSRST (1U << RCC_AHB2RSTR_OTGFSRST_BIT)
+ #define RCC_AHB2RSTR_RNGRST (1U << RCC_AHB2RSTR_RNGRST_BIT)
+ #define RCC_AHB2RSTR_HASHRST (1U << RCC_AHB2RSTR_HASHRST_BIT)
+ #define RCC_AHB2RSTR_CRYPRST (1U << RCC_AHB2RSTR_CRYPRST_BIT)
+ #define RCC_AHB2RSTR_DCMIRST (1U << RCC_AHB2RSTR_DCMIRST_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3RSTR_FSMCRST_BIT 0
+
+ #define RCC_AHB3RSTR_FSMCRST (1U << RCC_AHB3RSTR_FSMCRST_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1RSTR_DACRST_BIT 29
+ #define RCC_APB1RSTR_PWRRST_BIT 28
+ #define RCC_APB1RSTR_CAN2RST_BIT 26
+ #define RCC_APB1RSTR_CAN1RST_BIT 25
+ #define RCC_APB1RSTR_I2C3RST_BIT 23
+ #define RCC_APB1RSTR_I2C2RST_BIT 22
+ #define RCC_APB1RSTR_I2C1RST_BIT 21
+ #define RCC_APB1RSTR_UART5RST_BIT 20
+ #define RCC_APB1RSTR_UART4RST_BIT 19
+ #define RCC_APB1RSTR_UART3RST_BIT 18
+ #define RCC_APB1RSTR_UART2RST_BIT 17
+ #define RCC_APB1RSTR_SPI3RST_BIT 15
+ #define RCC_APB1RSTR_SPI2RST_BIT 14
+ #define RCC_APB1RSTR_WWDGRST_BIT 11
+ #define RCC_APB1RSTR_TIM14RST_BIT 8
+ #define RCC_APB1RSTR_TIM13RST_BIT 7
+ #define RCC_APB1RSTR_TIM12RST_BIT 6
+ #define RCC_APB1RSTR_TIM7RST_BIT 5
+ #define RCC_APB1RSTR_TIM6RST_BIT 4
+ #define RCC_APB1RSTR_TIM5RST_BIT 3
+ #define RCC_APB1RSTR_TIM4RST_BIT 2
+ #define RCC_APB1RSTR_TIM3RST_BIT 1
+ #define RCC_APB1RSTR_TIM2RST_BIT 0
+
+ #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
+ #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
+ #define RCC_APB1RSTR_CAN2RST (1U << RCC_APB1RSTR_CAN2RST_BIT)
+ #define RCC_APB1RSTR_CAN1RST (1U << RCC_APB1RSTR_CAN1RST_BIT)
+ #define RCC_APB1RSTR_I2C3RST (1U << RCC_APB1RSTR_I2C3RST_BIT)
+ #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
+ #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
+ #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
+ #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
+ #define RCC_APB1RSTR_UART3RST (1U << RCC_APB1RSTR_UART3RST_BIT)
+ #define RCC_APB1RSTR_UART2RST (1U << RCC_APB1RSTR_UART2RST_BIT)
+ #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
+ #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
+ #define RCC_APB1RSTR_WWDGRST (1U << RCC_APB1RSTR_WWDGRST_BIT)
+ #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
+ #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
+ #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
+ #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
+ #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
+ #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
+ #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
+ #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
+ #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2RSTR_TIM11RST_BIT 18
+ #define RCC_APB2RSTR_TIM10RST_BIT 17
+ #define RCC_APB2RSTR_TIM9RST_BIT 16
+ #define RCC_APB2RSTR_SYSCFGRST_BIT 14
+ #define RCC_APB2RSTR_SPI1RST_BIT 12
+ #define RCC_APB2RSTR_SDIORST_BIT 11
+ #define RCC_APB2RSTR_ADCRST_BIT 8
+ #define RCC_APB2RSTR_USART6RST_BIT 5
+ #define RCC_APB2RSTR_USART1RST_BIT 4
+ #define RCC_APB2RSTR_TIM8RST_BIT 1
+ #define RCC_APB2RSTR_TIM1RST_BIT 0
+
+ #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
+ #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
+ #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
+ #define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT)
+ #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
+ #define RCC_APB2RSTR_SDIORST (1U << RCC_APB2RSTR_SDIORST_BIT)
+ #define RCC_APB2RSTR_ADCRST (1U << RCC_APB2RSTR_ADCRST_BIT)
+ #define RCC_APB2RSTR_USART6RST (1U << RCC_APB2RSTR_USART6RST_BIT)
+ #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
+ #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
+ #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
+
+Peripheral clock enable registers
++++++++++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1ENR_OTGHSULPIEN_BIT 30
+ #define RCC_AHB1ENR_OTGHSEN_BIT 29
+ #define RCC_AHB1ENR_ETHMACPTPEN_BIT 28
+ #define RCC_AHB1ENR_ETHMACRXEN_BIT 27
+ #define RCC_AHB1ENR_ETHMACTXEN_BIT 26
+ #define RCC_AHB1ENR_ETHMACEN_BIT 25
+ #define RCC_AHB1ENR_DMA2EN_BIT 22
+ #define RCC_AHB1ENR_DMA1EN_BIT 21
+ #define RCC_AHB1ENR_BKPSRAMEN_BIT 18
+ #define RCC_AHB1ENR_CRCEN_BIT 12
+ #define RCC_AHB1ENR_GPIOIEN_BIT 8
+ #define RCC_AHB1ENR_GPIOHEN_BIT 7
+ #define RCC_AHB1ENR_GPIOGEN_BIT 6
+ #define RCC_AHB1ENR_GPIOFEN_BIT 5
+ #define RCC_AHB1ENR_GPIOEEN_BIT 4
+ #define RCC_AHB1ENR_GPIODEN_BIT 3
+ #define RCC_AHB1ENR_GPIOCEN_BIT 2
+ #define RCC_AHB1ENR_GPIOBEN_BIT 1
+ #define RCC_AHB1ENR_GPIOAEN_BIT 0
+
+ #define RCC_AHB1ENR_OTGHSULPIEN (1U << RCC_AHB1ENR_OTGHSULPIEN_BIT)
+ #define RCC_AHB1ENR_OTGHSEN (1U << RCC_AHB1ENR_OTGHSEN_BIT)
+ #define RCC_AHB1ENR_ETHMACPTPEN (1U << RCC_AHB1ENR_ETHMACPTPEN_BIT)
+ #define RCC_AHB1ENR_ETHMACRXEN (1U << RCC_AHB1ENR_ETHMACRXEN_BIT)
+ #define RCC_AHB1ENR_ETHMACTXEN (1U << RCC_AHB1ENR_ETHMACTXEN_BIT)
+ #define RCC_AHB1ENR_ETHMACEN (1U << RCC_AHB1ENR_ETHMACEN_BIT)
+ #define RCC_AHB1ENR_DMA2EN (1U << RCC_AHB1ENR_DMA2EN_BIT)
+ #define RCC_AHB1ENR_DMA1EN (1U << RCC_AHB1ENR_DMA1EN_BIT)
+ #define RCC_AHB1ENR_BKPSRAMEN (1U << RCC_AHB1ENR_BKPSRAMEN_BIT)
+ #define RCC_AHB1ENR_CRCEN (1U << RCC_AHB1ENR_CRCEN_BIT)
+ #define RCC_AHB1ENR_GPIOIEN (1U << RCC_AHB1ENR_GPIOIEN_BIT)
+ #define RCC_AHB1ENR_GPIOHEN (1U << RCC_AHB1ENR_GPIOHEN_BIT)
+ #define RCC_AHB1ENR_GPIOGEN (1U << RCC_AHB1ENR_GPIOGEN_BIT)
+ #define RCC_AHB1ENR_GPIOFEN (1U << RCC_AHB1ENR_GPIOFEN_BIT)
+ #define RCC_AHB1ENR_GPIOEEN (1U << RCC_AHB1ENR_GPIOEEN_BIT)
+ #define RCC_AHB1ENR_GPIODEN (1U << RCC_AHB1ENR_GPIODEN_BIT)
+ #define RCC_AHB1ENR_GPIOCEN (1U << RCC_AHB1ENR_GPIOCEN_BIT)
+ #define RCC_AHB1ENR_GPIOBEN (1U << RCC_AHB1ENR_GPIOBEN_BIT)
+ #define RCC_AHB1ENR_GPIOAEN (1U << RCC_AHB1ENR_GPIOAEN_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2ENR_OTGFSEN_BIT 7
+ #define RCC_AHB2ENR_RNGEN_BIT 6
+ #define RCC_AHB2ENR_HASHEN_BIT 5
+ #define RCC_AHB2ENR_CRYPEN_BIT 4
+ #define RCC_AHB2ENR_DCMIEN_BIT 0
+
+ #define RCC_AHB2ENR_OTGFSEN (1U << RCC_AHB2ENR_OTGFSEN_BIT)
+ #define RCC_AHB2ENR_RNGEN (1U << RCC_AHB2ENR_RNGEN_BIT)
+ #define RCC_AHB2ENR_HASHEN (1U << RCC_AHB2ENR_HASHEN_BIT)
+ #define RCC_AHB2ENR_CRYPEN (1U << RCC_AHB2ENR_CRYPEN_BIT)
+ #define RCC_AHB2ENR_DCMIEN (1U << RCC_AHB2ENR_DCMIEN_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3ENR_FSMCEN_BIT 0
+
+ #define RCC_AHB3ENR_FSMCEN (1U << RCC_AHB3ENR_FSMCEN_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1ENR_DACEN_BIT 29
+ #define RCC_APB1ENR_PWREN_BIT 28
+ #define RCC_APB1ENR_CAN2EN_BIT 26
+ #define RCC_APB1ENR_CAN1EN_BIT 25
+ #define RCC_APB1ENR_I2C3EN_BIT 23
+ #define RCC_APB1ENR_I2C2EN_BIT 22
+ #define RCC_APB1ENR_I2C1EN_BIT 21
+ #define RCC_APB1ENR_UART5EN_BIT 20
+ #define RCC_APB1ENR_UART4EN_BIT 19
+ #define RCC_APB1ENR_USART3EN_BIT 18
+ #define RCC_APB1ENR_USART2EN_BIT 17
+ #define RCC_APB1ENR_SPI3EN_BIT 15
+ #define RCC_APB1ENR_SPI2EN_BIT 14
+ #define RCC_APB1ENR_WWDGEN_BIT 11
+ #define RCC_APB1ENR_TIM14EN_BIT 8
+ #define RCC_APB1ENR_TIM13EN_BIT 7
+ #define RCC_APB1ENR_TIM12EN_BIT 6
+ #define RCC_APB1ENR_TIM7EN_BIT 5
+ #define RCC_APB1ENR_TIM6EN_BIT 4
+ #define RCC_APB1ENR_TIM5EN_BIT 3
+ #define RCC_APB1ENR_TIM4EN_BIT 2
+ #define RCC_APB1ENR_TIM3EN_BIT 1
+ #define RCC_APB1ENR_TIM2EN_BIT 0
+
+ #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
+ #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
+ #define RCC_APB1ENR_CAN2EN (1U << RCC_APB1ENR_CAN2EN_BIT)
+ #define RCC_APB1ENR_CAN1EN (1U << RCC_APB1ENR_CAN1EN_BIT)
+ #define RCC_APB1ENR_I2C3EN (1U << RCC_APB1ENR_I2C3EN_BIT)
+ #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
+ #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
+ #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
+ #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
+ #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
+ #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
+ #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
+ #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
+ #define RCC_APB1ENR_WWDGEN (1U << RCC_APB1ENR_WWDGEN_BIT)
+ #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
+ #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
+ #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
+ #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
+ #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
+ #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
+ #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
+ #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
+ #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2ENR_TIM11EN_BIT 18
+ #define RCC_APB2ENR_TIM10EN_BIT 17
+ #define RCC_APB2ENR_TIM9EN_BIT 16
+ #define RCC_APB2ENR_SYSCFGEN_BIT 14
+ #define RCC_APB2ENR_SPI1EN_BIT 12
+ #define RCC_APB2ENR_SDIOEN_BIT 11
+ #define RCC_APB2ENR_ADC3EN_BIT 10
+ #define RCC_APB2ENR_ADC2EN_BIT 9
+ #define RCC_APB2ENR_ADC1EN_BIT 8
+ #define RCC_APB2ENR_USART6EN_BIT 5
+ #define RCC_APB2ENR_USART1EN_BIT 4
+ #define RCC_APB2ENR_TIM8EN_BIT 1
+ #define RCC_APB2ENR_TIM1EN_BIT 0
+
+ #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
+ #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
+ #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
+ #define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT)
+ #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
+ #define RCC_APB2ENR_SDIOEN (1U << RCC_APB2ENR_SDIOEN_BIT)
+ #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
+ #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
+ #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
+ #define RCC_APB2ENR_USART6EN (1U << RCC_APB2ENR_USART6EN_BIT)
+ #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
+ #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
+ #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
+
+Peripheral clock enable in low power mode registers
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1LPENR_OTGHSULPILPEN_BIT 30
+ #define RCC_AHB1LPENR_OTGHSLPEN_BIT 29
+ #define RCC_AHB1LPENR_ETHMACPTPLPEN_BIT 28
+ #define RCC_AHB1LPENR_ETHMACRXLPEN_BIT 27
+ #define RCC_AHB1LPENR_ETHMACTXLPEN_BIT 26
+ #define RCC_AHB1LPENR_ETHMACLPEN_BIT 25
+ #define RCC_AHB1LPENR_DMA2LPEN_BIT 22
+ #define RCC_AHB1LPENR_DMA1LPEN_BIT 21
+ #define RCC_AHB1LPENR_BKPSRAMLPEN_BIT 18
+ #define RCC_AHB1LPENR_SRAM2LPEN_BIT 17
+ #define RCC_AHB1LPENR_SRAM1LPEN_BIT 16
+ #define RCC_AHB1LPENR_FLITFLPEN_BIT 15
+ #define RCC_AHB1LPENR_CRCLPEN_BIT 12
+ #define RCC_AHB1LPENR_GPIOILPEN_BIT 8
+ #define RCC_AHB1LPENR_GPIOGLPEN_BIT 6
+ #define RCC_AHB1LPENR_GPIOFLPEN_BIT 5
+ #define RCC_AHB1LPENR_GPIOELPEN_BIT 4
+ #define RCC_AHB1LPENR_GPIODLPEN_BIT 3
+ #define RCC_AHB1LPENR_GPIOCLPEN_BIT 2
+ #define RCC_AHB1LPENR_GPIOBLPEN_BIT 1
+ #define RCC_AHB1LPENR_GPIOALPEN_BIT 0
+
+ #define RCC_AHB1LPENR_OTGHSULPILPEN (1U << RCC_AHB1LPENR_OTGHSULPILPEN_BIT)
+ #define RCC_AHB1LPENR_OTGHSLPEN (1U << RCC_AHB1LPENR_OTGHSLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACPTPLPEN (1U << RCC_AHB1LPENR_ETHMACPTPLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACRXLPEN (1U << RCC_AHB1LPENR_ETHMACRXLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACTXLPEN (1U << RCC_AHB1LPENR_ETHMACTXLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACLPEN (1U << RCC_AHB1LPENR_ETHMACLPEN_BIT)
+ #define RCC_AHB1LPENR_DMA2LPEN (1U << RCC_AHB1LPENR_DMA2LPEN_BIT)
+ #define RCC_AHB1LPENR_DMA1LPEN (1U << RCC_AHB1LPENR_DMA1LPEN_BIT)
+ #define RCC_AHB1LPENR_BKPSRAMLPEN (1U << RCC_AHB1LPENR_BKPSRAMLPEN_BIT)
+ #define RCC_AHB1LPENR_SRAM2LPEN (1U << RCC_AHB1LPENR_SRAM2LPEN_BIT)
+ #define RCC_AHB1LPENR_SRAM1LPEN (1U << RCC_AHB1LPENR_SRAM1LPEN_BIT)
+ #define RCC_AHB1LPENR_FLITFLPEN (1U << RCC_AHB1LPENR_FLITFLPEN_BIT)
+ #define RCC_AHB1LPENR_CRCLPEN (1U << RCC_AHB1LPENR_CRCLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOILPEN (1U << RCC_AHB1LPENR_GPIOILPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOGLPEN (1U << RCC_AHB1LPENR_GPIOGLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOFLPEN (1U << RCC_AHB1LPENR_GPIOFLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOELPEN (1U << RCC_AHB1LPENR_GPIOELPEN_BIT)
+ #define RCC_AHB1LPENR_GPIODLPEN (1U << RCC_AHB1LPENR_GPIODLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOCLPEN (1U << RCC_AHB1LPENR_GPIOCLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOBLPEN (1U << RCC_AHB1LPENR_GPIOBLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOALPEN (1U << RCC_AHB1LPENR_GPIOALPEN_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2LPENR_OTGFSLPEN_BIT 7
+ #define RCC_AHB2LPENR_RNGLPEN_BIT 6
+ #define RCC_AHB2LPENR_HASHLPEN_BIT 5
+ #define RCC_AHB2LPENR_CRYPLPEN_BIT 4
+ #define RCC_AHB2LPENR_DCMILPEN_BIT 0
+
+ #define RCC_AHB2LPENR_OTGFSLPEN (1U << RCC_AHB2LPENR_OTGFSLPEN_BIT)
+ #define RCC_AHB2LPENR_RNGLPEN (1U << RCC_AHB2LPENR_RNGLPEN_BIT)
+ #define RCC_AHB2LPENR_HASHLPEN (1U << RCC_AHB2LPENR_HASHLPEN_BIT)
+ #define RCC_AHB2LPENR_CRYPLPEN (1U << RCC_AHB2LPENR_CRYPLPEN_BIT)
+ #define RCC_AHB2LPENR_DCMILPEN (1U << RCC_AHB2LPENR_DCMILPEN_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3LPENR_FSMCLPEN_BIT 0
+
+ #define RCC_AHB3LPENR_FSMCLPEN (1U << RCC_AHB3LPENR_FSMCLPEN_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1LPENR_DACLPEN_BIT 29
+ #define RCC_APB1LPENR_PWRLPEN_BIT 28
+ #define RCC_APB1LPENR_CAN2LPEN_BIT 26
+ #define RCC_APB1LPENR_CAN1LPEN_BIT 25
+ #define RCC_APB1LPENR_I2C3LPEN_BIT 23
+ #define RCC_APB1LPENR_I2C2LPEN_BIT 22
+ #define RCC_APB1LPENR_I2C1LPEN_BIT 21
+ #define RCC_APB1LPENR_UART5LPEN_BIT 20
+ #define RCC_APB1LPENR_UART4LPEN_BIT 19
+ #define RCC_APB1LPENR_USART3LPEN_BIT 18
+ #define RCC_APB1LPENR_USART2LPEN_BIT 17
+ #define RCC_APB1LPENR_SPI3LPEN_BIT 15
+ #define RCC_APB1LPENR_SPI2LPEN_BIT 14
+ #define RCC_APB1LPENR_WWDGLPEN_BIT 11
+ #define RCC_APB1LPENR_TIM14LPEN_BIT 8
+ #define RCC_APB1LPENR_TIM13LPEN_BIT 7
+ #define RCC_APB1LPENR_TIM12LPEN_BIT 6
+ #define RCC_APB1LPENR_TIM7LPEN_BIT 5
+ #define RCC_APB1LPENR_TIM6LPEN_BIT 4
+ #define RCC_APB1LPENR_TIM5LPEN_BIT 3
+ #define RCC_APB1LPENR_TIM4LPEN_BIT 2
+ #define RCC_APB1LPENR_TIM3LPEN_BIT 1
+ #define RCC_APB1LPENR_TIM2LPEN_BIT 0
+
+ #define RCC_APB1LPENR_DACLPEN (1U << RCC_APB1LPENR_DACLPEN_BIT)
+ #define RCC_APB1LPENR_PWRLPEN (1U << RCC_APB1LPENR_PWRLPEN_BIT)
+ #define RCC_APB1LPENR_CAN2LPEN (1U << RCC_APB1LPENR_CAN2LPEN_BIT)
+ #define RCC_APB1LPENR_CAN1LPEN (1U << RCC_APB1LPENR_CAN1LPEN_BIT)
+ #define RCC_APB1LPENR_I2C3LPEN (1U << RCC_APB1LPENR_I2C3LPEN_BIT)
+ #define RCC_APB1LPENR_I2C2LPEN (1U << RCC_APB1LPENR_I2C2LPEN_BIT)
+ #define RCC_APB1LPENR_I2C1LPEN (1U << RCC_APB1LPENR_I2C1LPEN_BIT)
+ #define RCC_APB1LPENR_UART5LPEN (1U << RCC_APB1LPENR_UART5LPEN_BIT)
+ #define RCC_APB1LPENR_UART4LPEN (1U << RCC_APB1LPENR_UART4LPEN_BIT)
+ #define RCC_APB1LPENR_USART3LPEN (1U << RCC_APB1LPENR_USART3LPEN_BIT)
+ #define RCC_APB1LPENR_USART2LPEN (1U << RCC_APB1LPENR_USART2LPEN_BIT)
+ #define RCC_APB1LPENR_SPI3LPEN (1U << RCC_APB1LPENR_SPI3LPEN_BIT)
+ #define RCC_APB1LPENR_SPI2LPEN (1U << RCC_APB1LPENR_SPI2LPEN_BIT)
+ #define RCC_APB1LPENR_WWDGLPEN (1U << RCC_APB1LPENR_WWDGLPEN_BIT)
+ #define RCC_APB1LPENR_TIM14LPEN (1U << RCC_APB1LPENR_TIM14LPEN_BIT)
+ #define RCC_APB1LPENR_TIM13LPEN (1U << RCC_APB1LPENR_TIM13LPEN_BIT)
+ #define RCC_APB1LPENR_TIM12LPEN (1U << RCC_APB1LPENR_TIM12LPEN_BIT)
+ #define RCC_APB1LPENR_TIM7LPEN (1U << RCC_APB1LPENR_TIM7LPEN_BIT)
+ #define RCC_APB1LPENR_TIM6LPEN (1U << RCC_APB1LPENR_TIM6LPEN_BIT)
+ #define RCC_APB1LPENR_TIM5LPEN (1U << RCC_APB1LPENR_TIM5LPEN_BIT)
+ #define RCC_APB1LPENR_TIM4LPEN (1U << RCC_APB1LPENR_TIM4LPEN_BIT)
+ #define RCC_APB1LPENR_TIM3LPEN (1U << RCC_APB1LPENR_TIM3LPEN_BIT)
+ #define RCC_APB1LPENR_TIM2LPEN (1U << RCC_APB1LPENR_TIM2LPEN_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2LPENR_TIM11LPEN_BIT 18
+ #define RCC_APB2LPENR_TIM10LPEN_BIT 17
+ #define RCC_APB2LPENR_TIM9LPEN_BIT 16
+ #define RCC_APB2LPENR_SYSCFGLPEN_BIT 14
+ #define RCC_APB2LPENR_SPI1LPEN_BIT 12
+ #define RCC_APB2LPENR_SDIOLPEN_BIT 11
+ #define RCC_APB2LPENR_ADC3LPEN_BIT 10
+ #define RCC_APB2LPENR_ADC2LPEN_BIT 9
+ #define RCC_APB2LPENR_ADC1LPEN_BIT 8
+ #define RCC_APB2LPENR_USART6LPEN_BIT 5
+ #define RCC_APB2LPENR_USART1LPEN_BIT 4
+ #define RCC_APB2LPENR_TIM8LPEN_BIT 1
+ #define RCC_APB2LPENR_TIM1LPEN_BIT 0
+
+ #define RCC_APB2LPENR_TIM11LPEN (1U << RCC_APB2LPENR_TIM11LPEN_BIT)
+ #define RCC_APB2LPENR_TIM10LPEN (1U << RCC_APB2LPENR_TIM10LPEN_BIT)
+ #define RCC_APB2LPENR_TIM9LPEN (1U << RCC_APB2LPENR_TIM9LPEN_BIT)
+ #define RCC_APB2LPENR_SYSCFGLPEN (1U << RCC_APB2LPENR_SYSCFGLPEN_BIT)
+ #define RCC_APB2LPENR_SPI1LPEN (1U << RCC_APB2LPENR_SPI1LPEN_BIT)
+ #define RCC_APB2LPENR_SDIOLPEN (1U << RCC_APB2LPENR_SDIOLPEN_BIT)
+ #define RCC_APB2LPENR_ADC3LPEN (1U << RCC_APB2LPENR_ADC3LPEN_BIT)
+ #define RCC_APB2LPENR_ADC2LPEN (1U << RCC_APB2LPENR_ADC2LPEN_BIT)
+ #define RCC_APB2LPENR_ADC1LPEN (1U << RCC_APB2LPENR_ADC1LPEN_BIT)
+ #define RCC_APB2LPENR_USART6LPEN (1U << RCC_APB2LPENR_USART6LPEN_BIT)
+ #define RCC_APB2LPENR_USART1LPEN (1U << RCC_APB2LPENR_USART1LPEN_BIT)
+ #define RCC_APB2LPENR_TIM8LPEN (1U << RCC_APB2LPENR_TIM8LPEN_BIT)
+ #define RCC_APB2LPENR_TIM1LPEN (1U << RCC_APB2LPENR_TIM1LPEN_BIT)
+
+Backup domain control register
+++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_BDCR_BDRST_BIT 16
+ #define RCC_BDCR_RTCEN_BIT 15
+ #define RCC_BDCR_LSEBYP_BIT 2
+ #define RCC_BDCR_LSERDY_BIT 1
+ #define RCC_BDCR_LSEON_BIT 0
+
+ #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
+ #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT)
+ #define RCC_BDCR_RTCSEL (0x3 << 8)
+ #define RCC_BDCR_RTCSEL_NOCLOCK (0x0 << 8)
+ #define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
+ #define RCC_BDCR_RTCSEL_LSI (0x2 << 8)
+ #define RCC_BDCR_RTCSEL_HSE_DIV (0x3 << 8)
+ #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
+ #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
+ #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
+
+Clock control and status register
++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CSR_LPWRRSTF_BIT 31
+ #define RCC_CSR_WWDGRSTF_BIT 30
+ #define RCC_CSR_IWDGRSTF_BIT 29
+ #define RCC_CSR_SFTRSTF_BIT 28
+ #define RCC_CSR_PORRSTF_BIT 27
+ #define RCC_CSR_PINRSTF_BIT 26
+ #define RCC_CSR_BORRSTF_BIT 25
+ #define RCC_CSR_RMVF_BIT 24
+ #define RCC_CSR_LSIRDY_BIT 1
+ #define RCC_CSR_LSION_BIT 0
+
+ #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
+ #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
+ #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
+ #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
+ #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
+ #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
+ #define RCC_CSR_BORRSTF (1U << RCC_CSR_BORRSTF_BIT)
+ #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
+ #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
+ #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
+
+Spread spectrum clock generation register
++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_SSCGR_SSCGEN_BIT 31
+ #define RCC_SSCGR_SPREADSEL_BIT 30
+
+ #define RCC_SSCGR_SSCGEN (1U << RCC_SSCGR_SSCGEN_BIT)
+ #define RCC_SSCGR_SPREADSEL (1U << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_SPREADSEL_CENTER (0x0 << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_SPREADSEL_DOWN (0x1 << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_INCSTEP (0xFFF << 16)
+ #define RCC_SSCGR_MODPER 0xFFFF
+
+PLLI2S configuration register
++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_PLLI2SCFGR_PLLI2SR (0x7 << 28)
+ #define RCC_PLLI2SCFGR_PLLI2SN (0x1FF << 6)
+
diff --git a/docs/source/libmaple/api/rcc.rst b/docs/source/libmaple/api/rcc.rst
new file mode 100644
index 0000000..ce58ec8
--- /dev/null
+++ b/docs/source/libmaple/api/rcc.rst
@@ -0,0 +1,360 @@
+.. highlight:: c
+.. _libmaple-rcc:
+
+``<libmaple/rcc.h>``
+====================
+
+Reset and Clock Control (RCC) support.
+
+The RCC is responsible for managing the MCU's various clocks. This
+includes the core clock SYSCLK, which determines the CPU clock
+frequency, as well as the clock lines that drive peripherals.
+
+Because of this, the available RCC functionality varies by target.
+There are a :ref:`variety of abstractions <libmaple-rcc-core-types>`
+in place to make managing this more convenient.
+
+.. contents:: Contents
+ :local:
+ :depth: 2
+
+.. _libmaple-rcc-core-types:
+
+Core Types
+----------
+
+The core abstractions in place are
+:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`,
+:ref:`rcc_clk <libmaple-rcc-rcc_clk>`,
+:ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`,
+:ref:`rcc_clk_domain <libmaple-rcc-rcc_clk_domain>`, and
+:ref:`rcc_prescaler <libmaple-rcc-rcc_prescaler>`.
+
+.. _libmaple-rcc-rcc_clk_id:
+
+Peripheral Identifiers: ``rcc_clk_id``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``rcc_clk_id`` is an enum used to identify peripherals. The RCC
+back-ends use them to look up a peripheral's bus and clock line, but
+they are also generally useful as unique identifiers for each
+peripheral. You can manage peripherals using their ``rcc_clk_id``\ s
+with :ref:`these functions <libmaple-rcc-clk-id-funcs>`.
+
+Peripherals which are common across targets have the same token
+(though not necessarily the same value) for their ``rcc_clk_id``
+across different targets. For example, the ``rcc_clk_id`` for the ADC1
+peripheral is always ``RCC_ADC1`` regardless of the target.
+Additionally, as explained in :ref:`libmaple-overview-devices`, each
+peripheral device type struct contains the ``rcc_clk_id`` for that
+peripheral in a ``clk_id`` field.
+
+The available ``rcc_clk_id``\ s on each supported target series are as
+follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk_id
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk_id
+
+.. _libmaple-rcc-rcc_sysclk_src:
+
+System Clock (SYSCLK) Sources: ``rcc_sysclk_src``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SYSCLK is the core system clock. It determines the CPU clock rate, and
+it's the base clock which is used to drive (most of) the peripherals
+on the STM32. ``rcc_sysclk_src`` is an enum for the possible SYSCLK
+sources. Switch the SYSCLK source with :ref:`rcc_switch_sysclk()
+<libmaple-rcc-rcc_switch_sysclk>`.
+
+.. doxygenenum:: rcc_sysclk_src
+
+As a special case, you can configure the PLL with a call to
+:ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>`.
+
+.. _libmaple-rcc-rcc_clk:
+
+System and Secondary Clock Sources: ``rcc_clk``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``rcc_clk`` type gives available system and secondary clock
+sources (e.g. HSI, HSE, LSE). As with :ref:`rcc_clk_id
+<libmaple-rcc-rcc_clk_id>`, clock sources which are common across
+targets have the same token, but not necessarily the same value, for
+their ``rcc_clk`` on each target. A variety of :ref:`clock management
+functions <libmaple-rcc-clk-funcs>` are available.
+
+Note that the inclusion of secondary clock sources, like LSI and LSE,
+makes ``rcc_clk`` different from the SYSCLK sources, which are managed
+using :ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`.
+
+The available ``rcc_clk``\ s for each supported target series are as
+follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk
+
+.. _libmaple-rcc-rcc_clk_domain:
+
+Clock Domains: ``rcc_clk_domain``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These specify the available clock domains. For example, each AHB and
+APB is a clock domain.
+
+This type mostly exists to enable asking devices what bus they're on,
+which, given knowledge of your system's clock configuration, can be
+useful when making decisions about prescalers, etc.
+
+Given an :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, you can get the
+peripheral's clock domain with :ref:`rcc_dev_clk()
+<libmaple-rcc-rcc_dev_clk>`. Clock domains that are common across
+series have the same token (but not necessarily the same value) for
+their corresponding ``rcc_clk_domain``.
+
+The available ``rcc_clk_domain``\ s for each supported target series
+are as follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk_domain
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk_domain
+
+.. _libmaple-rcc-rcc_prescaler:
+
+Prescalers: ``rcc_prescaler`` and Friends
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Available prescalers are managed via the ``rcc_prescaler`` type, the
+``rcc_set_prescaler()`` function, and a variety of related prescaler
+divider types. See :ref:`libmaple-rcc-prescalers` for more
+information and usage notes.
+
+Functions
+---------
+
+.. _libmaple-rcc-sysclk-funcs:
+.. _libmaple-rcc-rcc_switch_sysclk:
+
+SYSCLK Management
+~~~~~~~~~~~~~~~~~
+
+Change the SYSCLK source with ``rcc_switch_sysclk()``.
+
+.. doxygenfunction:: rcc_switch_sysclk
+
+.. _libmaple-rcc-rcc_configure_pll:
+
+PLL Configuration
+~~~~~~~~~~~~~~~~~
+
+You can configure the PLL with ``rcc_configure_pll()``. This takes an
+``rcc_pll_cfg`` struct as its argument. Though the definition of
+``rcc_pll_cfg`` is common across series, its contents are entirely
+target-dependent.
+
+.. doxygenstruct:: rcc_pll_cfg
+.. _rcc-rcc_configure_pll:
+.. doxygenfunction:: rcc_configure_pll
+
+The fields in an ``rcc_pll_cfg`` on each target are as follows.
+
+rcc_pll_cfg on STM32F1 Targets
+++++++++++++++++++++++++++++++
+
+The ``pllsrc`` field is chosen from the following.
+
+.. doxygenenum:: stm32f1::rcc_pllsrc
+
+.. FIXME [0.0.13] We've got plans to redo this; make sure you watch
+.. libmaple for changes here.
+
+The ``data`` field must point to a ``struct stm32f1_rcc_pll_data``.
+This just contains an ``rcc_pll_multiplier``.
+
+.. doxygenenum:: stm32f1::rcc_pll_multiplier
+
+.. doxygenstruct:: stm32f1::stm32f1_rcc_pll_data
+
+rcc_pll_cfg on STM32F2 Targets
+++++++++++++++++++++++++++++++
+
+The ``pllsrc`` field is chosen from the following.
+
+.. doxygenenum:: stm32f2::rcc_pllsrc
+
+The ``data`` field must point to a ``struct stm32f2_rcc_pll_data``.
+
+.. doxygenstruct:: stm32f2::stm32f2_rcc_pll_data
+
+.. _libmaple-rcc-clk-funcs:
+
+System and Secondary Clock Management
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These functions are useful for managing clocks via their :ref:`rcc_clk
+<libmaple-rcc-rcc_clk>`.
+
+.. doxygenfunction:: rcc_turn_on_clk
+.. doxygenfunction:: rcc_turn_off_clk
+.. doxygenfunction:: rcc_is_clk_on
+.. doxygenfunction:: rcc_is_clk_ready
+
+.. _libmaple-rcc-clk-id-funcs:
+
+Peripheral Management
+~~~~~~~~~~~~~~~~~~~~~
+
+These functions are useful for managing peripherals via their
+:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`.
+
+.. _libmaple-rcc-rcc_clk_enable:
+.. doxygenfunction:: rcc_clk_enable
+.. doxygenfunction:: rcc_reset_dev
+.. _libmaple-rcc-rcc_dev_clk:
+.. doxygenfunction:: rcc_dev_clk
+
+.. _libmaple-rcc-prescalers:
+
+Prescaler Management
+~~~~~~~~~~~~~~~~~~~~
+
+All clock prescalers managed by RCC can be controlled with a single
+function, ``rcc_set_prescaler()``.
+
+.. doxygenfunction:: rcc_set_prescaler
+
+The arguments to ``rcc_set_prescaler()`` are target-dependent, but
+follow a common pattern:
+
+- The first argument is the prescaler to set, so there's one for each
+ peripheral clock domain, etc. These have names like
+ ``RCC_PRESCALER_FOO``, e.g. ``RCC_PRESCALER_APB1``. Choose the
+ prescaler from the ``rcc_prescaler``\ s on your target (see below).
+
+- The second argument is the actual clock divider to use; it's chosen
+ based on the first argument. The dividers for ``RCC_PRESCALER_FOO``
+ are given by the type ``rcc_foo_divider``, and have values like
+ ``RCC_FOO_xxx_DIV_y``. This means that the foo clock will be the
+ ``xxx`` clock divided by ``y``.
+
+For example, calling ``rcc_set_prescaler(RCC_PRESCALER_APB1,
+RCC_APB1_HCLK_DIV_1)`` would set the APB1 clock to HCLK divided by 1.
+
+Prescalers which are common across targets have the same token, though
+not necessarily the same value, for their ``rcc_prescaler`` (for
+example, ``RCC_PRESCALER_APB1`` is available on both STM32F1 and
+STM32F2 targets). The available prescalers and dividers on each
+supported target series are as follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_prescaler
+.. doxygenenum:: stm32f1::rcc_adc_divider
+.. doxygenenum:: stm32f1::rcc_apb1_divider
+.. doxygenenum:: stm32f1::rcc_apb2_divider
+.. doxygenenum:: stm32f1::rcc_ahb_divider
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_prescaler
+.. doxygenenum:: stm32f2::rcc_mco2_divider
+.. doxygenenum:: stm32f2::rcc_mco1_divider
+.. doxygenenum:: stm32f2::rcc_rtc_divider
+.. doxygenenum:: stm32f2::rcc_apb2_divider
+.. doxygenenum:: stm32f2::rcc_apb1_divider
+.. doxygenenum:: stm32f2::rcc_ahb_divider
+
+Register Maps
+-------------
+
+These vary by target. The base pointer is always ``RCC_BASE``.
+
+.. doxygendefine:: RCC_BASE
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f1::rcc_reg_map
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f2::rcc_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code. Available register bit definitions
+vary by target.
+
+.. We need this include to avoid crashing Emacs's ReST parser. Yuck.
+
+.. include:: rcc-reg-bits.txt
+
+Deprecated Functionality
+------------------------
+
+.. _rcc-rcc_clk_init:
+.. doxygenfunction:: stm32f1::rcc_clk_init
+
+To replace a call to ``rcc_clk_init()`` in order to set SYSCLK to PLL
+driven by an external oscillator, you can use something like this,
+which is portable except for the initialization of ``your_pll_cfg``::
+
+ /* You need to make this point to something valid for your target; see
+ * the documentation for rcc_configure_pll() for more details. */
+ extern rcc_pll_cfg *your_pll_cfg;
+
+ void pll_reconfigure() {
+ /* Turn on HSI using rcc_turn_on_clk() and wait for it to
+ * become ready by busy-waiting on rcc_is_clk_ready().
+ *
+ * Switch to HSI to ensure we're not using the PLL while we
+ * reconfigure it. */
+ rcc_turn_on_clk(RCC_CLK_HSI);
+ while (!rcc_is_clk_ready(RCC_CLK_HSI))
+ ;
+ rcc_switch_sysclk(RCC_CLKSRC_HSI);
+
+ /* Turn off HSE and the PLL, or we can't reconfigure it. */
+ rcc_turn_off_clk(RCC_CLK_PLL);
+ rcc_turn_off_clk(RCC_CLK_HSE);
+
+ /* Reconfigure the PLL. You can also perform any other
+ * prescaler management here. */
+ rcc_configure_pll(your_pll_cfg);
+
+ /* Turn on RCC_CLK_HSE. */
+ rcc_turn_on_clk(RCC_CLK_HSE);
+ while (!rcc_is_clk_ready(RCC_CLK_HSE))
+ ;
+
+ /* Turn on RCC_CLK_PLL. */
+ rcc_turn_on_clk(RCC_CLK_PLL);
+ while (!rcc_is_clk_ready(RCC_CLK_PLL))
+ ;
+
+ /* Finally, switch to the PLL. */
+ rcc_switch_sysclk(RCC_CLKSRC_PLL);
+ }
diff --git a/docs/source/libmaple/api/ring_buffer.rst b/docs/source/libmaple/api/ring_buffer.rst
new file mode 100644
index 0000000..ef082dd
--- /dev/null
+++ b/docs/source/libmaple/api/ring_buffer.rst
@@ -0,0 +1,27 @@
+.. highlight:: c
+.. _libmaple-ring_buffer:
+
+``<libmaple/ring_buffer.h>``
+============================
+
+Simple circular byte buffer. This implementation is not thread-safe.
+In particular, none of these functions is guaranteed to be re-entrant.
+
+Ring Buffer Type
+----------------
+
+.. doxygenstruct:: ring_buffer
+
+Ring Buffer Operations
+----------------------
+
+.. doxygenfunction:: rb_init
+.. doxygenfunction:: rb_full_count
+.. doxygenfunction:: rb_is_full
+.. doxygenfunction:: rb_is_empty
+.. doxygenfunction:: rb_insert
+.. doxygenfunction:: rb_remove
+.. doxygenfunction:: rb_safe_remove
+.. doxygenfunction:: rb_safe_insert
+.. doxygenfunction:: rb_push_insert
+.. doxygenfunction:: rb_reset
diff --git a/docs/source/libmaple/api/scb.rst b/docs/source/libmaple/api/scb.rst
new file mode 100644
index 0000000..96d464f
--- /dev/null
+++ b/docs/source/libmaple/api/scb.rst
@@ -0,0 +1,156 @@
+.. highlight:: c
+.. _libmaple-scb:
+
+``<libmaple/scb.h>``
+====================
+
+.. TODO [0.0.13] check for any F2 modifications
+
+System Control Block (SCB) support. This is currently limited to a
+register map and bit definitions.
+
+.. warning::
+
+ At time of writing, ST PM0056 (which specifies the system control
+ block on STM32F1) appears to be buggy (some registers required or
+ specified as implementation-defined by ARM are not mentioned).
+ This file is the result of combining material from ARM and ST, and
+ is subject to change. See the source code for more details.
+
+ If you notice a problem or have any other input on this, please
+ `contact`_ us!
+
+.. contents:: Contents
+ :local:
+
+Register Maps
+-------------
+
+The SCB has the following register map. Its base pointer is ``SCB_BASE``.
+
+.. doxygenstruct:: scb_reg_map
+.. doxygendefine:: SCB_BASE
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* No SCB_REG_FIELD_BIT macros as the relevant addresses are not in a
+ * bit-band region. */
+
+ /* CPUID base register (SCB_CPUID) */
+
+ #define SCB_CPUID_IMPLEMENTER (0xFF << 24)
+ #define SCB_CPUID_VARIANT (0xF << 20)
+ #define SCB_CPUID_CONSTANT (0xF << 16)
+ #define SCB_CPUID_PARTNO (0xFFF << 4)
+ #define SCB_CPUID_REVISION 0xF
+
+ /* Interrupt control state register (SCB_ICSR) */
+
+ #define SCB_ICSR_NMIPENDSET (1U << 31)
+ #define SCB_ICSR_PENDSVSET (1U << 28)
+ #define SCB_ICSR_PENDSVCLR (1U << 27)
+ #define SCB_ICSR_PENDSTSET (1U << 26)
+ #define SCB_ICSR_PENDSTCLR (1U << 25)
+ #define SCB_ICSR_ISRPENDING (1U << 22)
+ #define SCB_ICSR_VECTPENDING (0x3FF << 12)
+ #define SCB_ICSR_RETOBASE (1U << 11)
+ #define SCB_ICSR_VECTACTIVE 0xFF
+
+ /* Vector table offset register (SCB_VTOR) */
+
+ #define SCB_VTOR_TBLOFF (0x1FFFFF << 9)
+
+ /* Application interrupt and reset control register (SCB_AIRCR) */
+
+ #define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16)
+ #define SCB_AIRCR_VECTKEY (0x5FA << 16)
+ #define SCB_AIRCR_ENDIANNESS (1U << 15)
+ #define SCB_AIRCR_PRIGROUP (0x3 << 8)
+ #define SCB_AIRCR_SYSRESETREQ (1U << 2)
+ #define SCB_AIRCR_VECTCLRACTIVE (1U << 1)
+ #define SCB_AIRCR_VECTRESET (1U << 0)
+
+ /* System control register (SCB_SCR) */
+
+ #define SCB_SCR_SEVONPEND (1U << 4)
+ #define SCB_SCR_SLEEPDEEP (1U << 2)
+ #define SCB_SCR_SLEEPONEXIT (1U << 1)
+
+ /* Configuration and Control Register (SCB_CCR) */
+
+ #define SCB_CCR_STKALIGN (1U << 9)
+ #define SCB_CCR_BFHFNMIGN (1U << 8)
+ #define SCB_CCR_DIV_0_TRP (1U << 4)
+ #define SCB_CCR_UNALIGN_TRP (1U << 3)
+ #define SCB_CCR_USERSETMPEND (1U << 1)
+ #define SCB_CCR_NONBASETHRDENA (1U << 0)
+
+ /* System handler priority registers (SCB_SHPRx) */
+
+ #define SCB_SHPR1_PRI6 (0xFF << 16)
+ #define SCB_SHPR1_PRI5 (0xFF << 8)
+ #define SCB_SHPR1_PRI4 0xFF
+
+ #define SCB_SHPR2_PRI11 (0xFF << 24)
+
+ #define SCB_SHPR3_PRI15 (0xFF << 24)
+ #define SCB_SHPR3_PRI14 (0xFF << 16)
+
+ /* System Handler Control and state register (SCB_SHCSR) */
+
+ #define SCB_SHCSR_USGFAULTENA (1U << 18)
+ #define SCB_SHCSR_BUSFAULTENA (1U << 17)
+ #define SCB_SHCSR_MEMFAULTENA (1U << 16)
+ #define SCB_SHCSR_SVCALLPENDED (1U << 15)
+ #define SCB_SHCSR_BUSFAULTPENDED (1U << 14)
+ #define SCB_SHCSR_MEMFAULTPENDED (1U << 13)
+ #define SCB_SHCSR_USGFAULTPENDED (1U << 12)
+ #define SCB_SHCSR_SYSTICKACT (1U << 11)
+ #define SCB_SHCSR_PENDSVACT (1U << 10)
+ #define SCB_SHCSR_MONITORACT (1U << 8)
+ #define SCB_SHCSR_SVCALLACT (1U << 7)
+ #define SCB_SHCSR_USGFAULTACT (1U << 3)
+ #define SCB_SHCSR_BUSFAULTACT (1U << 1)
+ #define SCB_SHCSR_MEMFAULTACT (1U << 0)
+
+ /* Configurable fault status register (SCB_CFSR) */
+
+ #define SCB_CFSR_DIVBYZERO (1U << 25)
+ #define SCB_CFSR_UNALIGNED (1U << 24)
+ #define SCB_CFSR_NOCP (1U << 19)
+ #define SCB_CFSR_INVPC (1U << 18)
+ #define SCB_CFSR_INVSTATE (1U << 17)
+ #define SCB_CFSR_UNDEFINSTR (1U << 16)
+ #define SCB_CFSR_BFARVALID (1U << 15)
+ #define SCB_CFSR_STKERR (1U << 12)
+ #define SCB_CFSR_UNSTKERR (1U << 11)
+ #define SCB_CFSR_IMPRECISERR (1U << 10)
+ #define SCB_CFSR_PRECISERR (1U << 9)
+ #define SCB_CFSR_IBUSERR (1U << 8)
+ #define SCB_CFSR_MMARVALID (1U << 7)
+ #define SCB_CFSR_MSTKERR (1U << 4)
+ #define SCB_CFSR_MUNSTKERR (1U << 3)
+ #define SCB_CFSR_DACCVIOL (1U << 1)
+ #define SCB_CFSR_IACCVIOL (1U << 0)
+
+ /* Hard Fault Status Register (SCB_HFSR) */
+
+ #define SCB_HFSR_DEBUG_VT (1U << 31)
+ #define SCB_CFSR_FORCED (1U << 30)
+ #define SCB_CFSR_VECTTBL (1U << 1)
+
+ /* Debug Fault Status Register */
+
+ /* Not specified by PM0056, but required by ARM. The bit definitions
+ * here are based on the names given in the ARM v7-M ARM. */
+
+ #define SCB_DFSR_EXTERNAL (1U << 4)
+ #define SCB_DFSR_VCATCH (1U << 3)
+ #define SCB_DFSR_DWTTRAP (1U << 2)
+ #define SCB_DFSR_BKPT (1U << 1)
+ #define SCB_DFSR_HALTED (1U << 0)
diff --git a/docs/source/libmaple/api/spi.rst b/docs/source/libmaple/api/spi.rst
new file mode 100644
index 0000000..e72696b
--- /dev/null
+++ b/docs/source/libmaple/api/spi.rst
@@ -0,0 +1,187 @@
+.. highlight:: c
+.. _libmaple-spi:
+
+``spi.h``
+=========
+
+Serial Peripheral Interface (SPI) support. Currently, there is no I2S
+support beyond register bit definitions.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: spi_reg_map
+.. doxygenstruct:: spi_dev
+.. doxygenenum:: spi_mode
+.. doxygenenum:: spi_baud_rate
+.. doxygenenum:: spi_cfg_flag
+.. doxygenenum:: spi_interrupt
+
+Devices
+-------
+
+.. doxygenvariable:: SPI1
+.. doxygenvariable:: SPI2
+.. doxygenvariable:: SPI3
+
+Functions
+---------
+
+.. doxygenfunction:: spi_init
+.. doxygenfunction:: spi_gpio_cfg
+.. doxygenfunction:: spi_master_enable
+.. doxygenfunction:: spi_slave_enable
+.. doxygenfunction:: spi_tx
+.. doxygenfunction:: spi_foreach
+.. doxygenfunction:: spi_peripheral_enable
+.. doxygenfunction:: spi_peripheral_disable
+.. doxygenfunction:: spi_peripheral_disable_all
+.. doxygenfunction:: spi_tx_dma_enable
+.. doxygenfunction:: spi_tx_dma_disable
+.. doxygenfunction:: spi_rx_dma_enable
+.. doxygenfunction:: spi_rx_dma_disable
+.. doxygenfunction:: spi_is_enabled
+.. doxygenfunction:: spi_irq_enable
+.. doxygenfunction:: spi_irq_disable
+.. doxygenfunction:: spi_dff
+.. doxygenfunction:: spi_is_rx_nonempty
+.. doxygenfunction:: spi_rx_reg
+.. doxygenfunction:: spi_is_tx_empty
+.. doxygenfunction:: spi_tx_reg
+.. doxygenfunction:: spi_is_busy
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: SPI1_BASE
+.. doxygendefine:: SPI2_BASE
+.. doxygendefine:: SPI3_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_CR1_BIDIMODE_BIT
+.. doxygendefine:: SPI_CR1_BIDIOE_BIT
+.. doxygendefine:: SPI_CR1_CRCEN_BIT
+.. doxygendefine:: SPI_CR1_CRCNEXT_BIT
+.. doxygendefine:: SPI_CR1_DFF_BIT
+.. doxygendefine:: SPI_CR1_RXONLY_BIT
+.. doxygendefine:: SPI_CR1_SSM_BIT
+.. doxygendefine:: SPI_CR1_SSI_BIT
+.. doxygendefine:: SPI_CR1_LSBFIRST_BIT
+.. doxygendefine:: SPI_CR1_SPE_BIT
+.. doxygendefine:: SPI_CR1_MSTR_BIT
+.. doxygendefine:: SPI_CR1_CPOL_BIT
+.. doxygendefine:: SPI_CR1_CPHA_BIT
+
+.. doxygendefine:: SPI_CR1_BIDIMODE
+.. doxygendefine:: SPI_CR1_BIDIMODE_2_LINE
+.. doxygendefine:: SPI_CR1_BIDIMODE_1_LINE
+.. doxygendefine:: SPI_CR1_BIDIOE
+.. doxygendefine:: SPI_CR1_CRCEN
+.. doxygendefine:: SPI_CR1_CRCNEXT
+.. doxygendefine:: SPI_CR1_DFF
+.. doxygendefine:: SPI_CR1_DFF_8_BIT
+.. doxygendefine:: SPI_CR1_DFF_16_BIT
+.. doxygendefine:: SPI_CR1_RXONLY
+.. doxygendefine:: SPI_CR1_SSM
+.. doxygendefine:: SPI_CR1_SSI
+.. doxygendefine:: SPI_CR1_LSBFIRST
+.. doxygendefine:: SPI_CR1_SPE
+.. doxygendefine:: SPI_CR1_BR
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_2
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_4
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_8
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_16
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_32
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_64
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_128
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_256
+.. doxygendefine:: SPI_CR1_MSTR
+.. doxygendefine:: SPI_CR1_CPOL
+.. doxygendefine:: SPI_CR1_CPOL_LOW
+.. doxygendefine:: SPI_CR1_CPOL_HIGH
+.. doxygendefine:: SPI_CR1_CPHA
+
+Control register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_CR2_TXEIE_BIT
+.. doxygendefine:: SPI_CR2_RXNEIE_BIT
+.. doxygendefine:: SPI_CR2_ERRIE_BIT
+.. doxygendefine:: SPI_CR2_SSOE_BIT
+.. doxygendefine:: SPI_CR2_TXDMAEN_BIT
+.. doxygendefine:: SPI_CR2_RXDMAEN_BIT
+
+.. doxygendefine:: SPI_CR2_TXEIE
+.. doxygendefine:: SPI_CR2_RXNEIE
+.. doxygendefine:: SPI_CR2_ERRIE
+.. doxygendefine:: SPI_CR2_SSOE
+.. doxygendefine:: SPI_CR2_TXDMAEN
+.. doxygendefine:: SPI_CR2_RXDMAEN
+
+Status register
+~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_SR_BSY_BIT
+.. doxygendefine:: SPI_SR_OVR_BIT
+.. doxygendefine:: SPI_SR_MODF_BIT
+.. doxygendefine:: SPI_SR_CRCERR_BIT
+.. doxygendefine:: SPI_SR_UDR_BIT
+.. doxygendefine:: SPI_SR_CHSIDE_BIT
+.. doxygendefine:: SPI_SR_TXE_BIT
+.. doxygendefine:: SPI_SR_RXNE_BIT
+
+.. doxygendefine:: SPI_SR_BSY
+.. doxygendefine:: SPI_SR_OVR
+.. doxygendefine:: SPI_SR_MODF
+.. doxygendefine:: SPI_SR_CRCERR
+.. doxygendefine:: SPI_SR_UDR
+.. doxygendefine:: SPI_SR_CHSIDE
+.. doxygendefine:: SPI_SR_CHSIDE_LEFT
+.. doxygendefine:: SPI_SR_CHSIDE_RIGHT
+.. doxygendefine:: SPI_SR_TXE
+.. doxygendefine:: SPI_SR_RXNE
+
+I2S configuration register
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_BIT
+.. doxygendefine:: SPI_I2SCFGR_I2SE_BIT
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_BIT
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_BIT
+
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_SPI
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_I2S
+.. doxygendefine:: SPI_I2SCFGR_I2SE
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_TX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_RX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_TX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_RX
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_SHORT
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_LONG
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PHILLIPS
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_MSB
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_LSB
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PCM
+.. doxygendefine:: SPI_I2SCFGR_CKPOL
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_LOW
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_HIGH
+.. doxygendefine:: SPI_I2SCFGR_DATLEN
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_16_BIT
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_24_BIT
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_32_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_16_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_32_BIT
diff --git a/docs/source/libmaple/api/stm32.rst b/docs/source/libmaple/api/stm32.rst
new file mode 100644
index 0000000..335bda4
--- /dev/null
+++ b/docs/source/libmaple/api/stm32.rst
@@ -0,0 +1,121 @@
+.. highlight:: c
+.. _libmaple-stm32:
+
+``<libmaple/stm32.h>``
+======================
+
+STM32 chip header. This header supplies various series-specific and
+chip-specific macros for the current build target. It's useful both
+to abstract away hardware details (e.g. through use of
+:ref:`STM32_NR_INTERRUPTS <libmaple-stm32-STM32_NR_INTERRUPTS>`) and
+to decide what to do when you want something nonportable (e.g. by
+checking :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>`).
+
+.. contents:: Contents
+ :local:
+
+Determining the Target Series
+-----------------------------
+
+The STM32 series (e.g. STM32F1, STM32F2, etc.) of the current target
+can be inspected with ``STM32_MCU_SERIES``.
+
+.. _libmaple-stm32-STM32_MCU_SERIES:
+.. doxygendefine:: STM32_MCU_SERIES
+
+Allowed values for ``STM32_MCU_SERIES`` are the following. This set is
+expected to grow over time.
+
+.. doxygendefine:: STM32_SERIES_F1
+.. doxygendefine:: STM32_SERIES_F2
+.. doxygendefine:: STM32_SERIES_L1
+.. doxygendefine:: STM32_SERIES_F4
+
+Series-Specific Characteristics
+-------------------------------
+
+The macros in this section are only available on some STM32 series.
+
+STM32F1
+~~~~~~~
+
+.. note:: These macros are only available when the current target is
+ an STM32F1 series MCU (i.e., when :ref:`STM32_MCU_SERIES
+ <libmaple-stm32-STM32_MCU_SERIES>` is ``STM32_SERIES_F1``).
+
+The STM32F1 series is further subdivided into :ref:`lines
+<stm32-series-f1-lines>`. The line of the current target can be
+inspected with ``STM32_F1_LINE``.
+
+.. doxygendefine:: STM32_F1_LINE
+
+There are five STM32F1 lines. The corresponding values
+``STM32_F1_LINE`` can take are the following, though libmaple doesn't
+currently support all of them.
+
+.. doxygendefine:: STM32_F1_LINE_VALUE
+.. doxygendefine:: STM32_F1_LINE_ACCESS
+.. doxygendefine:: STM32_F1_LINE_USB_ACCESS
+.. doxygendefine:: STM32_F1_LINE_PERFORMANCE
+.. doxygendefine:: STM32_F1_LINE_CONNECTIVITY
+
+MCU Feature Tests
+-----------------
+
+The following defines can be used to determine if the target MCU has
+a particular feature.
+
+.. _libmaple-stm32-STM32_HAVE_FSMC:
+.. doxygendefine:: STM32_HAVE_FSMC
+.. doxygendefine:: STM32_HAVE_USB
+
+MCU Characteristics
+-------------------
+
+The following defines give salient characteristics of the target MCU.
+
+.. doxygendefine:: STM32_NR_GPIO_PORTS
+.. _libmaple-stm32-STM32_NR_INTERRUPTS:
+.. doxygendefine:: STM32_NR_INTERRUPTS
+.. doxygendefine:: STM32_SRAM_END
+
+Clock Speeds
+------------
+
+The macros in this section are related to clock rates. As such, they
+are really part of the configuration of the MCU, rather than inherent
+characteristics of the MCU itself. For instance, it's possible to
+change the PCLK1 and PCLK2 clock rates by reconfiguring the :ref:`RCC
+<libmaple-rcc>`. libmaple proper never changes any clock rates, but it
+does have APIs for doing so (such as :ref:`rcc_configure_pll()
+<libmaple-rcc-rcc_configure_pll>`). Because of this, be careful when
+using the macros in this section, as they assume that some values are
+constant which in fact may be changed.
+
+The values these macros actually take are typically the maximum values
+supported by the MCU. Since these are their actual values in practice
+(at least in LeafLabs' current use cases, which have the chips running
+as fast as possible), they're still considered useful.
+
+.. doxygendefine:: STM32_PCLK1
+.. doxygendefine:: STM32_PCLK2
+
+The following macro, ``STM32_DELAY_US_MULT``, is a libmaple
+implementation detail. It was included in this public API page in a
+previous release by mistake, and is not deprecated, but using it in
+your own code is a bad idea.
+
+.. doxygendefine:: STM32_DELAY_US_MULT
+
+Deprecated Macros
+-----------------
+
+.. warning:: The macros in this section are deprecated, and are
+ available for backwards compatibility only. Do not use
+ them in new code.
+
+.. doxygendefine:: PCLK1
+.. doxygendefine:: PCLK2
+.. doxygendefine:: NR_INTERRUPTS
+.. doxygendefine:: NR_GPIO_PORTS
+.. doxygendefine:: DELAY_US_MULT
diff --git a/docs/source/libmaple/api/systick.rst b/docs/source/libmaple/api/systick.rst
new file mode 100644
index 0000000..45b6d63
--- /dev/null
+++ b/docs/source/libmaple/api/systick.rst
@@ -0,0 +1,62 @@
+.. highlight:: c
+
+.. _libmaple-systick:
+
+``systick.h``
+=============
+
+System timer (SysTick) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: systick_reg_map
+
+Devices
+-------
+
+None.
+
+Functions
+---------
+
+.. doxygenfunction:: systick_init
+.. _libmaple-systick-enable:
+.. doxygenfunction:: systick_enable
+.. _libmaple-systick-disable:
+.. doxygenfunction:: systick_disable
+.. doxygenfunction:: systick_uptime
+.. doxygenfunction:: systick_get_count
+.. doxygenfunction:: systick_check_underflow
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: SYSTICK_BASE
+
+Register Bit Definitions
+------------------------
+
+Control and status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SYSTICK_CSR_COUNTFLAG
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_EXTERNAL
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_CORE
+.. doxygendefine:: SYSTICK_CSR_TICKINT
+.. doxygendefine:: SYSTICK_CSR_TICKINT_PEND
+.. doxygendefine:: SYSTICK_CSR_TICKINT_NO_PEND
+.. doxygendefine:: SYSTICK_CSR_ENABLE
+.. doxygendefine:: SYSTICK_CSR_ENABLE_MULTISHOT
+.. doxygendefine:: SYSTICK_CSR_ENABLE_DISABLED
+
+Calibration value register
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SYSTICK_CVR_NOREF
+.. doxygendefine:: SYSTICK_CVR_SKEW
+.. doxygendefine:: SYSTICK_CVR_TENMS
diff --git a/docs/source/libmaple/api/timer.rst b/docs/source/libmaple/api/timer.rst
new file mode 100644
index 0000000..f315cb0
--- /dev/null
+++ b/docs/source/libmaple/api/timer.rst
@@ -0,0 +1,453 @@
+.. highlight:: c
+.. _libmaple-timer:
+
+``timer.h``
+===========
+
+Timer support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+The timer register map type, unlike that for most other peripherals in
+libmaple, is a union rather than a struct. This is due to the fact
+that there are advanced, general purpose, and basic timers. Thus,
+each kind of timer has a register map type, and a ``union
+timer_reg_map`` ties it all together.
+
+.. doxygenstruct:: timer_adv_reg_map
+.. doxygenstruct:: timer_gen_reg_map
+.. doxygenstruct:: timer_bas_reg_map
+.. doxygenunion:: timer_reg_map
+.. doxygenenum:: timer_type
+.. doxygenstruct:: timer_dev
+.. doxygenenum:: timer_mode
+.. doxygenenum:: timer_channel
+.. doxygenenum:: timer_interrupt_id
+.. doxygenenum:: timer_dma_base_addr
+.. doxygenenum:: timer_oc_mode
+.. doxygenenum:: timer_oc_mode_flags
+
+Devices
+-------
+
+.. doxygenvariable:: TIMER1
+.. doxygenvariable:: TIMER2
+.. doxygenvariable:: TIMER3
+.. doxygenvariable:: TIMER4
+.. doxygenvariable:: TIMER5
+.. doxygenvariable:: TIMER6
+.. doxygenvariable:: TIMER7
+.. doxygenvariable:: TIMER8
+
+Functions
+---------
+
+Enabling and Disabling
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_init
+.. doxygenfunction:: timer_init_all
+.. doxygenfunction:: timer_disable
+.. doxygenfunction:: timer_disable_all
+
+General Configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_set_mode
+.. doxygenfunction:: timer_foreach
+
+Count and Prescaler
+~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_get_count
+.. doxygenfunction:: timer_set_count
+.. doxygenfunction:: timer_pause
+.. doxygenfunction:: timer_resume
+.. doxygenfunction:: timer_generate_update
+.. doxygenfunction:: timer_get_prescaler
+.. doxygenfunction:: timer_set_prescaler
+.. doxygenfunction:: timer_get_reload
+.. doxygenfunction:: timer_set_reload
+
+Interrupts
+~~~~~~~~~~
+
+.. doxygenfunction:: timer_attach_interrupt
+.. doxygenfunction:: timer_detach_interrupt
+.. doxygenfunction:: timer_enable_irq
+.. doxygenfunction:: timer_disable_irq
+
+Capture/Compare
+~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_get_compare
+.. doxygenfunction:: timer_set_compare
+.. doxygenfunction:: timer_cc_enable
+.. doxygenfunction:: timer_cc_disable
+.. doxygenfunction:: timer_cc_get_pol
+.. doxygenfunction:: timer_cc_set_pol
+.. doxygenfunction:: timer_oc_set_mode
+
+DMA
+~~~
+
+.. doxygenfunction:: timer_dma_enable_trg_req
+.. doxygenfunction:: timer_dma_disable_trg_req
+.. doxygenfunction:: timer_dma_enable_req
+.. doxygenfunction:: timer_dma_get_burst_len
+.. doxygenfunction:: timer_dma_set_burst_len
+.. doxygenfunction:: timer_dma_get_base_addr
+.. doxygenfunction:: timer_dma_set_base_addr
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: TIMER1_BASE
+.. doxygendefine:: TIMER2_BASE
+.. doxygendefine:: TIMER3_BASE
+.. doxygendefine:: TIMER4_BASE
+.. doxygendefine:: TIMER5_BASE
+.. doxygendefine:: TIMER6_BASE
+.. doxygendefine:: TIMER7_BASE
+.. doxygendefine:: TIMER8_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1 (CR1)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CR1_ARPE_BIT
+.. doxygendefine:: TIMER_CR1_DIR_BIT
+.. doxygendefine:: TIMER_CR1_OPM_BIT
+.. doxygendefine:: TIMER_CR1_URS_BIT
+.. doxygendefine:: TIMER_CR1_UDIS_BIT
+.. doxygendefine:: TIMER_CR1_CEN_BIT
+
+.. doxygendefine:: TIMER_CR1_CKD
+.. doxygendefine:: TIMER_CR1_CKD_1TCKINT
+.. doxygendefine:: TIMER_CR1_CKD_2TCKINT
+.. doxygendefine:: TIMER_CR1_CKD_4TICKINT
+.. doxygendefine:: TIMER_CR1_ARPE
+.. doxygendefine:: TIMER_CR1_CKD_CMS
+.. doxygendefine:: TIMER_CR1_CKD_CMS_EDGE
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER1
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER2
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER3
+.. doxygendefine:: TIMER_CR1_DIR
+.. doxygendefine:: TIMER_CR1_OPM
+.. doxygendefine:: TIMER_CR1_URS
+.. doxygendefine:: TIMER_CR1_UDIS
+.. doxygendefine:: TIMER_CR1_CEN
+
+Control register 2 (CR2)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CR2_OIS4_BIT
+.. doxygendefine:: TIMER_CR2_OIS3N_BIT
+.. doxygendefine:: TIMER_CR2_OIS3_BIT
+.. doxygendefine:: TIMER_CR2_OIS2N_BIT
+.. doxygendefine:: TIMER_CR2_OIS2_BIT
+.. doxygendefine:: TIMER_CR2_OIS1N_BIT
+.. doxygendefine:: TIMER_CR2_OIS1_BIT
+.. doxygendefine:: TIMER_CR2_TI1S_BIT
+.. doxygendefine:: TIMER_CR2_CCDS_BIT
+.. doxygendefine:: TIMER_CR2_CCUS_BIT
+.. doxygendefine:: TIMER_CR2_CCPC_BIT
+
+.. doxygendefine:: TIMER_CR2_OIS4
+.. doxygendefine:: TIMER_CR2_OIS3N
+.. doxygendefine:: TIMER_CR2_OIS3
+.. doxygendefine:: TIMER_CR2_OIS2N
+.. doxygendefine:: TIMER_CR2_OIS2
+.. doxygendefine:: TIMER_CR2_OIS1N
+.. doxygendefine:: TIMER_CR2_OIS1
+.. doxygendefine:: TIMER_CR2_TI1S
+.. doxygendefine:: TIMER_CR2_MMS
+.. doxygendefine:: TIMER_CR2_MMS_RESET
+.. doxygendefine:: TIMER_CR2_MMS_ENABLE
+.. doxygendefine:: TIMER_CR2_MMS_UPDATE
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_PULSE
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC1REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC2REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC3REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC4REF
+.. doxygendefine:: TIMER_CR2_CCDS
+.. doxygendefine:: TIMER_CR2_CCUS
+.. doxygendefine:: TIMER_CR2_CCPC
+
+Slave mode control register (SMCR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_SMCR_ETP_BIT
+.. doxygendefine:: TIMER_SMCR_ECE_BIT
+.. doxygendefine:: TIMER_SMCR_MSM_BIT
+
+.. doxygendefine:: TIMER_SMCR_ETP
+.. doxygendefine:: TIMER_SMCR_ECE
+.. doxygendefine:: TIMER_SMCR_ETPS
+.. doxygendefine:: TIMER_SMCR_ETPS_OFF
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV2
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV4
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV8
+.. doxygendefine:: TIMER_SMCR_ETF
+.. doxygendefine:: TIMER_SMCR_MSM
+.. doxygendefine:: TIMER_SMCR_TS
+.. doxygendefine:: TIMER_SMCR_TS_ITR0
+.. doxygendefine:: TIMER_SMCR_TS_ITR1
+.. doxygendefine:: TIMER_SMCR_TS_ITR2
+.. doxygendefine:: TIMER_SMCR_TS_ITR3
+.. doxygendefine:: TIMER_SMCR_TS_TI1F_ED
+.. doxygendefine:: TIMER_SMCR_TS_TI1FP1
+.. doxygendefine:: TIMER_SMCR_TS_TI2FP2
+.. doxygendefine:: TIMER_SMCR_TS_ETRF
+.. doxygendefine:: TIMER_SMCR_SMS
+.. doxygendefine:: TIMER_SMCR_SMS_DISABLED
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER1
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER2
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER3
+.. doxygendefine:: TIMER_SMCR_SMS_RESET
+.. doxygendefine:: TIMER_SMCR_SMS_GATED
+.. doxygendefine:: TIMER_SMCR_SMS_TRIGGER
+.. doxygendefine:: TIMER_SMCR_SMS_EXTERNAL
+
+DMA/Interrupt enable register (DIER)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_DIER_TDE_BIT
+.. doxygendefine:: TIMER_DIER_CC4DE_BIT
+.. doxygendefine:: TIMER_DIER_CC3DE_BIT
+.. doxygendefine:: TIMER_DIER_CC2DE_BIT
+.. doxygendefine:: TIMER_DIER_CC1DE_BIT
+.. doxygendefine:: TIMER_DIER_UDE_BIT
+.. doxygendefine:: TIMER_DIER_TIE_BIT
+.. doxygendefine:: TIMER_DIER_CC4IE_BIT
+.. doxygendefine:: TIMER_DIER_CC3IE_BIT
+.. doxygendefine:: TIMER_DIER_CC2IE_BIT
+.. doxygendefine:: TIMER_DIER_CC1IE_BIT
+.. doxygendefine:: TIMER_DIER_UIE_BIT
+
+.. doxygendefine:: TIMER_DIER_TDE
+.. doxygendefine:: TIMER_DIER_CC4DE
+.. doxygendefine:: TIMER_DIER_CC3DE
+.. doxygendefine:: TIMER_DIER_CC2DE
+.. doxygendefine:: TIMER_DIER_CC1DE
+.. doxygendefine:: TIMER_DIER_UDE
+.. doxygendefine:: TIMER_DIER_TIE
+.. doxygendefine:: TIMER_DIER_CC4IE
+.. doxygendefine:: TIMER_DIER_CC3IE
+.. doxygendefine:: TIMER_DIER_CC2IE
+.. doxygendefine:: TIMER_DIER_CC1IE
+.. doxygendefine:: TIMER_DIER_UIE
+
+Status register (SR)
+~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_SR_CC4OF_BIT
+.. doxygendefine:: TIMER_SR_CC3OF_BIT
+.. doxygendefine:: TIMER_SR_CC2OF_BIT
+.. doxygendefine:: TIMER_SR_CC1OF_BIT
+.. doxygendefine:: TIMER_SR_BIF_BIT
+.. doxygendefine:: TIMER_SR_TIF_BIT
+.. doxygendefine:: TIMER_SR_COMIF_BIT
+.. doxygendefine:: TIMER_SR_CC4IF_BIT
+.. doxygendefine:: TIMER_SR_CC3IF_BIT
+.. doxygendefine:: TIMER_SR_CC2IF_BIT
+.. doxygendefine:: TIMER_SR_CC1IF_BIT
+.. doxygendefine:: TIMER_SR_UIF_BIT
+
+.. doxygendefine:: TIMER_SR_CC4OF
+.. doxygendefine:: TIMER_SR_CC3OF
+.. doxygendefine:: TIMER_SR_CC2OF
+.. doxygendefine:: TIMER_SR_CC1OF
+.. doxygendefine:: TIMER_SR_BIF
+.. doxygendefine:: TIMER_SR_TIF
+.. doxygendefine:: TIMER_SR_COMIF
+.. doxygendefine:: TIMER_SR_CC4IF
+.. doxygendefine:: TIMER_SR_CC3IF
+.. doxygendefine:: TIMER_SR_CC2IF
+.. doxygendefine:: TIMER_SR_CC1IF
+.. doxygendefine:: TIMER_SR_UIF
+
+Event generation register (EGR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_EGR_TG_BIT
+.. doxygendefine:: TIMER_EGR_CC4G_BIT
+.. doxygendefine:: TIMER_EGR_CC3G_BIT
+.. doxygendefine:: TIMER_EGR_CC2G_BIT
+.. doxygendefine:: TIMER_EGR_CC1G_BIT
+.. doxygendefine:: TIMER_EGR_UG_BIT
+
+.. doxygendefine:: TIMER_EGR_TG
+.. doxygendefine:: TIMER_EGR_CC4G
+.. doxygendefine:: TIMER_EGR_CC3G
+.. doxygendefine:: TIMER_EGR_CC2G
+.. doxygendefine:: TIMER_EGR_CC1G
+.. doxygendefine:: TIMER_EGR_UG
+
+Capture/compare mode registers, common values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR_CCS_OUTPUT
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TRC
+
+Capture/compare mode register 1 (CCMR1)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR1_OC2CE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC2PE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC2FE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1CE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1PE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1FE_BIT
+
+.. doxygendefine:: TIMER_CCMR1_OC2CE
+.. doxygendefine:: TIMER_CCMR1_OC2M
+.. doxygendefine:: TIMER_CCMR1_IC2F
+.. doxygendefine:: TIMER_CCMR1_OC2PE
+.. doxygendefine:: TIMER_CCMR1_OC2FE
+.. doxygendefine:: TIMER_CCMR1_IC2PSC
+.. doxygendefine:: TIMER_CCMR1_CC2S
+.. doxygendefine:: TIMER_CCMR1_CC2S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TRC
+.. doxygendefine:: TIMER_CCMR1_OC1CE
+.. doxygendefine:: TIMER_CCMR1_OC1M
+.. doxygendefine:: TIMER_CCMR1_IC1F
+.. doxygendefine:: TIMER_CCMR1_OC1PE
+.. doxygendefine:: TIMER_CCMR1_OC1FE
+.. doxygendefine:: TIMER_CCMR1_IC1PSC
+.. doxygendefine:: TIMER_CCMR1_CC1S
+.. doxygendefine:: TIMER_CCMR1_CC1S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TRC
+
+Capture/compare mode register 2 (CCMR2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR2_OC4CE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC4PE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC4FE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3CE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3PE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3FE_BIT
+
+.. doxygendefine:: TIMER_CCMR2_OC4CE
+.. doxygendefine:: TIMER_CCMR2_OC4M
+.. doxygendefine:: TIMER_CCMR2_IC2F
+.. doxygendefine:: TIMER_CCMR2_OC4PE
+.. doxygendefine:: TIMER_CCMR2_OC4FE
+.. doxygendefine:: TIMER_CCMR2_IC2PSC
+.. doxygendefine:: TIMER_CCMR2_CC4S
+.. doxygendefine:: TIMER_CCMR1_CC4S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TRC
+.. doxygendefine:: TIMER_CCMR2_OC3CE
+.. doxygendefine:: TIMER_CCMR2_OC3M
+.. doxygendefine:: TIMER_CCMR2_IC1F
+.. doxygendefine:: TIMER_CCMR2_OC3PE
+.. doxygendefine:: TIMER_CCMR2_OC3FE
+.. doxygendefine:: TIMER_CCMR2_IC1PSC
+.. doxygendefine:: TIMER_CCMR2_CC3S
+.. doxygendefine:: TIMER_CCMR1_CC3S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TRC
+
+Capture/compare enable register (CCER)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCER_CC4P_BIT
+.. doxygendefine:: TIMER_CCER_CC4E_BIT
+.. doxygendefine:: TIMER_CCER_CC3P_BIT
+.. doxygendefine:: TIMER_CCER_CC3E_BIT
+.. doxygendefine:: TIMER_CCER_CC2P_BIT
+.. doxygendefine:: TIMER_CCER_CC2E_BIT
+.. doxygendefine:: TIMER_CCER_CC1P_BIT
+.. doxygendefine:: TIMER_CCER_CC1E_BIT
+
+.. doxygendefine:: TIMER_CCER_CC4P
+.. doxygendefine:: TIMER_CCER_CC4E
+.. doxygendefine:: TIMER_CCER_CC3P
+.. doxygendefine:: TIMER_CCER_CC3E
+.. doxygendefine:: TIMER_CCER_CC2P
+.. doxygendefine:: TIMER_CCER_CC2E
+.. doxygendefine:: TIMER_CCER_CC1P
+.. doxygendefine:: TIMER_CCER_CC1E
+
+Break and dead-time register (BDTR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_BDTR_MOE_BIT
+.. doxygendefine:: TIMER_BDTR_AOE_BIT
+.. doxygendefine:: TIMER_BDTR_BKP_BIT
+.. doxygendefine:: TIMER_BDTR_BKE_BIT
+.. doxygendefine:: TIMER_BDTR_OSSR_BIT
+.. doxygendefine:: TIMER_BDTR_OSSI_BIT
+
+.. doxygendefine:: TIMER_BDTR_MOE
+.. doxygendefine:: TIMER_BDTR_AOE
+.. doxygendefine:: TIMER_BDTR_BKP
+.. doxygendefine:: TIMER_BDTR_BKE
+.. doxygendefine:: TIMER_BDTR_OSSR
+.. doxygendefine:: TIMER_BDTR_OSSI
+.. doxygendefine:: TIMER_BDTR_LOCK
+.. doxygendefine:: TIMER_BDTR_LOCK_OFF
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL1
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL2
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL3
+.. doxygendefine:: TIMER_BDTR_DTG
+
+DMA control register (DCR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_DCR_DBL
+.. doxygendefine:: TIMER_DCR_DBL_1BYTE
+.. doxygendefine:: TIMER_DCR_DBL_2BYTE
+.. doxygendefine:: TIMER_DCR_DBL_3BYTE
+.. doxygendefine:: TIMER_DCR_DBL_4BYTE
+.. doxygendefine:: TIMER_DCR_DBL_5BYTE
+.. doxygendefine:: TIMER_DCR_DBL_6BYTE
+.. doxygendefine:: TIMER_DCR_DBL_7BYTE
+.. doxygendefine:: TIMER_DCR_DBL_8BYTE
+.. doxygendefine:: TIMER_DCR_DBL_9BYTE
+.. doxygendefine:: TIMER_DCR_DBL_10BYTE
+.. doxygendefine:: TIMER_DCR_DBL_11BYTE
+.. doxygendefine:: TIMER_DCR_DBL_12BYTE
+.. doxygendefine:: TIMER_DCR_DBL_13BYTE
+.. doxygendefine:: TIMER_DCR_DBL_14BYTE
+.. doxygendefine:: TIMER_DCR_DBL_15BYTE
+.. doxygendefine:: TIMER_DCR_DBL_16BYTE
+.. doxygendefine:: TIMER_DCR_DBL_17BYTE
+.. doxygendefine:: TIMER_DCR_DBL_18BYTE
+.. doxygendefine:: TIMER_DCR_DBA
+.. doxygendefine:: TIMER_DCR_DBA_CR1
+.. doxygendefine:: TIMER_DCR_DBA_CR2
+.. doxygendefine:: TIMER_DCR_DBA_SMCR
+.. doxygendefine:: TIMER_DCR_DBA_DIER
+.. doxygendefine:: TIMER_DCR_DBA_SR
+.. doxygendefine:: TIMER_DCR_DBA_EGR
+.. doxygendefine:: TIMER_DCR_DBA_CCMR1
+.. doxygendefine:: TIMER_DCR_DBA_CCMR2
+.. doxygendefine:: TIMER_DCR_DBA_CCER
+.. doxygendefine:: TIMER_DCR_DBA_CNT
+.. doxygendefine:: TIMER_DCR_DBA_PSC
+.. doxygendefine:: TIMER_DCR_DBA_ARR
+.. doxygendefine:: TIMER_DCR_DBA_RCR
+.. doxygendefine:: TIMER_DCR_DBA_CCR1
+.. doxygendefine:: TIMER_DCR_DBA_CCR2
+.. doxygendefine:: TIMER_DCR_DBA_CCR3
+.. doxygendefine:: TIMER_DCR_DBA_CCR4
+.. doxygendefine:: TIMER_DCR_DBA_BDTR
+.. doxygendefine:: TIMER_DCR_DBA_DCR
+.. doxygendefine:: TIMER_DCR_DBA_DMAR
diff --git a/docs/source/libmaple/api/usart.rst b/docs/source/libmaple/api/usart.rst
new file mode 100644
index 0000000..68f2c37
--- /dev/null
+++ b/docs/source/libmaple/api/usart.rst
@@ -0,0 +1,197 @@
+.. highlight:: c
+.. _libmaple-usart:
+
+``usart.h``
+===========
+
+Universal Synchronous/Asynchronous Receiver/Transmitter (USART, or
+commonly *serial port*) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: usart_reg_map
+.. doxygenstruct:: usart_dev
+
+Devices
+-------
+
+.. doxygenvariable:: USART1
+.. doxygenvariable:: USART2
+.. doxygenvariable:: USART3
+.. doxygenvariable:: UART4
+.. doxygenvariable:: UART5
+
+Functions
+---------
+
+.. doxygenfunction:: usart_init
+.. doxygenfunction:: usart_set_baud_rate
+.. doxygenfunction:: usart_enable
+.. doxygenfunction:: usart_disable
+.. doxygenfunction:: usart_disable_all
+.. doxygenfunction:: usart_foreach
+.. doxygenfunction:: usart_rx
+.. doxygenfunction:: usart_tx
+.. doxygenfunction:: usart_putudec
+.. doxygenfunction:: usart_putc
+.. doxygenfunction:: usart_putstr
+.. doxygenfunction:: usart_getc
+.. doxygenfunction:: usart_data_available
+.. doxygenfunction:: usart_reset_rx
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: USART1_BASE
+.. doxygendefine:: USART2_BASE
+.. doxygendefine:: USART3_BASE
+.. doxygendefine:: UART4_BASE
+.. doxygendefine:: UART5_BASE
+
+Register Bit Definitions
+------------------------
+
+Status Register
+~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_SR_CTS_BIT
+.. doxygendefine:: USART_SR_LBD_BIT
+.. doxygendefine:: USART_SR_TXE_BIT
+.. doxygendefine:: USART_SR_TC_BIT
+.. doxygendefine:: USART_SR_RXNE_BIT
+.. doxygendefine:: USART_SR_IDLE_BIT
+.. doxygendefine:: USART_SR_ORE_BIT
+.. doxygendefine:: USART_SR_NE_BIT
+.. doxygendefine:: USART_SR_FE_BIT
+.. doxygendefine:: USART_SR_PE_BIT
+
+.. doxygendefine:: USART_SR_CTS
+.. doxygendefine:: USART_SR_LBD
+.. doxygendefine:: USART_SR_TXE
+.. doxygendefine:: USART_SR_TC
+.. doxygendefine:: USART_SR_RXNE
+.. doxygendefine:: USART_SR_IDLE
+.. doxygendefine:: USART_SR_ORE
+.. doxygendefine:: USART_SR_NE
+.. doxygendefine:: USART_SR_FE
+.. doxygendefine:: USART_SR_PE
+
+Data register
+~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_DR_DR
+
+Baud Rate Register
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_BRR_DIV_MANTISSA
+.. doxygendefine:: USART_BRR_DIV_FRACTION
+
+Control Register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR1_UE_BIT
+.. doxygendefine:: USART_CR1_M_BIT
+.. doxygendefine:: USART_CR1_WAKE_BIT
+.. doxygendefine:: USART_CR1_PCE_BIT
+.. doxygendefine:: USART_CR1_PS_BIT
+.. doxygendefine:: USART_CR1_PEIE_BIT
+.. doxygendefine:: USART_CR1_TXEIE_BIT
+.. doxygendefine:: USART_CR1_TCIE_BIT
+.. doxygendefine:: USART_CR1_RXNEIE_BIT
+.. doxygendefine:: USART_CR1_IDLEIE_BIT
+.. doxygendefine:: USART_CR1_TE_BIT
+.. doxygendefine:: USART_CR1_RE_BIT
+.. doxygendefine:: USART_CR1_RWU_BIT
+.. doxygendefine:: USART_CR1_SBK_BIT
+
+.. doxygendefine:: USART_CR1_UE
+.. doxygendefine:: USART_CR1_M
+.. doxygendefine:: USART_CR1_WAKE
+.. doxygendefine:: USART_CR1_WAKE_IDLE
+.. doxygendefine:: USART_CR1_WAKE_ADDR
+.. doxygendefine:: USART_CR1_PCE
+.. doxygendefine:: USART_CR1_PS
+.. doxygendefine:: USART_CR1_PS_EVEN
+.. doxygendefine:: USART_CR1_PS_ODD
+.. doxygendefine:: USART_CR1_PEIE
+.. doxygendefine:: USART_CR1_TXEIE
+.. doxygendefine:: USART_CR1_TCIE
+.. doxygendefine:: USART_CR1_RXNEIE
+.. doxygendefine:: USART_CR1_IDLEIE
+.. doxygendefine:: USART_CR1_TE
+.. doxygendefine:: USART_CR1_RE
+.. doxygendefine:: USART_CR1_RWU
+.. doxygendefine:: USART_CR1_RWU_ACTIVE
+.. doxygendefine:: USART_CR1_RWU_MUTE
+.. doxygendefine:: USART_CR1_SBK
+
+Control Register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR2_LINEN_BIT
+.. doxygendefine:: USART_CR2_CLKEN_BIT
+.. doxygendefine:: USART_CR2_CPOL_BIT
+.. doxygendefine:: USART_CR2_CPHA_BIT
+.. doxygendefine:: USART_CR2_LBCL_BIT
+.. doxygendefine:: USART_CR2_LBDIE_BIT
+.. doxygendefine:: USART_CR2_LBDL_BIT
+
+.. doxygendefine:: USART_CR2_LINEN
+.. doxygendefine:: USART_CR2_STOP
+.. doxygendefine:: USART_CR2_STOP_BITS_1
+.. doxygendefine:: USART_CR2_STOP_BITS_POINT_5
+.. doxygendefine:: USART_CR2_STOP_BITS_1_POINT_5
+.. doxygendefine:: USART_CR2_STOP_BITS_2
+.. doxygendefine:: USART_CR2_CLKEN
+.. doxygendefine:: USART_CR2_CPOL
+.. doxygendefine:: USART_CR2_CPOL_LOW
+.. doxygendefine:: USART_CR2_CPOL_HIGH
+.. doxygendefine:: USART_CR2_CPHA
+.. doxygendefine:: USART_CR2_CPHA_FIRST
+.. doxygendefine:: USART_CR2_CPHA_SECOND
+.. doxygendefine:: USART_CR2_LBCL
+.. doxygendefine:: USART_CR2_LBDIE
+.. doxygendefine:: USART_CR2_LBDL
+.. doxygendefine:: USART_CR2_LBDL_10_BIT
+.. doxygendefine:: USART_CR2_LBDL_11_BIT
+.. doxygendefine:: USART_CR2_ADD
+
+Control Register 3
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR3_CTSIE_BIT
+.. doxygendefine:: USART_CR3_CTSE_BIT
+.. doxygendefine:: USART_CR3_RTSE_BIT
+.. doxygendefine:: USART_CR3_DMAT_BIT
+.. doxygendefine:: USART_CR3_DMAR_BIT
+.. doxygendefine:: USART_CR3_SCEN_BIT
+.. doxygendefine:: USART_CR3_NACK_BIT
+.. doxygendefine:: USART_CR3_HDSEL_BIT
+.. doxygendefine:: USART_CR3_IRLP_BIT
+.. doxygendefine:: USART_CR3_IREN_BIT
+.. doxygendefine:: USART_CR3_EIE_BIT
+
+.. doxygendefine:: USART_CR3_CTSIE
+.. doxygendefine:: USART_CR3_CTSE
+.. doxygendefine:: USART_CR3_RTSE
+.. doxygendefine:: USART_CR3_DMAT
+.. doxygendefine:: USART_CR3_DMAR
+.. doxygendefine:: USART_CR3_SCEN
+.. doxygendefine:: USART_CR3_NACK
+.. doxygendefine:: USART_CR3_HDSEL
+.. doxygendefine:: USART_CR3_IRLP
+.. doxygendefine:: USART_CR3_IRLP_NORMAL
+.. doxygendefine:: USART_CR3_IRLP_LOW_POWER
+.. doxygendefine:: USART_CR3_IREN
+.. doxygendefine:: USART_CR3_EIE
+
+Guard Time and Prescaler Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_GTPR_GT
+.. doxygendefine:: USART_GTPR_PSC
diff --git a/docs/source/libmaple/api/util.rst b/docs/source/libmaple/api/util.rst
new file mode 100644
index 0000000..54377c0
--- /dev/null
+++ b/docs/source/libmaple/api/util.rst
@@ -0,0 +1,54 @@
+.. highlight:: c
+.. _libmaple-util:
+
+``<libmaple/util.h>``
+=====================
+
+.. TODO [0.2.0?] clean this up.
+
+Miscellaneous utility macros and procedures.
+
+.. contents:: Contents
+ :local:
+
+Bit Manipulation
+----------------
+
+The following macros are useful for bit manipulation.
+
+.. doxygendefine:: BIT
+.. doxygendefine:: BIT_MASK_SHIFT
+.. doxygendefine:: GET_BITS
+.. doxygendefine:: IS_POWER_OF_TWO
+
+Failure Routines
+----------------
+
+``throb()`` is called by various routines to throb a built-in
+LED. **Usually, you shouldn't call it yourself**; use something like
+``ASSERT(0)`` (or the libc ``abort()`` function) instead.
+
+.. doxygenfunction:: throb
+
+Asserts and Debug Levels
+------------------------
+
+The level of libmaple's assertion support is determined by
+``DEBUG_LEVEL``, as follows:
+
+.. doxygendefine:: DEBUG_LEVEL
+
+The current assert macros are ``ASSERT()`` and ``ASSERT_FAULT()``.
+``ASSERT()`` is checked when ``DEBUG_LEVEL >= DEBUG_ALL``.
+``ASSERT_FAULT()`` is checked whenever ``DEBUG_LEVEL >= DEBUG_FAULT``.
+
+As explained above, an assert macro is checked when the current
+``DEBUG_LEVEL`` is high enough. If the debug level is too low, the
+macro expands into a no-op that gets compiled away.
+
+If an assertion fails, execution is halted at the point of the failed
+assertion. When libmaple has been configured properly (Wirish
+performs this configuration by default), the built-in LED throbs in a
+smooth pattern to signal the failed assertion (using
+:c:func:`throb()`), and the file and line where the assert failed are
+transmitted to the user as detailed in :ref:`lang-assert`.
diff --git a/docs/source/libmaple/apis.rst b/docs/source/libmaple/apis.rst
new file mode 100644
index 0000000..31f4902
--- /dev/null
+++ b/docs/source/libmaple/apis.rst
@@ -0,0 +1,14 @@
+.. _libmaple-apis:
+
+``libmaple`` API Index
+======================
+
+This is the master index for libmaple proper's APIs.
+
+**Contents**
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ api/*
diff --git a/docs/source/libmaple/coding-standard.rst b/docs/source/libmaple/coding-standard.rst
new file mode 100644
index 0000000..9ed56cc
--- /dev/null
+++ b/docs/source/libmaple/coding-standard.rst
@@ -0,0 +1,422 @@
+.. _libmaple-coding-standard:
+
+Coding Standard
+===============
+
+This page documents the coding standard for :ref:`libmaple`. It's
+intended as a guide for how you should structure any code you would
+like included into the LeafLabs releases of libmaple.
+
+LeafLabs team members are required to follow these when producing new
+code. Community contributors to libmaple are strongly encouraged to
+do so; following these rules will greatly increase the probability
+that your patches will be folded in.
+
+In general, follow this guide unless there's a very good reason not
+to. Laziness doesn't count as a good reason. Most, if not all, of
+these decisions are entirely arbitrary, but it's important for
+readability that we be consistent. (If you notice an inconsistency,
+you should fix it).
+
+Note that the file ``.dir-locals.el`` in the libmaple root directory
+already ensures that many of these standards are followed by default
+in Emacs (but not on Windows, where it would need to be named
+``_dir_locals.el``, and no way, man). There's also some elisp
+scattered about this file which will provide you additional help.
+
+Configuration for other editors (vim, etc.) would be nice!
+
+.. contents:: Contents
+ :local:
+
+License
+-------
+
+.. highlight:: scheme
+
+Put an MIT license at the beginning of the file (look at any of our
+source files for an example). Copyright should go either to you or to
+LeafLabs, LLC.
+
+Emacs: if you don't like seeing the license, you should use elide-head
+(which will hide it for you). You can use the following::
+
+ (require 'elide-head)
+ (setq programming-mode-hooks '(c-mode-hook c++-mode-hook))
+ (add-to-list 'elide-head-headers-to-hide
+ '("The MIT License" . "DEALINGS IN\n [*] THE SOFTWARE"))
+ (add-to-list 'elide-head-headers-to-hide
+ '("The MIT License" . "DEALINGS IN THE\n...SOFTWARE"))
+ (dolist (hook programming-mode-hooks)
+ (add-hook hook (lambda () (elide-head))))
+
+Whitespace
+----------
+
+TextMate users may find `this bundle
+<https://github.com/glennr/uber-glory-tmbundle>`_ useful for
+automatically converting tabs to spaces and removing trailing
+whitespace at save time.
+
+- 4 space indents (set in ``.dir-locals.el``).
+
+- Unix newlines.
+
+- No tab characters (set in ``.dir-locals.el``).
+
+- No trailing whitespace. For help getting this (and no tab
+ characters) done automatically in Emacs, you can use
+ `code-fascism.el <https://github.com/mbolivar/code-fascism>`_.
+
+- Files end in exactly one newline. The presence of a newline at EOF
+ is already done by ``c-require-final-newline`` in recent versions of
+ Emacs.
+
+- Exactly two newlines separate source paragraphs (you do separate
+ your code into paragraphs, don't you?).
+
+- The first line in a function is non-blank.
+
+.. highlight:: cpp
+
+- Exactly one space after ``if``, ``else``, ``for``, and ``while``,
+ before the following ``{`` or ``(``. One space before ``else``,
+ after the preceding ``}``. For example::
+
+ // This is good; we like this:
+ if (foo) {
+ while (quux) {
+ bar();
+ }
+ } else {
+ baz();
+ }
+
+ // THIS IS BAD! DON'T DO THIS:
+ if(foo){
+ while(quux){
+ bar();
+ }
+ }else{
+ baz();
+ }
+
+- Exactly one space in between binary arithmetic, logical, and
+ comparison operators and their operands. Examples::
+
+ // This is good:
+ int x = a + b * (c - d);
+ if (x != 0 && a > 7) {
+ SerialUSB.println(x);
+ }
+
+ // THIS IS BAD!
+ int x = a+b*(c-d);
+ if (x!=0 && a>7) {
+ SerialUSB.println(x);
+ }
+
+ // This is good:
+ uint32 adc_data = ADC1_BASE->DR;
+ SerialUSB.println(adc_data);
+
+ // THIS IS BAD!
+ uint32 adc_data = ADC1_BASE -> DR;
+ SerialUSB . println(adc_data);
+
+- No space between a unary operator and its operand. Examples::
+
+ // Good:
+ x++;
+
+ // BAD!
+ x ++;
+
+ // Good:
+ y = -x;
+
+ // BAD!
+ y = - x;
+
+- If you need to break up a long line:
+
+ * Prefer to break up long expressions after a binary operator. Example::
+
+ // Good:
+ if (some_really_long_conditional_wow_this_really_goes_on_forever ||
+ maybe_something_else_could_happen_too) {
+ ...
+ }
+
+ // BAD!
+ if (some_really_long_conditional_wow_this_really_goes_on_forever
+ || maybe_something_else_could_happen_too) {
+ ...
+ }
+
+ * When breaking up a function's arguments over multiple lines, align
+ the arguments on subsequent lines with the first argument.
+ Example::
+
+ // Good:
+ return_type value_i_got = function_with_a_really_long_name(argument1,
+ argument2,
+ argument3);
+
+ // BAD!
+ return_type value_i_got = function_with_a_really_long_name(argument1,
+ argument2,
+ argument3);
+
+ // BAD!
+ return_type value_i_got = function_with_a_really_long_name(argument1,
+ argument2,
+ argument3);
+
+- In function invocations, no space in between the function name and
+ the opening parenthesis. Example::
+
+ // Good:
+ SerialUSB.println("Hello, world!");
+
+ // BAD!
+ SerialUSB.println ("Hello, world!");
+
+- Don't indent C code within a conditionally-compiled ``extern "C"``
+ block. Example::
+
+ // Good:
+ #ifdef __cplusplus
+ extern "C"{
+ #endif
+
+ void some_c_function(void);
+
+ #ifdef __cplusplus
+ } // extern "C"
+ #endif
+
+ // BAD!
+ #ifdef __cplusplus
+ extern "C"{
+ #endif
+
+ void some_c_function(void);
+
+ #ifdef __cplusplus
+ } // extern "C"
+ #endif
+
+ Emacs does the "bad" behavior by default, which can be very
+ annoying. You can turn this off with ::
+
+ (defun c-mode-inextern-lang-hook ()
+ (setcdr (assq 'inextern-lang c-offsets-alist) '-))
+ (add-hook 'c-mode-hook c-mode-inextern-lang-hook)
+
+Comments
+--------
+
+.. highlight:: c++
+
+- Multi-line comments are pretty flexible. Any of these is fine::
+
+ /* Comment starts here.
+ * Continued lines have a '*' before them.
+ * The comment can end after the last line.
+ */
+
+ /* Comment starts here.
+ * The comment can end on the same line. */
+
+ /*
+ * You can also place a newline after the opening "/*".
+ */
+
+- Doxygen comments are multi-line comments that begin with ``/**``
+ instead.
+
+- Single-line comments are up to you.
+
+Braces
+------
+
+- Mostly `1TBS
+ <http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS>`_. The
+ only difference is that the opening brace of a function's definition
+ occurs exactly one space character after the closing parenthesis in
+ that function's parameter list. Example::
+
+ void func(void) {
+ ...
+ }
+
+Naming conventions
+------------------
+
+We'll handle the usual casing/underscore debate as follows.
+
+- First, ``Dont_Mix_Like_This``, because ``It_Looks_Really_Ugly``, ok?
+ [There's been some debate about this, and some exceptions are
+ already grandfathered in, so in order to settle it, let's call this
+ a "recommendation" instead of "requirement".]
+
+- Variables: Use underscores to separate words in C identifiers::
+
+ int some_example_name;
+
+ User-facing C++ variables should be camel cased
+ (``thisIsAnExample``, ``boardPWMPins``, etc.), for consistency with
+ the Arduino style. It's probably a good idea for you to case
+ non-user facing C++ variables in the C style; this will help
+ disambiguate what's part of the Wirish API and what's not.
+
+- Classes: Pascal case. So ``ThisIsAClassName``, but ``thisIsNot``,
+ ``this_is_not``, and ``Dont_You_DareTryANYTHING_STUPID``.
+
+- Functions: C functions are all lowercase, and words are separated by
+ underscores. C++ method names are camel cased.
+
+- Structs: Usually like variables (``adc_dev``, ``adc_reg_map``,
+ etc.), but it's not crucial. Don't feel obliged to put ``_t`` at
+ the end of the type name; we don't.
+
+- Macros and constants: all caps, separated by underscores. C++
+ variables with the ``const`` qualifier generally aren't considered
+ "constants" for the purposes of this rule; i.e., they are cased
+ according to the rules for variables. We make an exception for
+ ``PIN_MAP``, because it's the central Wirish data structure.
+
+- foo.h gets ``#ifdef``\ 'ed to ``_FOO_H_``.
+
+- Acronyms: The case of letters in an acronym is determined by the
+ case of the first letter in the acronym, which is determined by
+ following the above rules. Examples::
+
+ // Good:
+ void usb_func() { ... }
+ void frob_usb_disc() { ... }
+ class SomethingUSB {
+ void usbInit();
+ void initUSB();
+ };
+
+ // BAD:
+ class BadUsb { ... }; // say "GoodUSB" instead
+ void swizzle_USB_disc() { ... } // say "swizzle_usb_disc" instead
+
+Documentation
+-------------
+
+- Doxygen comments on every user-facing function and type.
+ Additionally, individually document the fields and enumerator values
+ of nontrivial user-facing structs and enums. See any register map
+ type's definition for an example.
+
+- For libmaple proper, you don't need comments for each register bit
+ definition, since that's just repeating information better obtained
+ by reading ST RM0008.
+
+- Doxygen comments generally only belong on types, functions,
+ etc. that are part of the public user-facing API.
+
+ This essentially means that if what you're writing is going to be
+ documented under http://leaflabs.com/docs/ (i.e., if there's `Sphinx
+ documentation <http://sphinx.pocoo.org/>`_ for it in the
+ `leaflabs-docs <https://github.com/leaflabs/leaflabs-docs>`_
+ repository), then you need to write Doxygen comments. Further,
+ those Sphinx docs should use Breathe to pull the Doxygen out. (For
+ more information on this, see the `leaflabs-docs README
+ <https://raw.github.com/leaflabs/leaflabs-docs/master/README>`_).
+
+ Because Breathe isn't totally mature yet, you won't always be able
+ to do this. In these cases, document the code "manually" using the
+ Sphinx `C and C++ domains
+ <http://sphinx.pocoo.org/domains.html#the-c-domain>`_. This should
+ be avoided if at all possible, since it creates a maintenance burden
+ of documenting things in two places at once, and makes it easier for
+ documentation to go stale.
+
+ If you do have to document something manually, put a comment in the
+ source file informing future maintainers about it, so they'll pay
+ extra attention when making changes.
+
+- When adding peripheral support, it would be nice if you put
+ longer-form comments into the libmaple ``notes/`` directory, with a
+ comment in the corresponding .h file referring to it. See the
+ :ref:`dac.h <libmaple-dac>` source for an example.
+
+ This lets us keep the source files relatively free of "introductory"
+ material, while allowing new readers a convenient starting point.
+ These longer-form notes also have a habit of turning into official,
+ user-facing documentation (or `wiki <http://wiki.leaflabs.com>`_
+ pages).
+
+- **For libmaple proper**, the convention is to document any
+ user-facing function at the point where it is defined. In
+ particular, this means you should document an externally-linked
+ function defined in a .c file in that .c file, not in the header
+ file where it is declared to the user.
+
+ **For Wirish**, the convention is to put the documentation in the
+ header file where the function is declared.
+
+General Formatting
+------------------
+
+.. highlight:: scheme
+
+- Keep it 80-column clean.
+
+ Emacs users: this means that the largest column number is 79. You
+ should turn on column number mode to help you out::
+
+ (column-number-mode 1)
+
+ You can get more help from `lineker-mode
+ <http://www.helsinki.fi/~sjpaavol/programs/lineker.el>`_. Just put
+ lineker.el somewhere in your load-path, and::
+
+ (require 'lineker)
+ (dolist (hook '(c-mode-hook c++-mode-hook))
+ (add-hook hook (lambda () (lineker-mode 1))))
+
+.. highlight:: cpp
+
+Language Features
+-----------------
+
+In libmaple proper, aim for C99 compatibility. Some GCC extensions
+are OK, but `don't get crazy <http://www.youtube.com/watch?v=jZkdcYlOn5M>`_.
+
+Explicitly approved GCC extensions:
+
+ * `asm volatile <http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html>`_
+
+ * `Nested functions <http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>`_
+
+In Wirish, generally be very conservative when using C++ features that
+aren't part of C. We are forced to use C++ for Arduino compatibility
+(and the general Arduino style of conflating objects and libraries),
+but it's an angry beast, and we don't want to provoke it. **The
+mantra is "C with classes"**.
+
+Explicitly approved C++ features:
+
+ * Initializers that aren't constant; e.g. the ``gpio_dev*`` values
+ in a ``PIN_MAP``.
+
+ * Default arguments: e.g., the timeout argument in
+ :ref:`lang-waitforbuttonpress`.
+
+Explicitly forbidden C++ features:
+
+ * Templates
+
+Conditionally allowed C++ features:
+
+ * Operator overloading: Never allowed when it's just for style.
+ Probably fine when you're implementing a class that models a
+ mathematical structure, and you'd like to implement
+ e.g. ``operator+()``.
+
diff --git a/docs/source/libmaple/contributing.rst b/docs/source/libmaple/contributing.rst
new file mode 100644
index 0000000..25c6c17
--- /dev/null
+++ b/docs/source/libmaple/contributing.rst
@@ -0,0 +1,176 @@
+.. _libmaple-contributing:
+
+Contributing to libmaple
+========================
+
+First of all, thanks! Community contributions are what makes open
+source great.
+
+If your patch is minor (you've found a typo, you've added a new
+function, etc.), feel free to just make a `forum post
+<http://forums.leaflabs.com>`_ describing your changes.
+
+If your changes are larger (you wrote a new library, you added support
+for a new peripheral, etc.), we'd prefer you submit a pull request on
+GitHub or send us a nicely-formatted patch via email.
+
+.. contents:: Contents
+ :local:
+
+.. _libmaple-faq-patches-preparing:
+
+Preparing Your Patch
+--------------------
+
+Before submitting a patch, please make sure it complies with the
+:ref:`coding standard <libmaple-coding-standard>`. Consistent style throughout
+the source tree is an important implementation objective for us, and a
+patch that doesn't comply with the coding standard we've set forth is
+likely to be sent back until it follows the standard.
+
+We would prefer if you release each new file you submit under the `MIT
+license <http://www.opensource.org/licenses/mit-license.php>`_. See
+e.g. `bkp.h
+<https://github.com/leaflabs/libmaple/blob/master/libmaple/bkp.h#L1>`_
+for an example, and the coding standard for more details. Code
+released under the `Lesser GPL
+<http://www.gnu.org/copyleft/lesser.html>`_ may be accepted for
+Wirish, but will almost certainly be rejected for libmaple proper. We
+will not accept patches released under the `GPL
+<http://www.gnu.org/licenses/gpl.html>`_.
+
+**We're not against the GPL**! It just doesn't suit our purposes for
+libmaple. If you're interested in a GPLed library for ST
+microcontrollers, check out `libopenstm32
+<http://www.hermann-uwe.de/blog/libopenstm32-a-free-software-firmware-library-for-stm32-arm-cortex-m3-microcontrollers>`_.
+Also note that :ref:`libraries <libraries>` released under the GPL are
+fine, we just don't want any core libmaple or Wirish code to be GPLed.
+
+.. _libmaple-faq-patches-github:
+
+Submitting Via GitHub Pull Request (Preferred)
+----------------------------------------------
+
+The most convenient way for you to contribute patches is to submit a
+pull request on `GitHub <https://github.com>`_. Github provides
+excellent code review interfaces, which will make it easy for us at
+LeafLabs to communicate with you (and each other) about your patch.
+It also makes it easy for us to merge your patch into the libmaple
+source tree when the time comes.
+
+The steps to submit a pull request are as follows:
+
+1. If you don't already have one, get a `GitHub account
+ <https://github.com/plans>`_ (free).
+
+2. Fork libmaple, then clone your fork to the computer you code on.
+ GitHub provides detailed instructions on `forking and cloning a
+ repository <http://help.github.com/fork-a-repo/>`_.
+
+3. Push your commits to your GitHub libmaple fork (see instructions
+ linked in Step 2 for a step-by-step walkthrough on how to do this).
+
+ Please add a signed-off-by line to your commits which certify your
+ `developer certificate of origin
+ <http://elinux.org/Developer_Certificate_Of_Origin>`_ [#fcert]_.
+ For example, if your name is "John Smith", and your email address
+ is "jsmith@example.com", just include the following line at the
+ bottom of your commit messages:
+
+ ``Signed-off-by: John Smith <jsmith@example.com>``
+
+ If you've configured Git to know your name and email, you can
+ instruct it to insert this line automatically by calling ``git
+ commit`` with the ``-s`` flag.
+
+4. `Submit a pull request <http://help.github.com/pull-requests/>`_ to
+ the LeafLabs version of libmaple.
+
+.. _libmaple-faq-patches-email:
+
+Submitting Via Email
+--------------------
+
+If you're unfamiliar with Git or would prefer not to use GitHub, you
+can always send us a patch via email at info@leaflabs.com. We'd love
+it if you used the `Linux kernel patch format
+<http://linux.yyz.us/patch-format.html>`_, but please at least include
+the following information in your email:
+
+1. How you generated your patch (arguments to ``diff``, etc.)
+
+2. What git branch/commit or libmaple version your patch applies to
+
+3. A one-line summary of your changes, along with any other details
+ you think we should know.
+
+4. A sign-off line certifying your `developer certificate of origin
+ <http://elinux.org/Developer_Certificate_Of_Origin>`_ [#fcert]_.
+
+.. _libmaple-git-resources:
+
+Git Resources
+-------------
+
+If you'd like to learn more about Git, we recommend the following
+resources:
+
+* `The Git Community Book <http://book.git-scm.com/index.html>`_: A
+ collaboratively edited book on Git.
+
+* `Pro Git <http://progit.org/book/>`_: despite its title, this is a
+ fairly beginner-friendly source of information.
+
+* `Git - Revision Control Perfected (Linux Journal)
+ <http://www.linuxjournal.com/content/git-revision-control-perfected>`_:
+ Despite a title that makes it sound like it was written by a
+ marketing department, this is a very good introductory article on
+ basic Git concepts, and a solid primer on Git's internals.
+
+- `GitPhraseBook (openembedded.org)
+ <http://www.openembedded.org/index.php/GitPhraseBook>`_: A
+ cookbook-style list of common Git problems and their solutions.
+
+* `Understanding Git Conceptually
+ <http://www.eecs.harvard.edu/~cduan/technical/git/>`_: a good,
+ introductory tutorial on Git's fundamental concepts.
+
+* `Git for Computer Scientists
+ <http://eagain.net/articles/git-for-computer-scientists/>`_: if
+ you're comfortable with directed acyclic graphs, this resource
+ explains Git's functionality in graph-theoretic terms.
+
+.. highlight:: text
+
+.. rubric:: Footnotes
+
+.. [#fcert] Including this line indicates that you certify the following::
+
+ Developer's Certificate of Origin 1.1
+
+ By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+
+ This may seem arbitrary, but it helps ensure that libmaple
+ remains open source.
diff --git a/docs/source/libmaple/overview.rst b/docs/source/libmaple/overview.rst
new file mode 100644
index 0000000..006f1d8
--- /dev/null
+++ b/docs/source/libmaple/overview.rst
@@ -0,0 +1,516 @@
+.. highlight:: c
+
+.. _libmaple-overview:
+
+Overview
+========
+
+This page is a general overview of :ref:`libmaple proper
+<libmaple-vs-wirish>`. It describes libmaple's design, and names
+implementation patterns to look for when using it. General
+familiarity with the :ref:`STM32 <stm32>` is assumed; beginners should
+start with the high-level :ref:`Wirish interface <language>` instead.
+Examples are given from libmaple's sources.
+
+.. contents:: Contents
+ :local:
+
+Design Goals
+------------
+
+The central goal for libmaple proper is to provide a pleasant,
+portable, and consistent set of interfaces for dealing with the
+various series of STM32 microcontrollers.
+
+Portability in particular can be a problem when programming for the
+STM32. While the various STM32 series are largely pin-compatible with
+one another, the peripheral register maps between series often change
+drastically, even when the functionality provided by the peripheral
+doesn't change very much. This means that code which accesses
+registers directly often needs to change when porting a program to a
+different series MCU.
+
+ST's solution to this problem thus far has been to `issue
+<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32l1_stdperiph_lib.zip>`_
+`separate
+<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f10x_stdperiph_lib.zip>`_
+`firmware
+<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f2xx_stdperiph_lib.zip>`_
+`libraries
+<http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip>`_;
+one for each STM32 series. Along with these, they have released a
+`number
+<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00024853.pdf>`_
+of `application
+<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00033267.pdf>`_
+`notes
+<http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00032987.pdf>`_
+describing the compatibility issues and how to migrate between series
+by switching firmware libraries. Often, the migration advice is
+essentially "rewrite your code"; this occurs, for example, with any
+code involving GPIO or DMA being migrated between STM32F1 and STM32F2.
+
+Needless to say, this can be very annoying. (Didn't we solve this
+sort of problem years ago?) When you just want your robot to fly,
+your `LEDs to blink <http://www.youtube.com/watch?v=J845L45zqfk>`_, or
+your `FM synthesizer <https://github.com/Ixox/preen>`_ to, well,
+`synthesize <http://xhosxe.free.fr/IxoxFMSynth.mp3>`_, you probably
+couldn't care less about dealing with a new set of registers.
+
+We want to make it easier to write portable STM32 code. To enable
+that, libmaple abstracts away many hardware details behind portable
+interfaces. We also want to make it easy for you to get your hands
+dirty when need or desire arises. To that end, libmaple makes as few
+assumptions as possible, and does its best to get out of your way when
+you want it to leave.
+
+.. _libmaple-overview-devices:
+
+Libmaple's Device Model
+-----------------------
+
+The libmaple device model is simple and stupid. This is a feature.
+
+*Device types* are the central libmaple abstraction; they exist to
+provide portable interfaces to common peripherals, but they still let
+you do nonportable things easily if you want to.
+
+The rules for device types are:
+
+- Device types are structs representing peripherals. The name of the
+ device type for peripheral "foo" is ``struct foo_dev`` (so for
+ foo=ADC, it's ``struct adc_dev``. For foo=DMA, it's ``struct
+ dma_dev``; etc.). These are always ``typedef``\ ed to ``foo_dev``.
+
+- Each device type contains any information needed or used by libmaple
+ for operating on the peripheral the type represents. Device types
+ are defined alongside declarations for portable support routines in
+ the header ``<libmaple/foo.h>`` (examples: :ref:`libmaple-adc`,
+ :ref:`libmaple-dma`).
+
+- Direct :ref:`register access <libmaple-overview-regmaps>` is
+ possible via the ``regs`` field in each device type. (Given a
+ ``foo_dev *foo``, you can read and write the BAR register
+ ``FOO_BAR`` with ``foo->regs->BAR``.)
+
+- An :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>` for the device is
+ available in the ``clk_id`` field; this is an opaque type that can
+ be used to uniquely identifies the peripheral. (Given ``foo_dev
+ *foo``, you can check which foo you have by looking at
+ ``foo->clk_id``.)
+
+- The backend for each supported STM32 series statically initializes
+ devices as appropriate, and ensures that the peripheral support
+ header includes declarations for pointers to these statically
+ allocated devices.
+
+- Peripheral support functions usually expect a pointer to a device as
+ their first argument. These functions' implementations may vary
+ with the particular microcontroller you're targeting, but their
+ semantics try to stay the same. To migrate to a different target,
+ you'll often be able to simply recompile your program (and libmaple)
+ for the new target.
+
+- When complete portability is not possible, libmaple tries to keep
+ the nonportable bits in data, rather than code.
+
+Example: ``adc_dev``
+~~~~~~~~~~~~~~~~~~~~
+
+These rules are best explained by example. The device type for ADC
+peripherals is ``struct adc_dev``. Its definition is provided by
+``<libmaple/adc.h>``::
+
+ typedef struct adc_dev {
+ adc_reg_map *regs;
+ rcc_clk_id clk_id;
+ } adc_dev;
+
+An ``adc_dev`` contains a pointer to its register map in the ``regs``
+field. This ``regs`` field is available on all device types. Its value
+is a :ref:`register map base pointer
+<libmaple-overview-regmaps-base-pts>` (like ``ADC1_BASE``, etc.) for
+the peripheral, as determined by the current target. For example, two
+equivalent expressions for reading the ADC1 regular data register are
+``ADC1_BASE->DR`` and ``ADC1->regs->DR`` (though the first one is
+faster). Manipulating registers directly via ``->regs`` is thus
+always possible, but can be nonportable, and should you choose to do
+this, it's up to you to get it right.
+
+An ``adc_dev`` also contains an ``rcc_clk_id`` for the ADC peripheral
+it represents in the ``clk_id`` field. The ``rcc_clk_id`` enum type
+has an enumerator for each peripheral supported by your series. For
+example, the ADC peripherals' ``rcc_clk_id`` enumerators are
+``RCC_ADC1``, ``RCC_ADC2``, and ``RCC_ADC3``. In general, an
+``rcc_clk_id`` is useful not only for managing the clock line to a
+peripheral, but also as a unique identifier for that peripheral.
+
+(Device types can be more complicated than this; ``adc_dev`` was
+chosen as a simple example of the minimum you can expect.)
+
+Rather than have you define your own ``adc_dev``\ s, libmaple defines
+them for you as appropriate for your target STM32 series. For example,
+on STM32F1, the file libmaple/stm32f1/adc.c contains the following::
+
+ static adc_dev adc1 = {
+ .regs = ADC1_BASE,
+ .clk_id = RCC_ADC1,
+ };
+ /** ADC1 device. */
+ const adc_dev *ADC1 = &adc1;
+
+ static adc_dev adc2 = {
+ .regs = ADC2_BASE,
+ .clk_id = RCC_ADC2,
+ };
+ /** ADC2 device. */
+ const adc_dev *ADC2 = &adc2;
+
+ #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
+ static adc_dev adc3 = {
+ .regs = ADC3_BASE,
+ .clk_id = RCC_ADC3,
+ };
+ /** ADC3 device. */
+ const adc_dev *ADC3 = &adc3;
+ #endif
+
+Since all supported STM32F1 targets support ADC1 and ADC2, libmaple
+predefines corresponding ``adc_dev`` instances for you. To save space,
+it avoids defining an ``adc_dev`` for ADC3 unless you are targeting a
+high- or XL-density STM32F1, as medium- and lower density MCUs don't
+have ADC3.
+
+Note that the structs themselves are static and are exposed only via
+pointers. These pointers are declared in a series-specific ADC
+header, ``<series/adc.h>`` which is included by ``<libmaple/adc.h>``
+based on the MCU you're targeting. (**Never include <series/foo.h>
+directly**. Instead, include ``<libmaple/foo.h>`` and let it take
+care of that for you.) On STM32F1, the series ADC header contains the
+following::
+
+ extern const struct adc_dev *ADC1;
+ extern const struct adc_dev *ADC2;
+ #if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
+ extern const struct adc_dev *ADC3;
+ #endif
+
+In general, you access the predefined devices via these pointers. As
+illustrated by the ADC example, the variables for these pointers
+follow the naming scheme used in ST's reference manuals -- the pointer
+to ADC1's ``adc_dev`` is named ``ADC1``, and so on.
+
+The :ref:`API documentation <libmaple-apis>` for the peripherals
+you're interested in will list the available devices on each target.
+
+Using Devices
+~~~~~~~~~~~~~
+
+Peripheral support routines usually expect pointers to their device
+types as their first arguments. Here are some ADC examples::
+
+ uint16 adc_read(const adc_dev *dev, uint8 channel);
+ static inline void adc_enable(const adc_dev *dev);
+ static inline void adc_disable(const adc_dev *dev);
+
+So, to read channel 2 of ADC1, you could call ``adc_read(ADC1, 2)``.
+To disable ADC2, call ``adc_disable(ADC2)``; etc.
+
+That's it; there's nothing complicated here. In general, just follow
+links from the :ref:`libmaple-apis` page to the header for the
+peripheral you're interested in. It will explain the supported
+functionality, both portable and series-specific.
+
+Segregating Non-portable Functionality into Data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned previously, when total portability isn't possible,
+libmaple tries to do the right thing and segregate the nonportable
+portions into data rather than code. The function
+``adc_set_sample_rate()`` is a good example of how this works, and why
+it's useful::
+
+ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
+
+For example, while both STM32F1 and STM32F2 support setting the ADC
+sample time via the same register interface, the actual sample times
+supported are different. For instance, on STM32F1, available sample
+times include 1.5, 7.5, and 13.5 ADC cycles. On STM32F2, none of these
+are available, but 3, 15, and 28 ADC cycles are supported (which is
+not true for STM32F1). To work with this, libmaple provides a single
+function, ``adc_set_sample_rate()``, for setting an ADC controller's
+channel sampling time, but the actual sample rates it takes are given
+by the ``adc_smp_rate`` type, which is different on STM32F1 and
+STM32F2.
+
+This is the STM32F1 implementation of adc_smp_rate::
+
+ typedef enum adc_smp_rate {
+ ADC_SMPR_1_5, /**< 1.5 ADC cycles */
+ ADC_SMPR_7_5, /**< 7.5 ADC cycles */
+ ADC_SMPR_13_5, /**< 13.5 ADC cycles */
+ ADC_SMPR_28_5, /**< 28.5 ADC cycles */
+ ADC_SMPR_41_5, /**< 41.5 ADC cycles */
+ ADC_SMPR_55_5, /**< 55.5 ADC cycles */
+ ADC_SMPR_71_5, /**< 71.5 ADC cycles */
+ ADC_SMPR_239_5, /**< 239.5 ADC cycles */
+ } adc_smp_rate;
+
+And here is the STM32F2 implementation::
+
+ typedef enum adc_smp_rate {
+ ADC_SMPR_3, /**< 3 ADC cycles */
+ ADC_SMPR_15, /**< 15 ADC cycles */
+ ADC_SMPR_28, /**< 28 ADC cycles */
+ ADC_SMPR_56, /**< 56 ADC cycles */
+ ADC_SMPR_84, /**< 84 ADC cycles */
+ ADC_SMPR_112, /**< 112 ADC cycles */
+ ADC_SMPR_144, /**< 144 ADC cycles */
+ ADC_SMPR_480, /**< 480 ADC cycles */
+ } adc_smp_rate;
+
+So, on F1, you could call ``adc_set_sample_rate(ADC1, ADC_SMPR_1_5)``,
+and on F2, you could call ``adc_set_sample_rate(ADC1,
+ADC_SMPR_3)``. If you're only interested in one of those series, then
+that's all you need to know.
+
+However, if you're targeting multiple series, then this is useful
+because it lets you put the actual sample time for the MCU you're
+targeting into a variable (or macro, etc.), whose value depends on the
+target you're compiling for. This lets you have a single codebase to
+test and maintain, and lets you add support for a new target by simply
+adding some new data.
+
+To continue the example, one easy way is to pick an ``adc_smp_rate``
+for each of STM32F1 and STM32F2 is with conditional compilation. Using
+the :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>` define
+from :ref:`libmaple-stm32`, you can write::
+
+ #include <libmaple/adc.h>
+ #include <libmaple/stm32.h>
+
+ #if STM32_MCU_SERIES == STM32_SERIES_F1
+ /* Target is an STM32F1 */
+ adc_smp_rate smp_rate = ADC_SMPR_1_5;
+ #elif STM32_MCU_SERIES == STM32_SERIES_F2
+ /* Target is an STM32F2 */
+ adc_smp_rate smp_rate = ADC_SMPR_3;
+ #else
+ #error "Unsupported STM32 target; can't pick a sample rate"
+ #endif
+
+ void setup(void) {
+ adc_set_smp_rate(ADC1, smp_rate);
+ }
+
+Adding support for e.g. STM32F4 would only require adding a new
+``#elif`` for that series. This is simple, but hackish, and can get
+out of control if you're not careful.
+
+Another way to get the job done is to declare an ``extern adc_smp_rate
+smp_rate``, and use the build system to compile a file defining
+``smp_rate`` depending on your target. As was discussed earlier, this
+is what libmaple does when choosing which files to use for defining
+the appropriate ``adc_dev``\ s for your target. How to do this is
+outside the scope of this overview, however.
+
+.. _libmaple-overview-regmaps:
+
+Register Maps
+-------------
+
+Though we aim to enable libmaple's users to interact with the more
+portable :ref:`device interface <libmaple-overview-devices>` as much
+as possible, there will always be a need for efficient direct register
+access. To allow for that, libmaple provides *register maps* as a
+consistent set of names and abstractions for dealing with peripheral
+registers and their bits.
+
+A *register map type* is a struct which names and provides access to a
+peripheral's registers (we can use a struct because registers are
+usually mapped into contiguous regions of memory). Here's an example
+register map for the DAC peripheral on STM32F1 series MCUs (``__io``
+is just libmaple's way of saying ``volatile`` when referring to
+register values)::
+
+ typedef struct dac_reg_map {
+ __io uint32 CR; /**< Control register */
+ __io uint32 SWTRIGR; /**< Software trigger register */
+ __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data
+ holding register */
+ __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data
+ holding register */
+ __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data
+ holding register */
+ __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data
+ holding register */
+ __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data
+ holding register */
+ __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data
+ holding register */
+ __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data
+ holding register */
+ __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data
+ holding register */
+ __io uint32 DHR8RD; /**< Dual DAC 8-bit right-aligned data holding
+ register */
+ __io uint32 DOR1; /**< Channel 1 data output register */
+ __io uint32 DOR2; /**< Channel 2 data output register */
+ } dac_reg_map;
+
+There are two things to notice here. First, if the chip reference
+manual (for STM32F1, that's RM0008) names a register ``DAC_FOO``, then
+``dac_reg_map`` has a field named ``FOO``. So, the Channel 1 12-bit
+right-aligned data register (DAC_DHR12R1) is the ``DHR12R1`` field in
+a ``dac_reg_map``. Second, if the reference manual describes a
+register as "Foo bar register", the documentation for the
+corresponding field has the same description. This consistency makes
+it easy to search for a particular register, and, if you see one used
+in a source file, to feel sure about what's going on just based on its
+name.
+
+.. _libmaple-overview-regmaps-base-pts:
+
+So let's say you've included ``<libmaple/foo.h>``, and you want to
+mess with some particular register. You'll do this using *register map
+base pointers*, which are pointers to ``struct foo_reg_map``. What's
+the name of the base pointer you want? That depends on if there's
+more than one foo or not. If there's only one foo, then libmaple
+guarantees there will be a ``#define`` that looks like like this::
+
+ #define FOO_BASE ((struct foo_reg_map*)0xDEADBEEF)
+
+That is, you're guaranteed there will be a pointer to the (only)
+``foo_reg_map`` you want, and it will be called
+``FOO_BASE``. (``0xDEADBEEF`` is the register map's *base address*, or
+the fixed location in memory where the register map begins). Here's
+an example for STM32F1::
+
+ #define DAC_BASE ((struct dac_reg_map*)0x40007400)
+
+Here are some examples for how to read and write to registers using
+register map base pointers.
+
+* In order to write 2048 to the channel 1 12-bit left-aligned data
+ holding register (DAC_DHR12L1), you would write::
+
+ DAC_BASE->DHR12L1 = 2048;
+
+* In order to read the DAC control register, you would write::
+
+ uint32 cr = DAC_BASE->CR;
+
+That covers the case where there's a single foo peripheral. If
+there's more than one (say, if there are *n*), then
+``<libmaple/foo.h>`` provides the following::
+
+ #define FOO1_BASE ((struct foo_reg_map*)0xDEADBEEF)
+ #define FOO2_BASE ((struct foo_reg_map*)0xF00DF00D)
+ ...
+ #define FOOn_BASE ((struct foo_reg_map*)0x1EAF1AB5)
+
+Here are some examples for the ADCs on STM32F1::
+
+ #define ADC1_BASE ((struct adc_reg_map*)0x40012400)
+ #define ADC2_BASE ((struct adc_reg_map*)0x40012800)
+
+In order to read from the ADC1's regular data register (where the
+results of ADC conversion are stored), you would write::
+
+ uint32 converted_result = ADC1_BASE->DR;
+
+Register Bit Definitions
+------------------------
+
+In ``<libmaple/foo.h>``, there will also be a variety of ``#define``\
+s for dealing with interesting bits in the xxx registers, called
+*register bit definitions*. In keeping with the ST reference manuals,
+these are named according to the scheme ``FOO_REG_FIELD``, where
+"``REG``" refers to the register, and "``FIELD``" refers to the bit or
+bits in ``REG`` that are special.
+
+Again, this is probably best explained by example. On STM32F1, each
+Direct Memory Access (DMA) controller's register map has a certain
+number of channel configuration registers (DMA_CCRx). In each of
+these channel configuration registers, bit 14 is called the
+``MEM2MEM`` bit, and bits 13 and 12 are the priority level (``PL``)
+bits. Here are the register bit definitions for those fields on
+STM32F1::
+
+ #define DMA_CCR_MEM2MEM_BIT 14
+ #define DMA_CCR_MEM2MEM (1U << DMA_CCR_MEM2MEM_BIT)
+ #define DMA_CCR_PL (0x3 << 12)
+ #define DMA_CCR_PL_LOW (0x0 << 12)
+ #define DMA_CCR_PL_MEDIUM (0x1 << 12)
+ #define DMA_CCR_PL_HIGH (0x2 << 12)
+ #define DMA_CCR_PL_VERY_HIGH (0x3 << 12)
+
+Thus, to check if the ``MEM2MEM`` bit is set in DMA controller 1's
+channel configuration register 2 (DMA_CCR2), you can write::
+
+ if (DMA1_BASE->CCR2 & DMA_CCR_MEM2MEM) {
+ /* MEM2MEM is set */
+ }
+
+Certain register values occupy multiple bits. For example, the
+priority level (PL) of a DMA channel is determined by bits 13 and 12
+of the corresponding channel configuration register. As shown above,
+libmaple provides several register bit definitions for masking out the
+individual PL bits and determining their meaning. For example, to set
+the priority level of a DMA transfer to "high priority", you can
+do a read-modify-write sequence on the DMA_CCR_PL bits like so::
+
+ uint32 ccr = DMA1_BASE->CCR2;
+ ccr &= ~DMA_CCR_PL;
+ ccr |= DMA_CCR_PL_HIGH;
+ DMA1_BASE->CCR2 = ccr;
+
+Of course, before doing that, you should check to make sure there's
+not already a device-level function for performing the same task! (In
+this case, there is. It's called :c:func:`dma_set_priority()`; see
+:ref:`libmaple-dma`.) For instance, **none of the above code is
+portable** to STM32F4, which uses DMA streams instead of channels for
+this purpose.
+
+Peripheral Support Routines
+---------------------------
+
+This section describes patterns to look for in peripheral support
+routines.
+
+In general, each device needs to be initialized before it can be used.
+libmaple provides this initialization routine for each peripheral
+``foo``; its name is ``foo_init()``. These initialization routines
+turn on the clock to a device, and restore its register values to
+their default settings. Here are a few examples::
+
+ /* From <libmaple/dma.h> */
+ void dma_init(dma_dev *dev);
+
+ /* From <libmaple/gpio.h> */
+ void gpio_init(gpio_dev *dev);
+ void gpio_init_all(void);
+
+Note that, sometimes, there will be an additional initialization
+routine for all available peripherals of a certain kind.
+
+Many peripherals also need additional configuration before they can be
+used. These functions are usually called something along the lines of
+``foo_enable()``, and often take additional arguments which specify a
+particular configuration for the peripheral. Some examples::
+
+ /* From <libmaple/usart.h> */
+ void usart_enable(usart_dev *dev);
+
+ /* From <libmaple/i2c.h> */
+ void i2c_master_enable(i2c_dev *dev, uint32 flags);
+
+After you've initialized, and potentially enabled, your peripheral, it
+is now time to begin using it. The :ref:`libmaple API pages
+<libmaple-apis>` are your friends here.
+
+.. rubric:: Footnotes
+
+.. [#fgpio] As an exception, GPIO ports are given letters instead of
+ numbers (``GPIOA`` and ``GPIOB`` instead of ``GPIO1`` and
+ ``GPIO2``, etc.).
diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst
new file mode 100644
index 0000000..1ae0e87
--- /dev/null
+++ b/docs/source/libraries.rst
@@ -0,0 +1,80 @@
+.. highlight:: c++
+.. default-domain:: cpp
+
+.. _libraries:
+
+=========================
+ Maple Library Reference
+=========================
+
+.. Note: if you port an Arduino library and document it here, be sure
+.. to update compatibility.rst to reflect that fact.
+
+This page lists the extra libraries that are part of the :ref:`Maple
+IDE <ide>` (along with the rest of :ref:`libmaple <libmaple>`). You
+can use a library from within a sketch by going to Sketch > Import
+Library... from within the IDE, then choosing the library you want.
+
+Any incompatibilities between the Maple and Arduino versions of a
+library are noted in the library's documentation.
+
+.. contents:: Contents
+ :local:
+
+.. toctree::
+ :hidden:
+
+ libs/servo.rst
+ libs/wire.rst
+
+.. admonition:: **Looking for Something Else?**
+
+ - See the :ref:`language` for information on the core functions
+ used for programming a Maple board.
+
+ - If you're looking for something from the C standard library (like
+ ``atoi()``, for instance): the :ref:`CodeSourcery GCC compiler
+ <arm-gcc>` used to compile your programs is configured to link
+ against `newlib <http://sourceware.org/newlib/>`_, and allows the
+ use of any of its header files. However, dynamic memory allocation
+ (``malloc()``, etc.) is not available.
+
+ - If you're looking for low-level hardware support libraries, see
+ the :ref:`libmaple Reference <libmaple>`.
+
+.. _libraries-servo:
+
+Servo
+-----
+
+The :ref:`Servo <libs-servo>` library is provided for convenient
+control of RC servomotors.
+
+.. _libraries-liquid-crystal:
+
+LiquidCrystal
+-------------
+
+.. TODO [0.1.0] LiquidCrystal docs under libs/liquidcrystal.rst
+
+The LiquidCrystal library allows Maple to control LCD screens. For
+more information, see the `Arduino LiquidCrystal documentation
+<http://www.arduino.cc/en/Reference/LiquidCrystal>`_.
+
+**Arduino Compatibility**
+
+At this time, no incompatibilities between the Maple and Arduino
+versions are known (although the Maple version should perform
+significantly faster). Any observed differences should be considered
+bugs, and reported on the forums.
+
+.. _libraries-wire:
+
+Wire
+----
+
+.. FIXME [0.0.13] Update with crenn's info
+
+We currently provide a soft (bit-banged) implementation of the
+:ref:`Wire <libs-wire>` I2C library. A hardware version is planned
+for Maple IDE release 0.1.0.
diff --git a/docs/source/libs/servo.rst b/docs/source/libs/servo.rst
new file mode 100644
index 0000000..80288c6
--- /dev/null
+++ b/docs/source/libs/servo.rst
@@ -0,0 +1,92 @@
+.. highlight:: cpp
+
+.. _libs-servo:
+
+Servo
+=====
+
+This documents the Servo library for controlling RC servomotors. It
+is implemented as a thin layer over the built-in :ref:`timer
+peripherals <timers>`.
+
+You can use this library in the :ref:`IDE <ide>` by choosing the Servo
+item under the Sketch > Import Library... menu.
+
+If you are using the :ref:`Unix toolchain <unix-toolchain>`, the
+library is located in the ``/libraries/Servo/`` :ref:`libmaple`
+directory.
+
+.. contents:: Contents
+ :local:
+
+Servo Class Reference
+---------------------
+
+You can construct a Servo object by including the declaration ::
+
+ Servo servo;
+
+in your sketch. This will create a Servo object called ``servo``.
+You can then use any of its methods; for instance, to control a
+servomotor attached to pin 9, you could write ::
+
+ servo.attach(9);
+
+.. doxygenclass:: Servo
+ :members:
+
+Arduino Compatibility
+---------------------
+
+The Servo class provides a public interface identical to the Arduino
+version's documented functionality (as of Arduino 0021), so in most
+cases, this library will be a drop-in replacement.
+
+However, there are some differences, essentially at the level of
+implementation details.
+
+The major difference is that while the Arduino implementation drives
+servos with "bit-banged" PWM (in the sense that timer interrupt
+handlers are used to manually toggle pins), the Maple implementation
+uses :ref:`timers <timers>` to drive the PWM directly.
+
+Consequently, **the Maple implementation only allows Servo instances
+to attach to pins that support PWM**.
+
+To determine if a pin supports PWM, you can either check if "PWM"
+appears next to its number on your board's silkscreen, or look for it
+in the list of :ref:`boardPWMPins <lang-board-values-pwm-pins>` in
+your board's :ref:`hardware documentation <index-boards>`.
+
+RC Servos expect a pulse approximately every 20ms. In the Maple
+implementation, :ref:`periods <lang-hardwaretimer-setperiod>` are set
+for entire timers, rather than individual channels. Thus,
+``attach()``\ ing a Servo to a pin can interfere with other pins
+associated with the same timer\ [#fard-servo]_.
+
+Because of this, we recommend connecting multiple servomotors to pins
+which share a timer, in order to keep as many timers free for other
+purposes as possible. Consult your board's :ref:`Timer Pin Map
+<gpio-pin-maps>` to match up pins and timer channels.
+
+And here's some fine print:
+
+- Although it is not publicly documented to do so, the Arduino
+ implementation of `attach()
+ <http://arduino.cc/en/Reference/ServoAttach>`_ returns the timer
+ channel associated with the newly-attached pin, or 0 on failure (as
+ of Arduino 0021). The Maple implementation returns :ref:`true
+ <lang-constants-true>` on success, and :ref:`false
+ <lang-constants-false>` on failure (and this is its documented
+ behavior).
+
+- In another bit of undocumented behavior, the Arduino implementation
+ of write() also treats its argument as an angle or a pulse width
+ depending on its value. This is a bad idea, and we don't do it.
+
+.. rubric:: Footnotes
+
+.. [#fard-servo] The Arduino implementation also captures timer
+ channels in groups as more Servo objects are attached, but the
+ details of which channels have their periods reset when are
+ slightly different.
diff --git a/docs/source/libs/wire.rst b/docs/source/libs/wire.rst
new file mode 100644
index 0000000..2c5bed9
--- /dev/null
+++ b/docs/source/libs/wire.rst
@@ -0,0 +1,104 @@
+.. highlight:: cpp
+
+.. _libs-wire:
+
+Wire
+====
+
+.. TODO [0.1.0] Format this correctly, using Breathe
+
+This page documents the Wire library for the :ref:`i2c` protocol. You
+can use this library in the :ref:`Maple IDE <ide>` by choosing the
+Wire item under the Sketch > Import Library... menu.
+
+If you are using the :ref:`Unix toolchain <unix-toolchain>`, the
+library is located in the ``/libraries/Wire/`` :ref:`libmaple`
+directory.
+
+Wire Function Reference
+-----------------------
+
+``Wire.begin()``
+ Joins the i2c bus as master, using pin 20 as SDA and pin 21 as SCL
+ (this is compatible with the pin settings on the Arduino Mega).
+
+``Wire.begin(sda, scl)``
+ Like ``Wire.begin()``, but with the given pins as SDA and
+ SCL.
+
+``Wire.beginTransmission(slave_address)``
+ Set up a transmission to a slave device with the given (7-bit)
+ address. Bytes subsequently queued for transmission (using
+ ``Wire.send``) will be sent to ``slave_address`` when ``void
+ Wire.endTransmission()`` is called.
+
+``void Wire.send(byte)``
+ Queues the given byte (``uint8`` or ``int``) to the slave address
+ previously specified by a call to ``Wire.beginTransmission``. At
+ most 32 bytes may be queued in a single transmission.
+
+``Wire.send(string)``
+ Queues a given string (``char*``) for transmission. The characters
+ of the string are individually queued for transmission as
+ bytes. At most 32 bytes may be queued in a single transmission.
+
+``Wire.send(buffer, length)``
+ Queues a byte buffer ``buffer`` (``uint8*`` or ``int*``), with
+ ``length`` elements, for transmission. At most 32 bytes may be
+ queued in a single transmission.
+
+``Wire.endTransmission()``
+ Ends a transmission (begun by ``Wire.beginTransmission(uint8)``),
+ and actually sends the bytes queued by calls to Wire.send.
+
+ The return value is one of the following status codes:
+
+ * ``SUCCESS``: All bytes were transmitted successfully.
+
+ * ``EDATA``: More than 32 bytes were queued for transmission. No
+ bytes are actually sent when this happens.
+
+ * ``ENACKADDR``: Did not receive ACK on transmit of address. No
+ bytes are actually sent when this happens.
+
+ * ``ENACKTRNS``: Did not receive ACK during transmit of data. Some
+ bytes may have been sent when this happens; however, the
+ transmission is aborted after the first byte of data which is
+ not ACKed by the slave device.
+
+ * ``EOTHER``: Other error occurred.
+
+``Wire.requestFrom(address, num_bytes)``
+ Requests ``num_bytes`` bytes from 7-bit slave address
+ address. Returns the actual number of bytes read. These bytes may
+ subsequently be read one at a time using ``Wire.receive()``.
+
+ Note: if ``num_bytes`` exceeds the size of the transmit/receive
+ buffer (currently 32), it will be truncated to 32.
+
+``Wire.receive()``
+ Get and return the next byte read during the previous call to
+ ``Wire.requestFrom(uint8, int)``. You can check how many bytes are
+ left to read using ``uint8 Wire.available()``.
+
+``Wire.available()``
+ Returns the number of bytes which are still available for reading
+ (with ``Wire.receive()``) from the last call to
+ ``Wire.requestFrom(uint8, int)``.
+
+Arduino Compatibility
+---------------------
+
+.. FIXME [0.1.0] Replace this section when i2c Wire wrapper is done
+
+This implementation is synchronous, and thus supports only a subset of
+the full Wire interface (however, the functionality which is supported
+is fully compatible with Arduino). For now, please use the function
+reference which follows when developing projects using our
+implementation.
+
+Please note that the current implementation only supports master mode
+using a bit-banged (software) protocol. For now, use of the hardware
+:ref:`i2c` peripheral is only available through :ref:`libmaple-i2c`.
+
+
diff --git a/docs/source/maple-ide-install.rst b/docs/source/maple-ide-install.rst
new file mode 100644
index 0000000..7e9bfa2
--- /dev/null
+++ b/docs/source/maple-ide-install.rst
@@ -0,0 +1,176 @@
+.. highlight:: c++
+
+.. _maple-ide-install:
+
+========================
+ Maple IDE Installation
+========================
+
+If you still can't get the IDE installed after reading this page,
+check the :ref:`troubleshooting page <troubleshooting>` for help with
+some common problems. If all else fails, try our `forum`_, or `contact
+us directly`_\ !
+
+.. contents:: Contents
+ :local:
+
+Download
+--------
+
+.. FIXME [RELEASE] Update this for the release.
+
+This documentation was built from a development version of libmaple.
+See the formally released `LeafLabs documentation
+<http://leaflabs.com/docs/>`_ for more information about the current
+Maple IDE release.
+
+.. Choose the correct version for your operating system:
+
+.. .. list-table::
+.. :widths: 15 30
+.. :header-rows: 1
+
+.. * - Platform
+.. - Status
+.. - IDE Package
+.. * - `Windows XP <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-windowsxp32.zip>`_
+.. - Tested on Debian Wheezy (64-bit) and Mint 14.1 (64-bit)
+.. * - `Linux <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-linux32.tgz>`_
+.. - Tested on Ubuntu 10.04 (32-bit)
+.. * - `Mac OS X <http://static.leaflabs.com/pub/leaflabs/maple-ide/maple-ide-0.0.10-macosx-10_6.dmg>`_
+.. - Tested on Snow Leopard (10.6)
+
+The package bundles together a compiler, an upload utility, a software
+library, and a simple GUI text editor. All this software is `free and
+open <http://www.fsf.org/>`_; we are grateful to the `Arduino
+<http://arduino.cc/>`_, `CodeSourcery
+<http://www.codesourcery.com/>`_, `GNU <http://www.gnu.org/>`_, and
+`OpenMoko <http://openmoko.com/>`_ developers, as well as many others,
+who allow us to reuse their software.
+
+**Looking for something older?** `Source archives and binaries
+<http://static.leaflabs.com/pub/leaflabs/maple-ide/>`_ are available
+for previously-released versions.
+
+Installation
+------------
+
+* :ref:`Windows <maple-ide-install-windows>`
+* :ref:`Linux <maple-ide-install-linux>`
+* :ref:`OS X <maple-ide-install-osx>`
+
+.. _maple-ide-install-windows:
+
+Windows XP (Legacy Only)
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note:: Note that while these instructions work on Windows XP,
+ changes in Windows 7 (and later) mean that you won't be able to install the
+ IDE without disabling driver signing on your computer.
+ `Users on the forum have reported a workaround
+ <http://forums.leaflabs.com/topic.php?id=73#post-788>`_, but we
+ only officially support the IDE on 32-bit Windows XP.
+
+First, extract all the files in the ZIP file to a suitable location on
+your system (like your Desktop folder). Next, you have to install
+some drivers. Sorry!
+
+.. _maple-ide-install-windows-drivers:
+
+
+First, install DFU drivers (for uploading code to your Maple) using
+the following steps.
+
+1. Plug your Maple into the USB port.
+
+2. Hit the reset button on your Maple (it's the small button at the
+ bottom left, labeled RESET). Notice that it blinks quickly 6 times,
+ then blinks slowly a few more times.
+
+3. Hit reset again, and this time push and hold the other button
+ during the 6 fast blinks (the button is on the top right; it is
+ labeled BUT). You can release it once the slow blinks start.
+
+4. Your Maple is now in :ref:`perpetual bootloader mode
+ <troubleshooting-perpetual-bootloader>`. This should give you a
+ chance to install the DFU drivers.
+
+5. Windows should now prompt you for some drivers. In the top level
+ directory of the Maple IDE, point Windows to
+ :file:`drivers/mapleDrv/dfu/`.
+
+Next, install serial drivers (for communicating with your Maple using
+serial over USB).
+
+1. Reset your Maple and allow it to exit the bootloader (wait for the
+ slow blinking to stop). The Maple will next start running whatever
+ program was uploaded to it last. (New Maples will start running the
+ test program we upload to them before shipping them to you).
+
+2. Once Maple is running some user code, Windows should prompt you for
+ more drivers. Point windows to :file:`driver/mapleDrv/serial`.
+
+You can now run the Maple IDE by double-clicking on the
+:command:`maple-ide` program from within the extracted IDE directory.
+
+.. _maple-ide-install-linux:
+
+Linux
+^^^^^
+
+.. _maple-ide-install-java:
+.. note::
+
+ The IDE is written in Java and requires a compatible runtime (JRE).
+
+ If you don't have one, they're usually pretty easy to install.
+ Oracle Java 1.6 and OpenJDK 1.6 are known to work, and runtimes
+ mostly compatible with Oracle Java 1.5+ should probably get the job
+ done.
+
+ To install Java, try using your distribution's software packaging
+ tool and search for "JRE" or "java". On Debian-based systems
+ (including Ubuntu) you can try to install the OpenJDK 1.6 JRE
+ with::
+
+ $ sudo aptitude install openjdk-6-jre
+
+Extract the tarball to an appropriate location (like your home
+directory or desktop).
+
+Make sure you have a Java runtime (JRE) installed; if you can run
+:command:`java` from the shell, you should be fine.
+
+Next, run the script :file:`install-udev-rules.sh` in the extracted
+IDE directory. It will ask for root permissions (you will be prompted
+with something along the lines of ``[sudo] password for
+<username>:``). You now need to restart udev::
+
+ $ sudo restart udev
+
+This will grant members of the group ``plugdev`` read/write access to
+Maple devices over USB. Make sure that you are in that group by
+running ``$ sudo adduser <your username> plugdev`` (which will ensure
+access to the Maple, but may report that you are already a member of
+that group). (For more information on why this is part of the install
+process, see the :ref:`Unix toolchain quickstart <toolchain-udev>`).
+
+To run the Maple IDE, run :command:`maple-ide` from the shell, or
+double-click on it if your window system supports it.
+
+Feel free to put the IDE directory wherever you want. As long as you
+leave its internal structure unchanged, things should be fine.
+
+.. _maple-ide-install-osx:
+
+OS X
+^^^^
+
+Double-click on the :file:`.dmg` file you downloaded to mount the disk
+image. From the mounted image, drag and drop the Maple IDE icon into
+your computer's Applications folder.
+
+To run the Maple IDE, double-click the :command:`Maple IDE`
+application you dragged into your computer's :file:`Applications`
+folder.
+
diff --git a/docs/source/maple-quickstart.rst b/docs/source/maple-quickstart.rst
new file mode 100644
index 0000000..a4bc55a
--- /dev/null
+++ b/docs/source/maple-quickstart.rst
@@ -0,0 +1,210 @@
+.. highlight:: sh
+
+.. _maple-quickstart:
+
+========================
+ Maple Quickstart Guide
+========================
+
+.. TODO [0.0.13]: Update the images; e.g., "to FLASH" is now "to Flash"
+..
+.. Consider putting the images as a bundle somewhere under
+.. static.leaflabs.com that gets downloaded and unpacked if they are
+.. not present, but don't get crazy.
+
+You'll need a `Maple board <http://leaflabs.com/store/>`_, a `Mini-B
+USB cable <http://www.google.com/products?q=mini-b+usb+cable>`_, a
+functional computer, and possibly root (or "administrator") access to
+that computer.
+
+If you have trouble along the way, try the :ref:`troubleshooting page
+<troubleshooting>` for help with some common problems. If all else
+fails, try our `forum`_, or `contact`_ us directly!
+
+.. contents:: Contents
+ :local:
+
+.. _maple-quickstart-get-ide:
+
+Install and run the IDE
+-----------------------
+
+See the :ref:`IDE installation page <maple-ide-install>` for instructions.
+
+.. _maple-quickstart-compile-blinky:
+
+Compile a program!
+------------------
+
+Let's load up a simple example program that blinks the status LED.
+From the File menu, select Examples > Digital > Blink:
+
+.. image:: /_static/img/blinky.png
+ :align: center
+ :alt: Click "Blink"
+
+Next, select Tools > Board > "LeafLabs Maple ... to Flash", where
+"..." depends on the board you're using.
+
+.. image:: /_static/img/blinky-to-flash.png
+ :align: center
+ :alt: Upload to Flash
+
+.. note::
+
+ You have the choice between Flash and RAM programming. Flash saves
+ the program into permanent Flash memory. RAM simply puts the
+ compiled program into the processor's built-in RAM.
+
+ Flash memory is larger, and is the only option for permanently
+ uploading a program. Programming to RAM is faster to upload, and a
+ buggy program can be wiped away with a simple reset.
+
+.. image:: /_static/img/verify_button.png
+ :align: left
+ :alt: Verify button
+
+Now press the "Verify" button (the "play" symbol; see image at left)
+to compile the code. Some output should scroll by in the bottom
+window, and then a confirmation message will appear:
+
+.. image:: /_static/img/verify-success.png
+ :align: center
+ :alt: Code verified successfully.
+
+.. _maple-quickstart-upload:
+
+Upload that program!
+--------------------
+
+Now it's time to plug in your Maple. Use a USB Mini-B cable (mini,
+not micro).
+
+On the Maple, make sure that the :ref:`power source jumper
+<maple-powering>` is on the USB header first (the same goes for Maple
+Native). We ship Maples with the power source jumper configured that
+way, so you shouldn't have to do anything. For reference, it should
+look like this (don't worry if a jumper is hanging half off of the
+CHRG header):
+
+.. image:: /_static/img/plugged-in-maple.png
+ :align: center
+ :alt: Correctly plugged in Maple
+
+.. note::
+
+ On OS X, a network interface dialog will pop up every time you plug in
+ the board.
+
+ .. image:: /_static/img/osx-unconfigured-popup.png
+ :align: center
+ :alt: Unconfigured modem popup
+
+ If you click "Network Preferences..." and accept the default ("Not
+ Configured"), the dialog won't pop up and everything will work fine.
+ That is, from this window, click "Apply":
+
+ .. image:: /_static/img/osx-network-prefs-unconfigured.png
+ :align: center
+ :scale: 75%
+ :alt: Click "Apply"
+
+If all systems are go, select your board's serial port in the Tools >
+Serial Port menu. It will appear as something like :file:`COMx`,
+:file:`/dev/ttyACMx`, or :file:`/dev/tty.usbmodemxxxxx`, depending on
+your platform, like so:
+
+Windows XP:
+
+.. image:: /_static/img/serial-port-win.png
+ :align: center
+ :alt: Board type and serial port for Windows XP
+
+Linux:
+
+.. image:: /_static/img/serial-port-ubuntu.png
+ :align: center
+ :alt: Board type and serial port for Linux
+
+OS X:
+
+.. image:: /_static/img/serial-port-mac.png
+ :align: center
+ :alt: Board type and serial port for the OS X
+
+Then press the "Upload" button to upload your program over USB.
+
+.. image:: /_static/img/upload-button.png
+ :align: center
+ :alt: Click the "Upload" button
+
+You should see some text and a progress bar flash by in the status
+window of the IDE, then some quick blinking patterns, followed a
+constant blinking on and off. Congratulations! You've successfully
+uploaded your first program to your Maple.
+
+The built-in status LED should blink in a short pattern every time the
+board is plugged in, reset, or reprogrammed. If it ever starts
+throbbing in a smooth, even pattern, then you've got a problem; see
+this :ref:`troubleshooting item <troubleshooting-throb>` for help.
+
+Next, go ahead and modify the file a little bit. If you change the
+number in the ``delay(1000);`` lines, the speed of the blink will
+change. The number is a time in milliseconds to pause before
+continuing with the program, so by default, the LED will be on for 1
+second, then off for 1 second, etc. Any time you make any changes, go
+through the same Verify and Upload process to upload the new version
+of your program to your Maple.
+
+.. warning::
+
+ The uploading step is the most common source of problems,
+ especially on Windows.
+
+ The situation is much improved over the past, but if you have
+ trouble, try doing things again, unplugging your Maple and plugging
+ it back in, using :ref:`perpetual bootloader mode
+ <troubleshooting-perpetual-bootloader>`, or restarting the
+ IDE.
+
+ If nothing works, please report the problem in the `forum`_.
+
+.. _maple-quickstart-serial-port:
+
+Use the serial port monitor!
+----------------------------
+
+As a last step to make sure everything has been configured correctly,
+let's upload a "Hello, world!" program that will send text from the
+board back to the IDE over the USB connection.
+
+From the File menu, select Examples > Stubs > HelloWorld (similarly to
+how you selected the Blink program), and make sure the correct board
+and serial port targets are selected from the Tools menu.
+
+Open the Serial Monitor window (on the far right of the toolbar). Then
+go back to the code editing window and upload your program. You should
+get text spit at you over the serial monitor right after the program
+is uploaded. Shout back! We can hear you!
+
+Go forth exuberantly!
+---------------------
+
+We really hope you got this far and didn't frown or make a bitter
+lemon face getting here. Where you go now is up to you: perhaps you've
+got some crazy project cooking, or a longer tutorial to work through,
+or maybe now is a good time for a trip to the kitchen for a delicious
+`sandwich <http://everything2.com/title/Velvet+Elvis>`_.
+
+If you blew through this guide and are the kind of person who drinks
+their coffee straight, has more than a 100 lines of vim or emacs
+customization, and doesn't even have a mouse plugged into their
+computer, you may want to look at the :ref:`Unix toolchain quickstart
+<unix-toolchain>` guide. It's the tutorial for getting working with
+your old friends :command:`make`, :command:`gcc`, and :command:`jtag`.
+
+Let us know what you come up with! Reach us at `leaflabs
+<http://twitter.com/#!/leaflabs>`_ on Twitter, post in the `forum`_,
+post on `our wiki's Projects page
+<http://wiki.leaflabs.com/index.php?title=Projects>`_, track us down
+in the real world, whatever. We love projects!
diff --git a/docs/source/prolog.rst b/docs/source/prolog.rst
new file mode 100644
index 0000000..8606555
--- /dev/null
+++ b/docs/source/prolog.rst
@@ -0,0 +1,8 @@
+.. Additions to this file will be included at the beginning of every
+.. .rst file. DO NOT USE IT to insert a header; this is not
+.. recommended by the Sphinx people, who have other ways of doing it.
+
+.. Common substitutions
+.. |vcc| replace:: V\ :sub:`CC`
+.. |vdda| replace:: V\ :sub:`DDA`
+.. |i2c| replace:: I\ :sup:`2`\ C
diff --git a/docs/source/pwm.rst b/docs/source/pwm.rst
new file mode 100644
index 0000000..421229d
--- /dev/null
+++ b/docs/source/pwm.rst
@@ -0,0 +1,103 @@
+.. _pwm:
+
+PWM
+===
+
+Pulse Width Modulation (PWM) is a basic technique to create repeated square
+waves (digital high/low voltage transitions) of user defined length
+and duty cycle. It can be used as a way to encode an "analog" signal
+on a single digital (high/low) line using the time between transitions
+("pulse width") as the variable; this technique is commonly used to
+send servo position and motor speed commands. Another use is to use to
+the ratio of "high" and "low" time to approximate a voltage output;
+this technique can be used to dim an LED or even (with careful
+filtering) generate audio waveforms.
+
+.. contents:: Contents
+ :local:
+
+Overview
+--------
+
+.. FIXME [0.1.0] More information about how timer channels drive PWM
+
+Each PWM output is driven by an output channel connected to one of 4
+timers. Some configuration, such as the clock rate or prescaling,
+must be common to the entire timer; see the :ref:`timer documentation
+<timers>` for more information. See your board's :ref:`pin mapping
+tables <gpio-pin-maps>` to track down the correspondence
+between timer channels and GPIO pins.
+
+Background
+----------
+
+In its simplest form, the device is a single counter with two
+variables. The counter starts at zero, and the output starts at
+"high". The counter increments every clock cycle until it reaches the
+first variable number, at which point the output goes "low". The
+counter continues incrementing until it reaches the second variable at
+which point the output goes "high" again and the counter resets to
+zero. The time spent with output high is called the **pulse duration**
+or **duty**; the total time before repeat is the **period**.
+
+This simple functionality could be approximated in software by setting
+a GPIO high or low, but the beauty of PWM is that user code simply has
+to configure the device and set the two variables and the device will
+function on its own; no further microprocessor cycles will be
+consumed, and a repeated high/low waveform will spew out.
+
+The Maple has 16-bit PWM resolution, which means that the counter and
+variables can be as large as 65535, as opposed to 255 with 8-bit
+resolution. With a 72MHz clock rate, a PWM output could have maximum
+period of about one millisecond; using a :ref:`prescaler
+<lang-hardwaretimer-setprescalefactor>` (clock divider) in front of
+the counter can increase this maximum period. Setting the
+:ref:`period <lang-hardwaretimer-setperiod>` to something other than
+the maximum value gives further control over the total length of the
+waveform. However, this effectively limits the resolution with which
+the duty can be modified: the duty must be less than or equal to the
+period.
+
+Here are some commonly used PWM configurations (note that servos are
+notoriously variable, especially the lower cost models):
+
++-------------+----------+-----------+---------+---------------+------+
+|**Purpose** |**Period**|**Duty** |Prescaler|Period |Duty |
+| |(ms) |(ms) | | | |
++=============+==========+===========+=========+===============+======+
+|LED throb |0.020 |0--0.020 |1 (none) |65535 (default)|0--767|
+| | | | | | |
++-------------+----------+-----------+---------+---------------+------+
+|Servo control|20 |1.25 (0°) |21 |65535 (default)|4096 |
+| | | | | | |
+| | |1.50 (90°) |21 |65535 (default)|4915 |
+| | | | | | |
+| | |1.75 (180°)|21 |65535 (default)|5734 |
+| | | | | | |
++-------------+----------+-----------+---------+---------------+------+
+
+Function Reference
+------------------
+
+- :ref:`lang-pinmode`
+- :ref:`lang-pwmwrite`
+- :ref:`Timer API<lang-hardwaretimer>` (especially :ref:`setOverflow()
+ <lang-hardwaretimer-setoverflow>`, :ref:`setPrescaleFactor()
+ <lang-hardwaretimer-setprescalefactor>`, and :ref:`setPeriod()
+ <lang-hardwaretimer-setperiod>`).
+- :ref:`Timers reference <timers>`.
+
+Recommended Reading
+-------------------
+
+* `Wikipedia Article on Pulse-width modulation
+ <http://en.wikipedia.org/wiki/Pulse-width_modulation>`_
+* `Arduino tutorial on PWM <http://www.arduino.cc/en/Tutorial/PWM>`_
+* `Secrets of Arduino PWM
+ <http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html>`_ by Ken
+ Shirriff
+* `So You Want To Use PWM, Eh? <http://www.nlvocables.com/blog/?p=188>`_ at Non-Lexical Vocables
+* STMicro documentation for STM32F103RB microcontroller:
+
+ * `Datasheet <http://www.st.com/web/en/resource/technical/document/datasheet/CD00161566.pdf>`_ (pdf)
+ * `Reference Manual <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_ (pdf)
diff --git a/docs/source/spi.rst b/docs/source/spi.rst
new file mode 100644
index 0000000..13c4c59
--- /dev/null
+++ b/docs/source/spi.rst
@@ -0,0 +1,30 @@
+.. _spi:
+
+=====
+ SPI
+=====
+
+The Serial Peripheral Interface Bus (SPI) is a serial data transfer
+protocol useful for interacting with a wide variety of hardware
+peripherals.
+
+The public libmaple API for managing the SPI ports is the
+:ref:`HardwareSPI <lang-hardwarespi>` class.
+
+Recommended Reading
+-------------------
+
+* `Wikipedia Article on Serial Peripheral Interface Bus (SPI)
+ <http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus>`_
+
+* `Arduino reference on SPI
+ <http://arduino.cc/en/Reference/SPI>`_
+
+* `Hardcore SPI on Arduino <http://web.archive.org/web/20100522034122/http://klk64.com/arduino-spi/>`_ by kik64
+
+* ST Documentation:
+
+ * Reference Manual `RM0008
+ <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_
+ (PDF), Chapter 25, "Serial Peripheral Interface"
+
diff --git a/docs/source/stm32.rst b/docs/source/stm32.rst
new file mode 100644
index 0000000..d918655
--- /dev/null
+++ b/docs/source/stm32.rst
@@ -0,0 +1,87 @@
+.. _stm32:
+
+Introduction to STM32
+=====================
+
+.. FIXME [v0.0.13] Stub page.
+
+Every Maple board is powered by an STM32 microcontroller (the chip
+which controls all of the pins). Once you're comfortable using your
+Maple, you'll probably start to get curious about what's going on
+under the hood. This page is a good place to begin. It includes an
+overview of the STM32, and helps you make sense of the sometimes
+dizzying array of features, libraries, and documentation that are
+available to you.
+
+The world of the STM32 is a big one, and it's only getting bigger.
+With literally thousands of pages of manuals, datasheets, application
+notes, etc. available for every STM32 microcontroller, and a huge
+variety of categories and subcategories of STM32s available to choose
+from, it's easy to get confused or feel daunted about getting started.
+Don't panic! We've got `your towel
+<http://en.wikipedia.org/wiki/Know_where_one%27s_towel_is#Knowing_where_one.27s_towel_is>`_
+right here.
+
+.. contents:: Contents
+ :local:
+
+.. _stm32-general:
+
+General Information
+-------------------
+
+- Description of the history and present state of the STM32 line. ARM
+ Cortex-M series etc.
+
+- Introduction and pointers to ARM Cortex-M docs and other good books
+ on the subject.
+
+- Pointers to ST reference manuals. Note that the appropriate
+ reference manual for each board is always documented in that board's
+ hardware page.
+
+.. _stm32-series:
+.. _stm32-series-f1-lines:
+
+STM32 Series
+------------
+
+- Describe families, F1 lines, etc.
+
+- Describe how a product name tells you what you need
+
+ST's Documentation
+------------------
+
+- Classes of documentation: product flyer, datasheet, reference
+ manual, programming manual, application note.
+
+.. _stm32-registers:
+
+Registers and Register Maps
+---------------------------
+
+- General purpose registers vs. peripheral registers.
+
+Perhaps you haven't read it in detail, but maybe you've at least
+thumbed through a few of the sections, trying to gain some
+understanding of what's going on. If you've done that (and if you
+haven't, just take our word for it), then you know that underneath the
+covers, *everything* is controlled by messing with bits in the
+seemingly endless collections of registers specific to every
+peripheral. The :ref:`USARTs <usart>` have data registers; (some of
+the) the :ref:`timers <timers>` have capture/compare registers, the
+:ref:`GPIOs <gpio>` have output data registers, etc.
+
+- Peripheral register maps; how they're duplicated for each peripheral
+
+- Portability concerns across series
+
+.. _stm32-libmaple-support:
+
+``libmaple`` STM32 support
+--------------------------
+
+- Descriptions of libmaple's present support for the STM32 line
+ (i.e. currently performance-line only; update when the F2 branch is
+ ready to merge into master etc.).
diff --git a/docs/source/systick.rst b/docs/source/systick.rst
new file mode 100644
index 0000000..afc8d09
--- /dev/null
+++ b/docs/source/systick.rst
@@ -0,0 +1,15 @@
+.. _systick:
+
+SysTick
+=======
+
+.. TODO Recommended reading and more content.
+
+The SysTick peripheral provides a timer which :ref:`libmaple` uses to
+keep track of the board's uptime.
+
+Library Documentation
+---------------------
+
+See :ref:`libmaple-systick` for more information on library support
+for interfacing with the SysTick peripheral.
diff --git a/docs/source/timers.rst b/docs/source/timers.rst
new file mode 100644
index 0000000..0fa0976
--- /dev/null
+++ b/docs/source/timers.rst
@@ -0,0 +1,123 @@
+.. highlight:: cpp
+
+.. _timers:
+
+Timers
+======
+
+There are four general purpose timers in the Maple microcontroller
+that can be configured to generate periodic or delayed events with
+minimal work done by the microcontroller. For example, the :ref:`PWM
+<pwm>` channels can generate regular square-wave signals on specific
+output pins without consuming extra clock cycles. By attaching
+interrupt handlers to these channels (instead of just changing the
+voltage on an external pin), more complex events can be scheduled.
+
+.. contents:: Contents
+ :local:
+
+Introduction
+------------
+
+.. _timers-prescale:
+
+The four timers each have four separate compare channels. Each channel
+has an associated 16-bit counter that can be configured with a 16-bit
+prescaler and a 16-bit overflow value. The prescaler determines how
+fast the counter changes, while the overflow value determines when it
+gets reset.
+
+The prescaler acts as a divider of the 72MHz system clock. That is,
+with a prescaler of 1, the channel's counter increments with a
+frequency of 72MHz, rolling over (passing the maximum 16-bit unsigned
+integer value of 65,535) more than a thousand times a second. With a
+prescaler of 7200, it has a frequency of (72/7200) MHz = 10 KHz,
+rolling over approximately every 6.55 seconds.
+
+The overflow value is the maximum value the counter will go up to. It
+defaults to the full 65,535; smaller values will cause the counter to
+reset to zero more frequently.
+
+Whenever a channel's counter reaches its overflow value, an "update
+event" interrupt is generated. You can configure the Maple to notify
+you when this takes place, by registering an interrupt handler, which
+is a function that will be called when the update event occurs.
+
+By default, different compare values only change the relative offsets
+between events on a single timer ("phase"). They don't control the
+frequency with which they occur. However, a common trick is to
+increment the compare value manually in the interrupt handler so that
+the event will fire again after the increment period. There can be a
+different increment value for each channel, so this trick allows
+events to be programmed at 4 different rates on a single timer. Note
+that function call overheads mean that the smallest increment rate is
+at least a few microseconds.
+
+Library Documentation
+---------------------
+
+See the :ref:`HardwareTimer <lang-hardwaretimer>` reference for more
+information on controlling the built-in timers.
+
+Caveats
+-------
+
+Working with timers and interrupts can be tricky; they are a somewhat
+"advanced" topic. The following subsections explain some common
+problems associated with using timers and timer interrupts.
+
+In general: start simple, test with :ref:`lang-assert`, and don't try
+to do too much in your interrupt handlers! Make sure that what you're
+trying to do in a handler isn't going to block other interrupts from
+firing, if those other interrupts are important for your program.
+
+.. _timers-pwm-conflicts:
+
+PWM Conflicts
+^^^^^^^^^^^^^
+
+Because PWM functionality on a given pin depends on the configuration
+of the timer and channel, you must chose your channels carefully if
+you want to use both timer interrupts and PWM in the same program.
+Refer to your board's timer pin map to match up timer channels and pin
+numbers:
+
+* :ref:`Maple <maple-timer-map>`
+* :ref:`Maple RET6 Edition <maple-ret6-timer-map>`
+* :ref:`Maple Mini <maple-mini-timer-map>`
+* :ref:`Maple Native Beta <maple-native-b-timer-map>`
+
+Overhead
+^^^^^^^^
+
+There is some overhead associated with function and interrupt calls
+(loading and unloading the stack, preparing state, etc.) and this
+overhead can fudge your timing. Imperfect code branching also means
+that, e.g., channel 1 interrupts may get called a couple clock cycles
+sooner than a channel 4 interrupt, all other configuration being the
+same.
+
+Jitter
+^^^^^^
+
+Other interrupts can and will get called before or during the timer
+interrupt routines, causing pseudorandom delays and other
+frustrations.
+
+Disabling the :ref:`USB <usb>` port (by calling ``SerialUSB.end()``,
+or just running off a battery) helps a lot, but then you lose the
+auto-reset and communications functionality. This will require that
+you put your Maple into :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>` before uploading a new program
+to it (or somehow causing your program to re-enable serial over USB
+using :ref:`SerialUSB.begin() <lang-serialusb-begin>`).
+
+The :ref:`SysTick <systick>` peripheral another way to perform
+periodic or delayed events. Its separate timer does not conflict with
+any other peripherals, but the associated 1 kHz interrupt can jitter
+the general purpose timer interrupts. The SysTick peripheral can be
+disabled by calling :ref:`systick_disable()
+<libmaple-systick-disable>`, and re-enabled using
+:ref:`systick_enable() <libmaple-systick-enable>`. However, be aware
+that calling ``systick_disable()`` will stop the values coming from
+:ref:`lang-micros` and :ref:`lang-millis` from increasing.
diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst
new file mode 100644
index 0000000..4d7cbb0
--- /dev/null
+++ b/docs/source/troubleshooting.rst
@@ -0,0 +1,258 @@
+.. highlight:: sh
+
+.. _troubleshooting:
+
+Troubleshooting
+===============
+
+This page documents common problems and their solutions.
+
+.. contents:: Contents
+ :local:
+
+===================
+ Hardware problems
+===================
+
+.. _troubleshooting-throb:
+
+The LED is throbbing and my program is stopped!
+-----------------------------------------------
+
+The LED throbs when there has been a failed software :ref:`ASSERT()
+<lang-assert>` or some other error.
+
+In the case of a failed assertion, a first debugging step you can take
+is to find out the file and line where the failed assertion took place
+(for instructions on this, see the ``ASSERT()`` documentation linked
+to above). This may give you some clue about the source of the error.
+
+:ref:`libmaple` often uses ``ASSERT()`` to halt immediately when it
+detects that something has gone wrong, so if you're not using
+assertions, then what's probably happening is that some bug is causing
+the failed ``ASSERT()`` lower down.
+
+If it's not a failed assertion, then you're likely looking at
+something like a `hard fault
+<http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/ch05s12s01.html>`_.
+
+There are a few issues with the bootloader which mean you might not be
+able to upload your program when this happens. You can still
+reprogram by using :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>`.
+
+My board is bricked! I can't upload via the bootloader no matter what!
+----------------------------------------------------------------------
+
+Don't panic. First, make sure that the board is plugged in correctly
+for program upload, using the instructions given in the
+:ref:`quickstart <maple-quickstart-upload>`. If that doesn't work,
+try using :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>`.
+
+If that doesn't work, then you've got a problem. All is not lost,
+however! You can always try to :ref:`re-flash the bootloader
+<bootloader-reflashing>` over serial (or :ref:`JTAG <jtag>`).
+
+If your board really is bricked, and you think it's our fault,
+`contact us <http://leaflabs.com/contact>`_\ !
+
+My 5v peripheral doesn't work! (I2C, SPI, USART, etc)
+-----------------------------------------------------
+
+Yup, the Maple is a 3.3v board. You may need to use a level
+converter. See the :ref:`Arduino Compatibility
+<arduino-compatibility>`, :ref:`GPIO <gpio>`, or other :ref:`hardware
+specific documentation <index-hardware>` for more information.
+
+The reset and D38/serial buttons don't seem to work reliably!
+-------------------------------------------------------------
+
+A few Maple Rev3 boards shipped in May-June 2010 may have had
+unreliable buttons; see the :ref:`Maple Errata
+<maple-rev3-bad-buttons>` for details. `We're happy to replace these
+for you <http://leaflabs.com/contact>`_\ !
+
+.. _troubleshooting-ide-install:
+
+=======================
+ Installation problems
+=======================
+
+I don't have root/administrator access!
+---------------------------------------
+
+There are probably hacks or work-arounds to getting programs uploaded
+without higher level system permissions. If you can access USB
+character devices (ACM or ttyUSB style), you should be able to
+communicate with the Maple and reprogram using an FTDI converter and
+the serial bootloader, but we haven't tried.
+
+.. TODO: be more helpful
+
+[Linux] I don't use udev!
+-------------------------
+
+There is probably a simple way to get autoconfiguration working with
+devfs; in the meantime, you could try running the entire IDE as root.
+
+.. TODO: be more helpful
+
+.. _troubleshooting-ide-usage:
+
+==============
+ IDE problems
+==============
+
+[Mac OS X] The "Board" and "Serial Port" menu items are missing!
+----------------------------------------------------------------
+
+Sometimes this happens if you try to compile or upload without having
+a board selected. The work-around is to restart the IDE. Mysterious!
+
+.. _troubleshooting-compilation:
+
+==========================
+ Common compiler problems
+==========================
+
+``NullPointerException``
+------------------------
+
+A classic! Make sure you have selected a board from the pulldown menu.
+
+``undefined reference to setup()/loop()``
+-----------------------------------------
+
+Your sketch/program either does not include one of the :ref:`setup()
+<lang-setup>` or :ref:`loop() <lang-loop>` functions, or it was not
+found by the compiler. Your program must include both ``void setup()``
+and ``void loop()`` functions; they don't have to do anything, but
+they **must** be there.
+
+You can start with an example program (to see one in the IDE, click on
+File > Examples > Stubs > BareMinimum) to get the basic structure.
+See also the :ref:`language <language>` documentation.
+
+This is a common error when your entire sketch is blank.
+
+``error: 'Serial' was not declared in this scope``
+--------------------------------------------------
+
+The classic Arduino has only one USART device and uses the unique name
+"Serial" to control it. Larger devices like the Arduino Mega and the
+Maple have multiple USARTS referred to as ``Serial1``, ``Serial2``,
+etc. You probably want ``Serial2`` on the Maple; that's the one
+connected to pins D0 and D1. See also the :ref:`USART docs <usart>`.
+
+``File(s) not found``
+---------------------
+
+There is an intermittent bug with the temporary directory build system
+that on occasion will lose many of the ``#include``\ d libmaple
+files. If you recompile everything, it should be fine.
+
+.. _troubleshooting-upload:
+
+======================
+Common upload problems
+======================
+
+My program is too large!
+------------------------
+
+First, make sure you're using the Flash target instead of RAM; there
+is several times more Flash memory available for user programs.
+
+``No DFU capable USB device found``
+-----------------------------------
+
+This probably means the Maple isn't plugged in or powered on. Try
+unplugging and plugging back in, or pressing the RESET button.
+
+This can also happen if you disable the USB peripheral, e.g. using
+:ref:`SerialUSB.end() <lang-serialusb-end>`.
+
+I have multiple boards plugged in; how do I know which one will get programmed?
+-------------------------------------------------------------------------------
+
+Because the Maple IDE uses DFU to upload programs, you can't select a
+particular board to upload to. There's no solution to this problem
+for now: you'll have to just plug in your boards one at a time. If
+this is a real problem, let us know, and we'll see if we can come up
+with a better solution.
+
+My Flash programs don't seem to stick; they behave like they are RAM!
+---------------------------------------------------------------------
+
+If you have uploaded a program to RAM, this will take priority over
+any program subsequently uploaded to flash. We'll be removing this
+bug in a later version of the bootloader. For now, you can fix this
+by unplugging your Maple to clear the contents of RAM, then plugging
+it back in.
+
+If you are using the :ref:`Unix toolchain <unix-toolchain>`, Make sure
+you :command:`make clean` when switching between Flash and RAM
+targets; our Makefile isn't smart enough to rebuild everything for the
+new target.
+
+My code uploads, but it doesn't work!
+-------------------------------------
+
+Are you sure you have the right board selected? (Maple vs. Maple Mini,
+etc.)
+
+.. _troubleshooting-shell:
+
+===================
+Command-Line Issues
+===================
+
+[Linux] ``cdc_acm 3-1:1.0: no more free acm devices``
+-----------------------------------------------------
+
+This is a nasty one! It means that all 32 possible CDC_ACM serial
+devices (:file:`/dev/ttyACM25`, etc.) have been used up.
+
+The usual cause is using a serial port monitor and not closing it
+before restarting the board or uploading a new program. The operating
+system doesn't like that, and locks up that device. After reset, the
+board comes back up as a new device. If you develop heavily and don't
+restart, you'll blow right through all 32 devices.
+
+The lazy solution is to always close the monitor before restarting,
+and if you get this error in :file:`dmesg` after a dfu-util "Not
+Found" error, restart you machine.
+
+The hacker solution is to restart your cdc_acm kernel module. On
+Ubuntu 9.10, this goes a little something like::
+
+ $ sudo rmmod cdc-acm
+ $ sudo insmod /lib/modules/2.6.31-20-generic/kernel/drivers/usb/class/cdc-acm.ko
+
+.. _troubleshooting-tips-tricks:
+
+===============
+Tips and Tricks
+===============
+
+.. _troubleshooting-perpetual-bootloader:
+
+Perpetual Bootloader Mode
+-------------------------
+
+In this mode, Maple stays a DFU device and does not jump to user code
+until the next reset. This is useful for guaranteeing that your Maple
+will be available for reprogramming.
+
+To put your Maple (or other Maple board) into perpetual bootloader mode:
+
+#. Plug your board into the USB port.
+
+#. Hit the reset button (it's the button labeled RESET). Notice that
+ your board blinks quickly 6 times, then blinks slowly a few more
+ times.
+
+#. Hit reset again, and this time push and hold the other button
+ during the 6 fast blinks (the normal button is labeled BUT). You
+ can release it once the slow blinks start.
diff --git a/docs/source/unix-toolchain-linux-setup.rst b/docs/source/unix-toolchain-linux-setup.rst
new file mode 100644
index 0000000..c1333e1
--- /dev/null
+++ b/docs/source/unix-toolchain-linux-setup.rst
@@ -0,0 +1,203 @@
+.. highlight:: sh
+
+.. _unix-toolchain-linux-setup:
+
+Unix Toolchain Linux Setup
+==========================
+
+This page contains instructions for setting up a Linux computer for
+use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup
+instructions for :ref:`other operating systems <toolchain-setup>` are
+also available.)
+
+These instructions have been tested successfully on:
+
+- Ubuntu 10.04 and 12.04 (32- and 64-bit)
+- Fedora 17 (64-bit)
+- Debian Wheezy 64-bit
+
+Generic instructions for other distributions are also provided. Please
+`contact`_ us with any updates for distros not already covered!
+
+.. contents:: Contents
+ :local:
+
+Collect and Install Tools
+-------------------------
+
+First, you'll need some tools.
+
+.. warning:: Due to firmware bugs in our :ref:`bootloader
+ <bootloader>`, you must use recent versions of ``dfu-util``, or
+ uploads will not work. ``dfu-util`` versions 0.6 and greater
+ should work.
+
+**Debian-based distributions (Debian, Ubuntu, Mint, etc.)**:
+
+ Install mandatory and optional tools with ::
+
+ $ sudo apt-get install build-essential git-core screen dfu-util python python-serial
+
+ On *64-bit distros only*, you will also need to install some 32-bit
+ libraries needed by the LeafLabs-supported :ref:`ARM GCC toolchain
+ <arm-gcc>` with ::
+
+ # 64-bit systems only!
+ $ sudo apt-get install ia32-libs
+
+ # As of Ubuntu 13, you should do this instead:
+ $ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
+
+ You may also need to remove `brltty <http://mielke.cc/brltty/>`_
+ with ::
+
+ # Optional
+ $ sudo apt-get remove brltty
+
+ Brltty provides braille access to the console. It has been reported
+ to cause conflicts with Maple.
+
+**Red Hat-based distributions (RHEL, Fedora, Centos, etc.)**:
+
+ Install mandatory and optional tools with ::
+
+ $ sudo yum install screen git python pyserial dfu-util make
+
+ On *64-bit distros only*, you will also need to install 32-bit
+ libraries needed by the LeafLabs-supported :ref:`ARM GCC toolchain
+ <arm-gcc>` with ::
+
+ # 64-bit systems only!
+ $ sudo yum install glibc.i686
+
+ You may also need to remove `brltty <http://mielke.cc/brltty/>`_
+ with one of these::
+
+ # Optional, 64-bit systems:
+ $ sudo yum erase brltty.x86_64
+
+ # Optional, 32-bit systems:
+ $ sudo yum erase brltty.i686
+
+ Brltty provides braille access to the console. It has been
+ reported to cause conflicts with Maple.
+
+**Other Linux distributions**:
+
+ On other distributions, you'll need to figure this out for yourself
+ (please `contact`_ us if you have instructions for distros not
+ covered here!).
+
+ Mandatory tools:
+
+ * `Git`_ is a distributed version control system. We use it to track
+ our source code.
+
+ * `dfu-util`_ is a tool from the `OpenMoko`_ project. It is used to
+ upload programs to the Maple over USB.
+
+ * `Make <http://www.gnu.org/software/make/>`_ is used to direct
+ compilation.
+
+ * `Python`_ is a programming language. Our reset script, which sends
+ control signals to the board which cause it to to reset and enter
+ the :ref:`bootloader <bootloader>`, is written in Python (and
+ works with Python 2 or 3). Most Linux distributions these days
+ include Python by default.
+
+ * `PySerial`_ is a Python library for interacting with serial port
+ devices. It's needed by our reset script. PySerial can also be
+ installed with `easy_install`_.
+
+ Optional tools:
+
+ * `screen <http://www.gnu.org/s/screen/>`_ is a screen manager used
+ here to connect to serial port devices. (Some popular
+ alternatives are `Minicom
+ <http://alioth.debian.org/projects/minicom/>`_ and `Kermit
+ <http://www.kermitproject.org/>`_).
+
+Fetch ``libmaple`` and Compiler Toolchain
+-----------------------------------------
+
+First, make a Git clone of :ref:`libmaple`::
+
+ $ cd ~
+ $ git clone git://github.com/leaflabs/libmaple.git libmaple
+
+Next, download the `Linux ARM GCC toolchain
+<http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-linux32.tar.gz>`_
+you'll use to build your programs. Extract the archive into a
+directory named :file:`arm`. Put the resulting :file:`arm/bin`
+subdirectory somewhere in your ``PATH``. For example, if you have
+`wget <http://www.gnu.org/software/wget/>`_ installed, you can run::
+
+ $ cd ~/libmaple
+ $ wget http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-linux32.tar.gz
+ $ tar xvf gcc-arm-none-eabi-latest-linux32.tar.gz
+ $ export PATH=$PATH:~/libmaple/arm/bin
+
+You can check that this worked by entering ``arm-none-`` and hitting
+tab to auto-complete; your shell should show a bunch of results. After
+you're done, you'll probably want to update your shell startup script
+so the :file:`arm/bin` directory stays in your ``PATH``.
+
+.. _toolchain-udev:
+
+Install udev Rules
+------------------
+
+From the libmaple directory, copy our udev rules [#fudev]_ to
+``/etc/udev/rules.d``::
+
+ $ sudo cp support/scripts/45-maple.rules /etc/udev/rules.d/45-maple.rules
+
+Then restart udev.
+
+**Ubuntu (NOT Debian)**:
+
+ Make sure you are in the plugdev group (e.g. by running ``$ groups``
+ and seeing if the output includes "plugdev"). If not, add yourself
+ to plugdev with ::
+
+ $ sudo usermod -a -G plugdev $USER
+
+ then log out and log back in.
+
+ After that's done, restart udev::
+
+ $ sudo restart udev
+
+**Debian (NOT Ubuntu)**:
+
+ Make sure you're in the dialout group. If not, add yourself with ::
+
+ $ sudo usermod -a -G dialout $USER
+
+ then log out and log back in.
+
+ After that's done, restart udev::
+
+ $ sudo /etc/init.d/udev restart
+
+**Red Hat-based distros**:
+
+ ::
+
+ $ udevadm control --reload-rules
+
+After restarting ``udev``, you'll need to unplug and re-plug your
+Maple.
+
+So far, so good?
+----------------
+
+Great! Move on by :ref:`compiling a sample program <toolchain-test>`.
+
+.. rubric:: Footnotes
+
+.. [#fudev] As a security precaution on Linux, unknown USB devices can
+ only be accessed by root. This udev script identifies the Maple
+ based on its vendor and product IDs, mounts it to
+ :file:`/dev/maple`, and (for Debian-based distros) grants
+ read/write permissions to the ``plugdev`` group.
diff --git a/docs/source/unix-toolchain-osx-setup.rst b/docs/source/unix-toolchain-osx-setup.rst
new file mode 100644
index 0000000..01b9e2c
--- /dev/null
+++ b/docs/source/unix-toolchain-osx-setup.rst
@@ -0,0 +1,132 @@
+.. highlight:: sh
+
+.. _unix-toolchain-osx-setup:
+
+Unix Toolchain OS X Setup
+=========================
+
+This page contains instructions for setting up an OS X computer for
+use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup
+instructions for :ref:`other operating systems <toolchain-setup>` are
+also available.)
+
+These instructions have been tested successfully on OS X 10.6.4 and
+10.8.1.
+
+.. contents:: Contents
+ :local:
+
+Collect and Install Tools
+-------------------------
+
+First, you'll need some tools. [#fpackman]_
+
+* `XCode <https://developer.apple.com/xcode/>`_: Provides compilers
+ and other basic tools of the trade. XCode seems to only be available for
+ those with Apple IDs through the Mac App Store. If you'd rather not go
+ through that mechanism, you can probably get by with just a `make
+ <http://www.gnu.org/software/make/>`_ binary, but you're on your own.
+
+* `Git`_: All of our code is tracked by a distributed versioning
+ system called Git. A `Mac installer
+ <http://code.google.com/p/git-osx-installer/downloads/list?can=3>`_
+ is available.
+
+* `dfu-util`_: A tool from `OpenMoko`_ that we use to upload programs
+ to the Maple over USB.
+
+ .. warning:: Due to firmware bugs in our :ref:`bootloader
+ <bootloader>`, you must use recent versions of ``dfu-util``, or
+ uploads will not work. ``dfu-util`` versions 0.6 and greater
+ should work.
+
+ If you prefer to compile from source, OpenMoko provides instructions
+ for `building dfu-util on OS X
+ <http://wiki.openmoko.org/wiki/Dfu-util#Mac>`_.
+
+ If you're in a hurry, you can use the dfu-util binary bundled with
+ `OpenMoko Flasher
+ <http://www.handheld-linux.com/wiki.php?page=OpenMoko%20Flasher>`_. To
+ do this, first `download OpenMoko Flasher
+ <http://projects.goldelico.com/p/omflasher/downloads/>`_, then move
+ it to your :file:`/Applications` folder (or wherever you
+ like). Let's say you save it as :file:`/Applications/OpenMoko
+ Flasher.app`. Then the ``dfu-util`` binary resides in
+
+ :file:`/Applications/OpenMoko Flasher.app/Contents/Mac OS/dfu-util`
+
+ To run it from the command line, make a symbolic link to the binary
+ from some place on your ``PATH``::
+
+ $ ln -s /Applications/OpenMoko\ Flasher.app/Contents/Mac\ OS/dfu-util \
+ /somewhere/on/your/PATH/dfu-util
+
+ .. note::
+
+ Copying the binary won't work, as it relies on dynamically linked
+ libraries found elsewhere in the .app bundle.
+
+ To make sure this worked, plug in your Maple, put it into
+ :ref:`perpetual bootloader mode
+ <troubleshooting-perpetual-bootloader>` (press RESET, then quickly
+ press and hold BUT for several seconds), and run ::
+
+ $ dfu-util -l
+
+ The output should look like this::
+
+ Found DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=0, name="DFU Program RAM 0x20000C00"
+ Found DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=1, name="DFU Program FLASH 0x08005000"
+
+* `PySerial`_: our reset script (which sends control signals over the
+ USB-serial connection to restart and enter the bootloader) is
+ written in Python, and requires the PySerial library. Download and
+ extract the `latest version
+ <http://pypi.python.org/pypi/pyserial>`_, then install with ::
+
+ $ cd /path/to/pyserial-x.y
+ $ python setup.py build
+ $ sudo python setup.py install
+
+ PySerial is also available via `easy_install`_, so if you're
+ comfortable using that, you could alternatively install it with ::
+
+ $ easy_install pyserial
+
+Fetch ``libmaple`` and Compiler Toolchain
+-----------------------------------------
+
+First, make a `Git`_ clone of :ref:`libmaple`::
+
+ $ cd ~
+ $ git clone git://github.com/leaflabs/libmaple.git
+
+Next, `download the cross-compilers
+<http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-osx32.tar.gz>`_
+you'll use to build libmaple and your own programs. (These are just
+special-purpose versions of :ref:`GCC <arm-gcc>`).
+
+Let's say you saved these into
+:file:`~/Downloads/gcc-arm-none-eabi-latest-osx32.tar.gz`. Then unpack
+the archive and tell the shell about its contents with::
+
+ $ cd ~/Downloads
+ $ tar -xvf gcc-arm-none-eabi-latest-osx32.tar.gz
+ $ mv arm ~/libmaple/arm
+ $ export PATH=$PATH:~/libmaple/arm/bin
+
+After that's done, update your shell startup script so
+:file:`~/libmaple/arm/bin` stays in your ``PATH``.
+
+So far, so good?
+----------------
+
+Great! Move on by :ref:`compiling a sample program <toolchain-test>`.
+
+.. rubric:: Footnotes
+
+.. [#fpackman] Some of these software packages might be available on
+ `MacPorts <http://www.macports.org/>`_ or `Homebrew
+ <http://mxcl.github.com/homebrew/>`_. The author had some bad
+ experiences with MacPorts a few years ago, though, and hasn't
+ touched a package manager on OS X since. Your mileage may vary.
diff --git a/docs/source/unix-toolchain-win-setup.rst b/docs/source/unix-toolchain-win-setup.rst
new file mode 100644
index 0000000..099e7fe
--- /dev/null
+++ b/docs/source/unix-toolchain-win-setup.rst
@@ -0,0 +1,163 @@
+.. highlight:: sh
+
+.. _unix-toolchain-win-setup:
+
+Unix Toolchain Windows Setup
+============================
+
+This page contains instructions for setting up a Windows computer for
+use with the :ref:`Unix toolchain <unix-toolchain>`. (Setup
+instructions for :ref:`other operating systems <toolchain-setup>` are
+also available.)
+
+These instructions have been tested successfully on Windows 7 Home
+Premium.
+
+.. contents:: Contents
+ :local:
+
+Collect and Install Tools
+-------------------------
+
+First, you'll need some tools.
+
+* `GitHub for Windows <http://windows.github.com/>`_: this is a GUI
+ for `Git`_, the version control system we use for :ref:`libmaple`.
+
+ If you don't have one, you need to sign up for a (free) `GitHub
+ account <https://github.com/signup/free>`_.
+
+ .. note:: If you use Git from the command line, you can clone
+ libmaple with::
+
+ $ git clone git://github.com/leaflabs/libmaple.git
+
+ If you go this route, you don't need a GitHub account.
+
+* `Python`_: choose the **latest 2.7.x version**. (Python 3 works, but
+ you're on your own.)
+
+* `PySerial`_: Choose the latest **pyserial-x.y-win32.exe version**.
+
+Fetch ``libmaple`` and Compiler Toolchain
+-----------------------------------------
+
+First, make a Git clone of the :ref:`libmaple` repository with the
+following steps:
+
+1. **Run GitHub for Windows**, and **sign in** using your GitHub
+ account.
+2. **Visit** `libmaple's GitHub page
+ <https://github.com/leaflabs/libmaple/>`_, and **sign in** to
+ GitHub in your web browser as well.
+3. **Click on the "Clone in Windows" button** on libmaple's GitHub
+ page, which looks like this:
+
+ .. figure:: /_static/img/github-clone-in-windows.png
+
+ Your browser may prompt you about what to do when you click the
+ "Clone in Windows" button. Choose the option that launches the
+ GitHub for Windows application.
+
+Next, you'll need to get some cross-compilers and other tools for
+building and uploading your programs:
+
+- `Download a .zip of the latest tools
+ <http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-win32.zip>`_.
+
+- Extract the .zip, and **move the extracted "arm" folder into the
+ libmaple repository's folder**.
+
+ You can open the libmaple repository folder by right-clicking
+ libmaple in the main GitHub for Windows screen and choosing "open in
+ explorer":
+
+ .. figure:: /_static/img/win7-github-open-in-explorer.png
+ :align: center
+
+Update your PATH
+----------------
+
+You'll next need to configure your system to use the various tools
+you've downloaded and installed. Do that by adding the Python and
+``arm\bin`` directories to your PATH environment variable.
+
+If you've never set environment variables before, this section
+explains what to do.
+
+**Add Python to your PATH**:
+
+ Start by navigating to the folder where Python is installed on your
+ system (this is probably ``C:\Python27``). Right click on the folder
+ address, then choose "Copy address as text":
+
+ .. figure:: /_static/img/win7-copy-python-address.png
+ :align: center
+
+ Next, open your environment variables window: from the Start/Windows
+ menu, right click on Computer, then choose Properties > Advanced
+ System Settings > Environment Variables. Under the "User variables
+ for YOUR_USERNAME", look for PATH.
+
+ - If PATH is missing from the list, click "New...".
+
+ Under "Variable Name", write PATH. Under "Variable value", paste
+ the Python address you just copied, and click OK. The result looks
+ like this:
+
+ .. figure:: /_static/img/win7-python-path.png
+ :align: center
+
+ - If PATH is present in the list, click on it and choose "Edit...".
+
+ Go to the end of the "Variable value:" text box, type a semicolon
+ (the ``;`` character), and then paste the path you just
+ copied. Click OK.
+
+ Test that this worked by running the Git Shell program that came with
+ GitHub for Windows, then running ``python`` at the command prompt. You
+ should get a Python interpreter that looks like this:
+
+ .. figure:: /_static/img/win7-python-prompt.png
+ :align: center
+
+ If that worked, then close the window.
+
+**Add compiler toolchain to your PATH**:
+
+ Do this by adding the ``arm\bin`` directory (earlier instructions
+ had you move ``arm`` to the libmaple repository folder) to your PATH
+ environment variable in the same way you added Python.
+
+ Copy the address of the ``arm\bin`` folder by right-clicking on it
+ after navigating to it:
+
+ .. figure:: /_static/img/win7-copy-arm-bin-address.png
+ :align: center
+
+ The PATH environment variable should exist from when you added
+ Python to it, so make sure you choose "Edit..." from the
+ environment variables window. Then paste the ``arm\bin`` address you
+ copied after typing a semicolon. The final result will look
+ something like this:
+
+ .. figure:: /_static/img/win7-python-arm-bin-path.png
+ :align: center
+
+ Click OK.
+
+So far, so good?
+----------------
+
+Great! Open a new Git Shell, then type this at the prompt and hit
+return to get to the libmaple directory::
+
+ cd libmaple
+
+.. warning:: You must open a new Git Shell window. If you use a shell
+ that's already open, then the changes to PATH you just
+ made won't be available, and the instructions in the next
+ section won't work.
+
+Now you're ready to move on by :ref:`compiling a sample program
+<toolchain-test>`.
diff --git a/docs/source/unix-toolchain.rst b/docs/source/unix-toolchain.rst
new file mode 100644
index 0000000..769b8ec
--- /dev/null
+++ b/docs/source/unix-toolchain.rst
@@ -0,0 +1,375 @@
+.. highlight:: sh
+
+.. _unix-toolchain:
+
+===========================
+ Unix Toolchain Quickstart
+===========================
+
+This is a tutorial for using a standard Unix toolchain (``make``,
+``gcc``, etc.) with Maple. It's intended for C and C++ programmers
+who want to use :ref:`libmaple` directly. If you're just beginning, we
+recommend installing :ref:`Maple IDE <maple-ide-install>` instead.
+
+.. contents:: Contents
+ :local:
+
+Requirements
+------------
+
+We assume you've had success with the :ref:`Maple IDE <ide>` (this is
+important on Windows, as this document doesn't cover :ref:`driver
+installation <maple-ide-install-windows-drivers>`).
+
+At a minimum, you need:
+
+* Maple board
+* Mini-B USB cable
+* root (or Administrator) access to your computer.
+
+On Linux and OS X, you need to know how to use `bash
+<http://www.gnu.org/software/bash/>`_, and how to edit your .bashrc.
+Some experience using `GCC <http://gcc.gnu.org/>`_ and `make
+<http://www.gnu.org/software/make/>`_ is recommended, but is not
+required.
+
+.. _toolchain-linux-setup:
+.. _toolchain-osx-setup:
+.. _toolchain-win-setup:
+.. _toolchain-setup:
+
+Setup
+-----
+
+You first need to set up your computer by installing and configuring
+various things. Don't fret! We've got detailed instructions, just for
+you.
+
+* :ref:`Linux <unix-toolchain-linux-setup>`
+* :ref:`OS X <unix-toolchain-osx-setup>`
+* :ref:`Windows <unix-toolchain-win-setup>`
+
+Come back when you're ready. We'll wait.
+
+.. _toolchain-test:
+
+Test compilation
+----------------
+
+Test that you've installed all the compilation tools correctly by
+running the following commands in your shell.
+
+Windows users:
+
+ - Don't type the ``$``'s, just the parts that come after.
+ - First get to libmaple by opening a Git Shell, then running ``cd libmaple``.
+ - **Always type** ``cs-make`` **instead of** ``make``.
+
+Linux and OS X users:
+
+ - Run these from the top-level libmaple directory.
+
+::
+
+ $ cp main.cpp.example main.cpp
+ $ make clean
+ $ make
+
+If all goes well, you should see a bunch of output, then something
+like this::
+
+ Final Size:
+ text data bss dec hex filename
+ 13164 1704 552 15420 3c3c build/maple.elf
+
+Hurray! You've just compiled your first program for Maple.
+
+**Important: if you're not using Maple (Maple Mini, etc.), make sure
+to read the following note before moving on**.
+
+You can now move on to :ref:`uploading a program <toolchain-upload>`,
+or take a quick detour to learn :ref:`more about the build output
+<toolchain-build-info>`.
+
+.. _toolchain-setting-board:
+
+.. note:: This tutorial assumes you're using a Maple. If you're
+ compiling for another board, you'll need to set a ``BOARD``
+ environment variable appropriately.
+
+ To get a list of values for ``BOARD``, run ::
+
+ $ make list-boards
+
+ For example, to compile for Maple Mini:
+
+ * On OS X or Linux, run::
+
+ $ export BOARD=maple_mini
+ $ make
+
+ * On Windows, set a new environment variable named ``BOARD`` to
+ value ``maple_mini``, then open a new Git Shell, and run ``cd
+ libmaple`` followed by ``cs-make`` as explained above.
+
+ You can check that this worked by making sure that the final
+ program file is named ``build/maple_mini.elf`` instead of
+ ``maple.elf``::
+
+ Final Size:
+ text data bss dec hex filename
+ 16848 2696 704 20248 4f18 build/maple_mini.elf
+
+ Other notes for OS X and Linux:
+
+ - You can also use the following, but you'll need to write the
+ ``BOARD=maple_mini`` part every time you call ``make`` (for
+ ``make install``, etc.)::
+
+ $ BOARD=maple_mini make
+
+ - To make the board setting permanent, add this line to your
+ .bashrc::
+
+ export BOARD=maple_mini
+
+.. warning:: You must start from a clean build after each time you
+ change ``BOARD`` (advanced users: or ``MEMORY_TARGET``). For
+ example, if you compile a program for Maple, then you want to
+ compile another program for Maple Mini, you must run ``$ make
+ clean`` **before** you compile the second program. If you do not,
+ you will experience strange errors.
+
+.. _toolchain-build-info:
+
+Notes about the ``libmaple`` build
+----------------------------------
+
+These are just some miscellaneous notes that are good to know. Feel
+free to skip reading this section.
+
+- The ``dec`` field at the end of the build output under ``Final
+ Size:`` gives the total program size in bytes. The ``text``,
+ ``data``, and ``bss`` fields respectively break down the size of the
+ program into `code <http://en.wikipedia.org/wiki/Code_segment>`_,
+ `initialized data <http://en.wikipedia.org/wiki/Data_segment>`_, and
+ `zero-valued data <http://en.wikipedia.org/wiki/.bss>`_.
+
+- The long list of object files above the ``Final Size`` shows similar
+ information on a per-file basis. You can use it to help slim down
+ programs that use too much space.
+
+- ``build/$BOARD.elf`` is the final build result (where ``BOARD`` is
+ ``maple``, ``maple_mini``, etc. :ref:`depending on your build
+ <toolchain-setting-board>`).
+
+- There are other files under ``build`` you may be interested in, like
+ disassembly and map files.
+
+- If you want quicker build times, you should check out our blog post,
+ `Making libmaple compile faster
+ <http://leaflabs.com/2012/08/2549/>`_.
+
+.. _toolchain-upload:
+
+Upload a program
+----------------
+
+Let's blow away the little example program and upload the interactive
+test session to your Maple. This will let you interact with the Maple
+over a :ref:`USB serial port <usb>`.
+
+* Linux: you need udev rules set up :ref:`as described in the setup
+ doc <toolchain-udev>`.
+
+* Windows: you need to :ref:`install the Maple's device drivers
+ <maple-ide-install-windows-drivers>`.
+
+* OS X: everything Just Works for you. Aren't you special?
+
+Plug in your Maple using a Mini-B USB cable, then run ::
+
+ # Window users: as usual, use cs-make instead of make.
+
+ $ cp examples/test-session.cpp main.cpp
+ $ make clean
+ $ make
+ $ make install
+
+A number of things can go wrong at this stage. Simple debugging steps
+include using :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>`, restarting the Maple a couple
+times, ``make clean``, etc. If nothing works, the `forum`_ is your
+friend.
+
+.. _toolchain-serialusb:
+
+Communicate over USB-Serial
+---------------------------
+
+Now let's try out the interactive test session. You need to connect
+to the board's serial port device file.
+
+* Linux: this looks like :file:`/dev/ttyACM*`.
+* OS X: it looks like :file:`/dev/tty.usbmodem*`.
+* Windows: it will be :file:`COMx`, where ``x`` is some number.
+
+Try using one of these to find out which it is::
+
+ # Linux
+ $ ls /dev/ttyACM*
+
+ # OS X
+ $ ls /dev/tty.usbmodem*
+
+ # Windows, works from libmaple directory
+ $ python support/scripts/win-list-com-ports.py
+
+To open up a session on Linux or OS X, run ::
+
+ $ screen /dev/ttyXXX
+
+(On Windows, you will need to use a separate program, such as Maple
+IDE's serial console or `PuTTY
+<http://www.chiark.greenend.org.uk/~sgtatham/putty/>`_.)
+
+``screen`` will present you an empty terminal. Your board is waiting
+for you to send it a command. Type ``h`` to print a list of commands;
+type any command's letter to run it.
+
+.. highlight:: none
+
+Example output (for Maple)::
+
+ > u
+ Hello World!
+ > b
+ Board information
+ =================
+ * Clock speed (MHz): 72
+ * BOARD_LED_PIN: 13
+ * BOARD_BUTTON_PIN: 38
+ * GPIO information (BOARD_NR_GPIO_PINS = 44):
+ ADC pins (15): 0, 1, 2, 3, 10, 11, 12, 15, 16, 17, 18, 19, 20, 27, 28
+ PWM pins (15): 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28
+ Used pins (7): 13, 38, 39, 40, 41, 42, 43``
+
+.. highlight:: sh
+
+To exit the screen session, type :kbd:`C-a k` (control-a k) on Linux,
+or :kbd:`C-a C-\\` (Control-a, followed by Control-backslash) on OS X,
+and type ``y`` when prompted if you're sure.
+
+.. note::
+
+ Using ``screen`` sometimes messes up your terminal session on OS X.
+ If your shell starts acting funny after you exit ``screen``, you
+ should be able to fix it with ::
+
+ $ reset && clear
+
+ If that doesn't work, just close the Terminal window and open up a
+ new one.
+
+.. _toolchain-projects:
+
+Start your own project
+----------------------
+
+So everything worked, and you want to start your own project? Great!
+There are two ways to go about it.
+
+If your project is small, all you have to do is replace
+:file:`~/libmaple/main.cpp` with your own code, and you're free to use
+``make`` and ``make install`` in the same way you did when you first
+:ref:`uploaded a program <toolchain-upload>`.
+
+If you have a more complicated project, with its own Makefile and
+multiple source files, or if you're using an IDE that creates its own
+Makefile, you'll probably want to load libmaple from an archive (a
+build-time library, not a DLL).
+
+To create an archive, use the ``library`` Makefile target::
+
+ $ cd ~/libmaple
+ $ make library
+
+This will produce a build-time library in the file
+:file:`~/libmaple/build/libmaple.a`. To use it, make sure that you
+link against that library, and that the libmaple sources are in your
+include path.
+
+There is also a page on `starting a project with the Unix toolchain
+<http://wiki.leaflabs.com/index.php?title=Starting_A_Project_%28No_IDE%29>`_
+on the `LeafLabs wiki <http://wiki.leaflabs.com>`_ that you may find
+useful.
+
+Get updates
+-----------
+
+We update libmaple fairly frequently with bugfixes and other
+improvements. In order get access to these in your local copy of the
+repository, you should periodically update it with::
+
+ $ cd ~/libmaple
+ $ git pull
+
+We do our best to keep the master libmaple branch on GitHub free from
+broken or half-finished code, so don't be too scared running the
+latest and greatest. If you do, please report any bugs or regressions!
+
+We keep releases of libmaple and the Maple IDE in lockstep, so any IDE
+updates will have corresponding library updates. Our `blog
+<http://leaflabs.com/blog/>`_ is the place to watch for major
+releases; an `RSS feed <http://leaflabs.com/blog/feed/>`_ is
+available.
+
+You can sign up for a free `GitHub <https://github.com/plans>`_
+account and `watch libmaple
+<https://github.com/leaflabs/libmaple/watchers>`_ to receive
+notifications about bleeding-edge development.
+
+.. _toolchain-openocd:
+
+(Optional) Upload/Debug with JTAG/SWD
+-------------------------------------
+
+Advanced users will wish to use a JTAG (or SWD) dongle for uploading
+and debugging their programs. A big advantage to this approach is that
+it lets you use `GDB <http://www.gnu.org/software/gdb/>`_ to
+single-step through your code, inspect variables, etc.
+
+You can build your projects for JTAG or SWD upload with the ``jtag``
+Makefile target. That is, instead of compiling with ``make``, compile
+with ::
+
+ # (This is equivalent to $ MEMORY_TARGET=jtag make)
+ $ make jtag
+
+Then use your favorite JTAG/SWD dongle and driver software to upload
+the resulting program. An `ELF
+<http://en.wikipedia.org/wiki/Executable_and_Linkable_Format>`_
+suitable for upload is in :file:`build/$BOARD.elf`; the raw binary you
+can copy directly to address 0x0 is :file:`build/$BOARD.bin`.
+
+.. warning:: Uploading code built with the ``jtag`` target will
+ overwrite the :ref:`bootloader <bootloader>`. This is a good thing
+ -- since you're using another upload method, this lets you use the
+ Flash and RAM the bootloader ordinarily reserves for itself. You
+ can always :ref:`reflash the bootloader <bootloader-reflashing>`
+ later.
+
+While LeafLabs doesn't officially support any particular way of using
+JTAG with Maple, there is a `JTAG How-To
+<http://wiki.leaflabs.com/index.php?title=Maple_JTAG_How_To>`_ on the
+`LeafLabs wiki <http://wiki.leaflabs.com>`_ that you may find useful.
+
+.. _toolchain-exuberantly:
+
+Go forth exuberantly!
+---------------------
+
+Let us know what you come up with! Mention `@leaflabs on Twitter
+<http://twitter.com/#!/leaflabs>`_, post in the `forum`_, join the the
+#leafblowers IRC channel on `freenode
+<http://freenode.net/irc_servers.shtml>`_, whatever. We love projects!
diff --git a/docs/source/usart.rst b/docs/source/usart.rst
new file mode 100644
index 0000000..dbbc81c
--- /dev/null
+++ b/docs/source/usart.rst
@@ -0,0 +1,62 @@
+.. _usart:
+
+USART
+=====
+
+A USART is more commonly known a *serial port*. It's used to transmit
+information between Maple and another device (like your computer,
+another Maple, etc.).
+
+.. contents:: Contents
+ :local:
+
+.. _usart-circuit:
+
+Hardware/Circuit Design
+-----------------------
+
+To use a serial port to communicate with an external serial device,
+connect the TX pin to your device's RX pin, the RX to your device's TX
+pin, and your Maple board's ground to your device's ground.
+
+.. warning:: Don't connect these pins directly to an RS232 serial
+ port; they operate at +/- 12V and can damage your board.
+
+Each LeafLabs board has at least 3 separate USART devices. In the most
+simple use case, the RX and TX pins are used to send data at a
+predetermined speed (or *baud rate*). Their usage is documented in
+the :ref:`Serial Ports <lang-serial>` language reference page.
+
+Which pins correspond to the USART TX and RX pins are given on your
+board's silkscreen, and also in the board-specific USART pin maps
+available here:
+
+* :ref:`Maple <maple-usart-map>`
+* :ref:`Maple RET6 Edition <maple-ret6-usart-map>`
+* :ref:`Maple Mini <maple-mini-usart-map>`
+* :ref:`Maple Native Beta <maple-native-b-usart-map>`
+
+If you use a particular serial port, you cannot also use its
+communication pins for other purposes at the same time.
+
+Compatible Devices and Specifications
+-------------------------------------
+
+We have successfully used the USART ports with an FT232R-based
+USB-serial converter at up to 115200 baud. Higher speeds should
+certainly be possible.
+
+Recommended Reading
+-------------------
+
+* `Wikipedia article on Universal Asynchronous Receiver/Transmitter
+ (USART)
+ <http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter>`_
+* `Arduino Serial reference
+ <http://arduino.cc/en/Reference/Serial>`_
+* ST `Reference Manual RM0008
+ <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_
+ (PDF), Chapter 27.
+* `Serial and UART Tutorial
+ <http://www.freebsd.org/doc/en/articles/serial-uart/>`_ (written for
+ FreeBSD, but contains a large amount of general information).
diff --git a/docs/source/usb.rst b/docs/source/usb.rst
new file mode 100644
index 0000000..80c40ca
--- /dev/null
+++ b/docs/source/usb.rst
@@ -0,0 +1,49 @@
+.. highlight:: cpp
+
+.. _usb:
+
+USB
+===
+
+The STM32 microprocessors include a dedicated USB peripheral which can
+be configured to act as a general USB slave device with transfer rates
+up to 12Mbps. (It unfortunately can't be configured as a host or
+on-the-go device). By default, the peripheral is configured for two
+uses: first, to receive sketch/program uploads from the :ref:`IDE
+<ide>`, and second, to emulate a regular serial port for use as a
+terminal (text read/write).
+
+The emulated terminal is relatively slow and inefficient; it is best
+for transferring data at regular serial speeds (kilobaud). Library
+support for accessing the emulated terminal is available at the
+:ref:`SerialUSB <lang-serialusb>` reference.
+
+The SerialUSB channel is used with the :ref:`Maple bootloader
+<bootloader>` to reprogram the board: a :ref:`magic sequence of
+control line toggles and transmitted data <bootloader-rev3>` causes a
+Maple to reset itself and enter bootloader mode. As an unfortunate
+consequence, the auto-reset will not work if the IDE can not access
+the serial port, either due to a conflict with another program (serial
+monitor) or because the interface has been disabled from the Maple
+side (through :ref:`SerialUSB.end() <lang-serialusb-end>`). A
+solution to the second problem is the use of :ref:`perpetual
+bootloader mode <troubleshooting-perpetual-bootloader>`.
+
+Recommended Reading
+-------------------
+
+* `USB in a Nutshell <http://www.beyondlogic.org/usbnutshell/usb1.shtml>`_, an overview from Beyond Logic
+* `USB made simple <http://www.usbmadesimple.co.uk/>`_, an illustrated series of articles on USB
+* The `USB 2.0 Specification <http://www.usb.org/developers/docs/>`_ (`direct link <http://www.usb.org/developers/docs/usb_20_070113.zip>`_)
+* `Embedded USB - a brief tutorial <http://www.computer-solutions.co.uk/info/Embedded_tutorials/usb_tutorial.htm>`_
+* `Wikipedia article on Universal Serial Bus (USB) <http://en.wikipedia.org/wiki/Universal_Serial_Bus>`_
+* Linux Kernel documentation for `USB ACM <http://www.kernel.org/doc/Documentation/usb/acm.txt>`_ and `USB Serial <http://www.kernel.org/doc/Documentation/usb/usb-serial.txt>`_
+* `USB Glossary of Terms <http://belcarra.com/usb_glossary.html>`_
+* ST documentation:
+ * Reference Manual `RM0008
+ <http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf>`_
+ (PDF), Chapter 23, "Universal serial bus full-speed device
+ interface"
+ * Programming Manual `PM0056
+ <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/CD00228163.pdf>`_
+ (PDF; assembly language and register reference)
diff --git a/docs/source/whats-new.rst b/docs/source/whats-new.rst
new file mode 100644
index 0000000..c7d10c5
--- /dev/null
+++ b/docs/source/whats-new.rst
@@ -0,0 +1,81 @@
+.. highlight:: c
+
+What's New
+==========
+
+.. FIXME [RELEASE] finish.
+
+This page tracks updates to libmaple and MapleIDE.
+
+.. contents::
+ :local:
+ :depth: 1
+
+v0.0.13
+-------
+
+.. We started doing this as we updated the docs on 29 Jun 2012, so
+.. updates before then need to be pulled from libmaple's Git logs.
+
+**General Changes**
+
+- Additional STM32 support: for this release, libmaple was taught
+ how to target STM32F1 value line (thanks to Anton Eltchaninov) and
+ STM32F2 series microcontrollers. It learned a huge bag of new
+ tricks as a result, so this list is only a summary of the most
+ important changes.
+
+- New include style: You should now include libmaple and Wirish
+ headers like this (respectively)::
+
+ #include <libmaple/libmaple.h>
+ #include <wirish/wirish.h>
+
+ The old include style (e.g. ``#include "libmaple.h"``) is now
+ **deprecated**, and will **break in the next release**. This is more
+ standard usage for libraries, and was necessary to e.g. allow for
+ implementing a Wiring/Arduino-style SPI library (which is included
+ as ``#include "SPI.h"`` and clashes with :ref:`libmaple-spi` on
+ case-insensitive filesystems like OS X's).
+
+- :ref:`Windows instructions <toolchain-win-setup>` for the
+ :ref:`unix-toolchain`.
+
+**Wirish**
+
+- Wire I2C library: New, improved, and more Arduino-compatible
+ :ref:`Wire <libs-wire>` library, thanks to Trystan Jones.
+
+**libmaple proper**
+
+Better documentation: The old documentation for libmaple's C layer did
+little more than list the Doxygen comments in the source code. It now
+includes explanatory material and usage notes. See
+:ref:`libmaple-apis`.
+
+.. FIXME [0.0.13] this is ugly
+
+Major changes by header follow.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 1 10
+
+ * - Header
+ - Changes
+
+ * - :ref:`libmaple-rcc`
+ - :ref:`rcc_clk_init() <rcc-rcc_clk_init>` is deprecated. Use
+ :ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>` as
+ the basis for a portable replacement; see the
+ ``rcc_clk_init()`` docs for a porting guide.
+
+ * - :ref:`libmaple-libmaple_types`
+ - Various new attributes and type qualifiers.
+
+ * - :ref:`libmaple-adc`
+ - New :ref:`adc_enable_single_swstart()
+ <adc-adc_enable_single_swstart>` and :ref:`adc_config_gpio()
+ <adc-adc_config_gpio>`, for portably enabling ADC peripherals
+ and their associated pins for use with :ref:`adc_read()
+ <adc-adc_read>`.
diff --git a/docs/tmpl/libmaple-proper-page.rst.tmpl b/docs/tmpl/libmaple-proper-page.rst.tmpl
new file mode 100644
index 0000000..c00dd63
--- /dev/null
+++ b/docs/tmpl/libmaple-proper-page.rst.tmpl
@@ -0,0 +1,43 @@
+.. This page is a template for documenting a peripheral support header
+.. in libmaple proper (example: source/libmaple/api/adc.rst).
+..
+.. To use, modify "foo" appropriately, etc. If a section would be
+.. empty (i.e., there are no devices, just register maps) feel free to
+.. leave it out.
+..
+.. It would be nice if, in addition to the base breathe directives,
+.. you flesh out sections as appropriate with free-form text that
+.. helps the user get their job done.
+
+``foo.h``
+=========
+
+Support for Furious Oscillation Ocelots (FOO) peripherals.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. Docs for register map and device types here
+
+Devices
+-------
+
+.. Docs for devices here
+
+Functions
+---------
+
+.. Documented, user-facing functions here
+
+Register Map Base Pointers
+--------------------------
+
+.. RMBPs here
+
+Register Bit Definitions
+------------------------
+
+.. you get the picture