aboutsummaryrefslogtreecommitdiffstats
path: root/source/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'source/libmaple')
-rw-r--r--source/libmaple/api/adc.rst12
-rw-r--r--source/libmaple/api/bitband.rst12
-rw-r--r--source/libmaple/api/bkp.rst12
-rw-r--r--source/libmaple/api/dac.rst12
-rw-r--r--source/libmaple/api/delay.rst12
-rw-r--r--source/libmaple/api/dma.rst12
-rw-r--r--source/libmaple/api/exti.rst12
-rw-r--r--source/libmaple/api/flash.rst12
-rw-r--r--source/libmaple/api/fsmc.rst12
-rw-r--r--source/libmaple/api/gpio.rst12
-rw-r--r--source/libmaple/api/i2c.rst12
-rw-r--r--source/libmaple/api/iwdg.rst12
-rw-r--r--source/libmaple/api/libmaple.rst12
-rw-r--r--source/libmaple/api/libmaple_types.rst12
-rw-r--r--source/libmaple/api/nvic.rst12
-rw-r--r--source/libmaple/api/pwr.rst12
-rw-r--r--source/libmaple/api/rcc.rst12
-rw-r--r--source/libmaple/api/ring_buffer.rst12
-rw-r--r--source/libmaple/api/scb.rst12
-rw-r--r--source/libmaple/api/spi.rst12
-rw-r--r--source/libmaple/api/stm32.rst12
-rw-r--r--source/libmaple/api/systick.rst12
-rw-r--r--source/libmaple/api/timer.rst12
-rw-r--r--source/libmaple/api/usart.rst12
-rw-r--r--source/libmaple/api/util.rst12
-rw-r--r--source/libmaple/apis.rst14
-rw-r--r--source/libmaple/coding-standard.rst412
-rw-r--r--source/libmaple/contributing.rst113
-rw-r--r--source/libmaple/overview.rst342
29 files changed, 1181 insertions, 0 deletions
diff --git a/source/libmaple/api/adc.rst b/source/libmaple/api/adc.rst
new file mode 100644
index 0000000..8817055
--- /dev/null
+++ b/source/libmaple/api/adc.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-adc:
+
+``adc.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: adc.h
diff --git a/source/libmaple/api/bitband.rst b/source/libmaple/api/bitband.rst
new file mode 100644
index 0000000..fd57944
--- /dev/null
+++ b/source/libmaple/api/bitband.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-bitband:
+
+``bitband.h``
+=============
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: bitband.h
diff --git a/source/libmaple/api/bkp.rst b/source/libmaple/api/bkp.rst
new file mode 100644
index 0000000..9a697c7
--- /dev/null
+++ b/source/libmaple/api/bkp.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-bkp:
+
+``bkp.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: bkp.h
diff --git a/source/libmaple/api/dac.rst b/source/libmaple/api/dac.rst
new file mode 100644
index 0000000..038753b
--- /dev/null
+++ b/source/libmaple/api/dac.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-dac:
+
+``dac.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: dac.h
diff --git a/source/libmaple/api/delay.rst b/source/libmaple/api/delay.rst
new file mode 100644
index 0000000..a0d013a
--- /dev/null
+++ b/source/libmaple/api/delay.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-delay:
+
+``delay.h``
+===========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: delay.h
diff --git a/source/libmaple/api/dma.rst b/source/libmaple/api/dma.rst
new file mode 100644
index 0000000..1512d0c
--- /dev/null
+++ b/source/libmaple/api/dma.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-dma:
+
+``dma.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: dma.h
diff --git a/source/libmaple/api/exti.rst b/source/libmaple/api/exti.rst
new file mode 100644
index 0000000..2909aa7
--- /dev/null
+++ b/source/libmaple/api/exti.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-exti:
+
+``exti.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: exti.h
diff --git a/source/libmaple/api/flash.rst b/source/libmaple/api/flash.rst
new file mode 100644
index 0000000..6f2f9d3
--- /dev/null
+++ b/source/libmaple/api/flash.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-flash:
+
+``flash.h``
+===========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: flash.h
diff --git a/source/libmaple/api/fsmc.rst b/source/libmaple/api/fsmc.rst
new file mode 100644
index 0000000..cecfc99
--- /dev/null
+++ b/source/libmaple/api/fsmc.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-fsmc:
+
+``fsmc.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: fsmc.h
diff --git a/source/libmaple/api/gpio.rst b/source/libmaple/api/gpio.rst
new file mode 100644
index 0000000..2cfec23
--- /dev/null
+++ b/source/libmaple/api/gpio.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-gpio:
+
+``gpio.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: gpio.h
diff --git a/source/libmaple/api/i2c.rst b/source/libmaple/api/i2c.rst
new file mode 100644
index 0000000..14dd304
--- /dev/null
+++ b/source/libmaple/api/i2c.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-i2c:
+
+``i2c.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: i2c.h
diff --git a/source/libmaple/api/iwdg.rst b/source/libmaple/api/iwdg.rst
new file mode 100644
index 0000000..3911ece
--- /dev/null
+++ b/source/libmaple/api/iwdg.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-iwdg:
+
+``iwdg.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: iwdg.h
diff --git a/source/libmaple/api/libmaple.rst b/source/libmaple/api/libmaple.rst
new file mode 100644
index 0000000..d4f28f0
--- /dev/null
+++ b/source/libmaple/api/libmaple.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-libmaple:
+
+``libmaple.h``
+==============
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: libmaple.h
diff --git a/source/libmaple/api/libmaple_types.rst b/source/libmaple/api/libmaple_types.rst
new file mode 100644
index 0000000..bbea2c1
--- /dev/null
+++ b/source/libmaple/api/libmaple_types.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-libmaple_types:
+
+``libmaple_types.h``
+====================
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: libmaple_types.h
diff --git a/source/libmaple/api/nvic.rst b/source/libmaple/api/nvic.rst
new file mode 100644
index 0000000..b94dc31
--- /dev/null
+++ b/source/libmaple/api/nvic.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-nvic:
+
+``nvic.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: nvic.h
diff --git a/source/libmaple/api/pwr.rst b/source/libmaple/api/pwr.rst
new file mode 100644
index 0000000..82e4864
--- /dev/null
+++ b/source/libmaple/api/pwr.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-pwr:
+
+``pwr.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: pwr.h
diff --git a/source/libmaple/api/rcc.rst b/source/libmaple/api/rcc.rst
new file mode 100644
index 0000000..81dc604
--- /dev/null
+++ b/source/libmaple/api/rcc.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-rcc:
+
+``rcc.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: rcc.h
diff --git a/source/libmaple/api/ring_buffer.rst b/source/libmaple/api/ring_buffer.rst
new file mode 100644
index 0000000..a014fa4
--- /dev/null
+++ b/source/libmaple/api/ring_buffer.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-ring_buffer:
+
+``ring_buffer.h``
+=================
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: ring_buffer.h
diff --git a/source/libmaple/api/scb.rst b/source/libmaple/api/scb.rst
new file mode 100644
index 0000000..78cc7eb
--- /dev/null
+++ b/source/libmaple/api/scb.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-scb:
+
+``scb.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: scb.h
diff --git a/source/libmaple/api/spi.rst b/source/libmaple/api/spi.rst
new file mode 100644
index 0000000..b0c7e86
--- /dev/null
+++ b/source/libmaple/api/spi.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-spi:
+
+``spi.h``
+=========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: spi.h
diff --git a/source/libmaple/api/stm32.rst b/source/libmaple/api/stm32.rst
new file mode 100644
index 0000000..2784540
--- /dev/null
+++ b/source/libmaple/api/stm32.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-stm32:
+
+``stm32.h``
+===========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: stm32.h
diff --git a/source/libmaple/api/systick.rst b/source/libmaple/api/systick.rst
new file mode 100644
index 0000000..5ec906c
--- /dev/null
+++ b/source/libmaple/api/systick.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-systick:
+
+``systick.h``
+=============
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: systick.h
diff --git a/source/libmaple/api/timer.rst b/source/libmaple/api/timer.rst
new file mode 100644
index 0000000..3acbf4f
--- /dev/null
+++ b/source/libmaple/api/timer.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-timer:
+
+``timer.h``
+===========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: timer.h
diff --git a/source/libmaple/api/usart.rst b/source/libmaple/api/usart.rst
new file mode 100644
index 0000000..26e6b9c
--- /dev/null
+++ b/source/libmaple/api/usart.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-usart:
+
+``usart.h``
+===========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: usart.h
diff --git a/source/libmaple/api/util.rst b/source/libmaple/api/util.rst
new file mode 100644
index 0000000..50ffe76
--- /dev/null
+++ b/source/libmaple/api/util.rst
@@ -0,0 +1,12 @@
+.. highlight:: c
+.. _libmaple-util:
+
+``util.h``
+==========
+
+[Stub] support.
+
+Library Documentation
+---------------------
+
+.. doxygenfile:: util.h
diff --git a/source/libmaple/apis.rst b/source/libmaple/apis.rst
new file mode 100644
index 0000000..f493406
--- /dev/null
+++ b/source/libmaple/apis.rst
@@ -0,0 +1,14 @@
+.. _libmaple-apis:
+
+APIs
+====
+
+This is the master index for libmaple proper's APIs.
+
+**Contents**
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ api/*
diff --git a/source/libmaple/coding-standard.rst b/source/libmaple/coding-standard.rst
new file mode 100644
index 0000000..23d20f8
--- /dev/null
+++ b/source/libmaple/coding-standard.rst
@@ -0,0 +1,412 @@
+.. _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.
+
+Vim customizations to do the same thing 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
+----------
+
+- 4 space indents (set in ``.dir-locals.el``).
+
+- Unix newlines. Some exceptions are currently grandfathered in; these
+ will go away in time.
+
+- 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 generally
+ means that if there's ReST documentation for it under libmaple's
+ ``docs/source/``, it needs Doxygen comments, and that ReST should
+ use Breathe to pull that Doxygen comment out. (For more information
+ on this, see libmaple file ``docs/README``).
+
+ There are some exceptions to this rule since Breathe isn't totally
+ mature yet and Sphinx's C++ domain is still in flux. In these
+ cases, document the code "manually" in ReST.
+
+ 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.
+
+- **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/source/libmaple/contributing.rst b/source/libmaple/contributing.rst
new file mode 100644
index 0000000..724605b
--- /dev/null
+++ b/source/libmaple/contributing.rst
@@ -0,0 +1,113 @@
+.. _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).
+
+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>`_.
+
+That said, we'd really prefer a pull request. 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.
+
+* `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.
diff --git a/source/libmaple/overview.rst b/source/libmaple/overview.rst
new file mode 100644
index 0000000..9bce564
--- /dev/null
+++ b/source/libmaple/overview.rst
@@ -0,0 +1,342 @@
+.. highlight:: c
+
+.. _libmaple-overview:
+
+Overview
+========
+
+This page is a general overview of the low-level aspects of libmaple
+proper. It provides a general perspective of the library's goals and
+design. Examples are given from the libmaple sources.
+
+.. contents:: Contents
+ :local:
+
+Design Goals
+------------
+
+The central goal of the libmaple project is to provide a pleasant,
+consistent set of interfaces for dealing with the various peripherals
+on the STM32 line.
+
+Let's start with the basics. If you're interested in low-level details
+on the STM32, then you're going to spend a lot of quality time wading
+through `ST RM0008
+<http://www.st.com/stonline/products/literature/rm/13902.pdf>`_.
+RM0008 is the single most important tool in your toolbox. It is the
+authoritative documentation for the capabilities and low-level
+programming interfaces of ST's line of ARM Cortex M3 microcontrollers.
+
+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 `USARTs <http://leaflabs.com/docs/usart.html>`_ have
+data registers; (some of the) the `timers
+<http://leaflabs.com/docs/timers.html>`_ have capture/compare
+registers, the `GPIOs <http://leaflabs.com/docs/gpio.html>`_ have
+output data registers, etc.
+
+For the most part, Wirish does everything it can to hide this truth
+from you. That's because when you really just want to get your robot
+to fly, your LEDs to blink, 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 messing with registers.
+
+That's fine! In fact, it's our explicit goal for Wirish to be good
+enough that most people never need to know libmaple proper even
+exists. We want to make programming our boards as easy as possible,
+after all. But the day may come when you want to add a library for an
+as-yet unsupported peripheral, or you want to do something we didn't
+anticipate, or you'd like to squeeze a little more speed out of a
+critical section in your program. Or maybe you're just curious!
+
+If anything in the above paragraph describes you, then you'll find
+that you need a way to translate your knowledge of RM0008 into
+software. We imagine (if you're anything like us) you want to spend
+the least amount of time you possibly can doing that
+translation. Ideally, once you've finished your design, you want some
+way to start reading and writing code right away, without having to
+bushwhack your way through a thicket of clunky APIs.
+
+The central abstractions we've chosen to accomplish the above goals
+are *register maps* and *devices*. Register maps are just structs
+which encapsulate the layout of the IO-mapped memory regions
+corresponding to a peripheral's registers. Devices encapsulate a
+peripheral's register map as well as any other necessary information
+needed to operate on it. Peripheral support routines generally
+operate on devices rather than register maps.
+
+Devices
+-------
+
+At the highest level, you'll be dealing with *devices*, where a
+"device" is a general term for any particular piece of hardware you
+might encounter. So, for example, an analog to digital converter is a
+device. So is a USART. So is a GPIO port. In this section, we'll
+consider some hypothetical "xxx" device.
+
+The first thing you need to know is that the header file for dealing
+with xxx devices is, naturally enough, called ``xxx.h``. So if you
+want to interface with the :ref:`ADCs <adc>`, just ``#include
+"adc.h"``.
+
+Inside of ``xxx.h``, there will be a declaration for a ``struct
+xxx_dev`` type. This type encapsulates all of the information we keep
+track of for that xxx. So, for example, in ``adc.h``, there's a
+``struct adc_dev``::
+
+ /** ADC device type. */
+ typedef struct adc_dev {
+ adc_reg_map *regs; /**< Register map */
+ rcc_clk_id clk_id; /**< RCC clock information */
+ } adc_dev;
+
+The ADCs aren't particularly complicated. All we keep track of for an
+ADC device is a pointer to its register map (which keeps track of all
+of its registers' bits; see :ref:`below <libmaple-overview-regmaps>`
+for more details), and an identifying piece of information which tells
+the RCC (reset and clock control) interface how to turn the ADC on and
+reset its registers to their default values.
+
+The timers on the STM32 line are more involved than the ADCs, so a
+``timer_dev`` has to keep track of a bit more information::
+
+ /** Timer device type */
+ typedef struct timer_dev {
+ timer_reg_map_union regs;
+ rcc_clk_id clk_id;
+ timer_type type;
+ voidFuncPtr handlers[];
+ } timer_dev;
+
+However, as you can see, both ADC and timer devices are named
+according to a single scheme, and store similar information.
+
+``xxx.h`` will also declare pointers to the actual devices you need to
+deal with, called ``XXX1``, ``XXX2``, etc. (or just ``XXX``, if
+there's only one) [#fgpio]_. For instance, on the Maple's
+microcontroller (the STM32F103RBT6), there are two ADCs.
+Consequently, in ``adc.h``, there are declarations for dealing with
+ADC devices one and two::
+
+ extern const adc_dev *ADC1;
+ extern const adc_dev *ADC2;
+
+In general, each device needs to be initialized before it can be used.
+libmaple provides this initialization routine for each peripheral
+``xxx``; its name is ``xxx_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 dma.h */
+ void dma_init(dma_dev *dev);
+
+ /* From 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
+``xxx_enable()``, and often take additional arguments which specify a
+particular configuration for the peripheral. Some examples::
+
+ /* From usart.h */
+ void usart_enable(usart_dev *dev);
+
+ /* From 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 file ``xxx.h`` contains other
+convenience functions for dealing with xxx devices. For instance,
+here are a few from ``adc.h``::
+
+ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
+ uint32 adc_read(const adc_dev *dev, uint8 channel);
+
+We aim to enable libmaple's users to interact with peripherals through
+devices as much as possible, rather than having to break the
+abstraction and consider individual registers. However, there will
+always be a need for low-level access. To allow for that, libmaple
+provides *register maps* as a consistent set of names and abstractions
+for dealing with registers and their bits.
+
+.. _libmaple-overview-regmaps:
+
+Register Maps
+-------------
+
+A *register map* is just a C struct which names and provides access to
+a peripheral's registers. These registers are usually mapped to
+contiguous regions of memory (though at times unusable or reserved
+regions exist between a peripheral's registers). Here's an example
+register map, from ``dac.h`` (``__io`` is just libmaple's way of
+saying ``volatile`` when referring to register values)::
+
+ /** DAC register map. */
+ 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 left-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 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 (RM0008:
+DAC_DHR12R1) is the ``DHR12R1`` field in a ``dac_reg_map``. Second,
+if RM0008 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.
+
+So let's say you've included ``xxx.h``, and you want to mess with some
+particular register. What's the name of the ``xxx_reg_map`` variable
+you want? That depends on if there's more than one xxx or not. If
+there's only one xxx, then libmaple guarantees there will be a
+``#define`` that looks like like this::
+
+ #define XXX_BASE ((xxx_reg_map*)0xDEADBEEF)
+
+That is, you're guaranteed there will be a pointer to the (only)
+``xxx_reg_map`` you want, and it will be called
+``XXX_BASE``. (``0xDEADBEEF`` is the register map's *base address*, or
+the fixed location in memory where the register map begins). Here's a
+concrete example from ``dac.h``::
+
+ #define DAC_BASE ((dac_reg_map*)0x40007400)
+
+How can you use these? This is perhaps best explained by example.
+
+* In order to write 2048 to the channel 1 12-bit left-aligned data
+ holding register (RM0008: DAC_DHR12L1), you could write::
+
+ DAC_BASE->DHR12L1 = 2048;
+
+* In order to read the DAC control register, you could write::
+
+ uint32 cr = DAC_BASE->CR;
+
+The microcontroller takes care of converting reads and writes from a
+register's IO-mapped memory regions into reads and writes to the
+corresponding hardware registers.
+
+That covers the case where there's a single xxx peripheral. If
+there's more than one (say, if there are *n*), then ``xxx.h`` provides
+the following::
+
+ #define XXX1_BASE ((xxx_reg_map*)0xDEADBEEF)
+ #define XXX2_BASE ((xxx_reg_map*)0xF00DF00D)
+ ...
+ #define XXXn_BASE ((xxx_reg_map*)0x13AF1AB5)
+
+Here's a concrete example from ``adc.h``::
+
+ /** ADC1 register map base pointer. */
+ #define ADC1_BASE ((adc_reg_map*)0x40012400)
+ /** ADC2 register map base pointer. */
+ #define ADC2_BASE ((adc_reg_map*)0x40012800)
+ /** ADC3 register map base pointer. */
+ #define ADC3_BASE ((adc_reg_map*)0x40013C00)
+
+In order to read from the ADC1's regular data register (where the
+results of ADC conversion are stored), you might write::
+
+ uint32 converted_result = ADC1->DR;
+
+Register Bit Definitions
+------------------------
+
+In ``xxx.h``, there will also be a variety of #defines for dealing
+with interesting bits in the xxx registers, called *register bit
+definitions*. These are named according to the scheme
+``XXX_REG_FIELD``, where "``REG``" refers to the register, and
+"``FIELD``" refers to the bit or bits in ``REG`` that are special.
+
+.. TODO image of the bit layout of a DMA_CCR register
+
+Again, this is probably best explained by example. Each Direct Memory
+Access (DMA) controller's register map has a certain number of channel
+configuration registers (RM0008: 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::
+
+ /* From dma.h */
+
+ #define DMA_CCR_MEM2MEM_BIT 14
+ #define DMA_CCR_MEM2MEM BIT(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 (RM0008: 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
+check the priority level of a DMA transfer, you can write::
+
+ switch (DMA1_BASE->CCR2 & DMA_CCR_PL) {
+ case DMA_CCR_PL_LOW:
+ /* handle low priority case */
+ case DMA_CCR_PL_MEDIUM:
+ /* handle medium priority case */
+ case DMA_CCR_PL_HIGH:
+ /* handle high priority case */
+ case DMA_CCR_PL_VERY_HIGH:
+ /* handle very high priority case */
+ }
+
+Of course, before doing that, you should check to make sure there's
+not already a device-level function for performing the same task!
+
+What Next?
+----------
+
+After you've read this page, you can proceed to the :ref:`libmaple API
+listing <libmaple-apis>`. From there, you can read documentation and
+follow links to the current source code for those files on `libmaple's
+Github page <https://github.com/leaflabs/libmaple>`_.
+
+.. rubric:: Footnotes
+
+.. [#fgpio] For consistency with RM0008, GPIO ports are given letters
+ instead of numbers (``GPIOA`` and ``GPIOB`` instead of
+ ``GPIO1`` and ``GPIO2``, etc.).