aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2014-08-27 17:36:11 -0400
committerbnewbold <bnewbold@robocracy.org>2014-08-27 17:42:22 -0400
commit34b766c9d5f778762069938c71e052fa40455d1c (patch)
tree3a2b77e636b222fecff6366218cf7845029afecf /docs
parent746d6fecf86572c9fe95dbbffdf541a8d3875dd0 (diff)
parentadd7e54ccaf61859874527feda2b51ea172ce697 (diff)
downloadlibrambutan-34b766c9d5f778762069938c71e052fa40455d1c.tar.gz
librambutan-34b766c9d5f778762069938c71e052fa40455d1c.zip
merge libmaple docs ("leaflabs-docs") into ./docs
In the past, libample documentation was forked out of this repository because the documentation had increased in scope. For the librambutan, and the rambutan project in general, we will try to keep documentation closer to the source code, so the librambutan-specific documentation should live here. Other sections of leaflabs-docs will be culled in a following commit. This merge attempts to maintain history by using a subtree strategy. Followed directions at: http://nuclearsquid.com/writings/subtree-merging-and-you/ Full history for files should be accessible using the "--follow" flag to git log, eg: git log --follow docs/source/adc.rst It should be possible to pull patches from leaflabs-docs with: git pull -s subtree leaflabs-docs master ... at least until the docs in this repository diverge significantly.
Diffstat (limited to 'docs')
-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