aboutsummaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/_static/apilist.html5
-rw-r--r--source/_static/index-style.css19
-rw-r--r--source/_static/leaflabs-docs.css1
-rw-r--r--source/_templates/indexcontent.html117
-rw-r--r--source/_templates/layout.html10
-rw-r--r--source/arm-gcc.rst4
-rw-r--r--source/bootloader.rst6
-rw-r--r--source/conf.py22
-rw-r--r--source/contents.rst70
-rw-r--r--source/faq.rst14
-rw-r--r--source/hardware/maple-mini.rst53
-rw-r--r--source/hardware/maple-native-beta.rst65
-rw-r--r--source/hardware/maple-ret6.rst31
-rw-r--r--source/hardware/maple.rst68
-rw-r--r--source/ide.rst4
-rw-r--r--source/index.rst78
-rw-r--r--source/lang/api/serial.rst1
-rw-r--r--source/lang/cpp/built-in-types.rst12
-rw-r--r--source/language-index.rst6
-rw-r--r--source/language.rst44
-rw-r--r--source/libmaple.rst49
-rw-r--r--source/libmaple/api/adc.rst360
-rw-r--r--source/libmaple/api/bitband.rst4
-rw-r--r--source/libmaple/api/delay.rst11
-rw-r--r--source/libmaple/api/flash.rst296
-rw-r--r--source/libmaple/api/fsmc.rst348
-rw-r--r--source/libmaple/api/iwdg.rst79
-rw-r--r--source/libmaple/api/libmaple.rst4
-rw-r--r--source/libmaple/api/libmaple_types.rst68
-rw-r--r--source/libmaple/api/nvic.rst43
-rw-r--r--source/libmaple/api/rcc-reg-bits.txt1017
-rw-r--r--source/libmaple/api/rcc.rst677
-rw-r--r--source/libmaple/api/ring_buffer.rst4
-rw-r--r--source/libmaple/api/stm32.rst118
-rw-r--r--source/libmaple/api/usart.rst1
-rw-r--r--source/libmaple/api/util.rst19
-rw-r--r--source/libmaple/apis.rst4
-rw-r--r--source/libmaple/overview.rst642
-rw-r--r--source/libraries.rst2
-rw-r--r--source/stm32.rst87
-rw-r--r--source/unix-toolchain.rst16
-rw-r--r--source/whats-new.rst78
42 files changed, 3273 insertions, 1284 deletions
diff --git a/source/_static/apilist.html b/source/_static/apilist.html
deleted file mode 100644
index 556fcc9..0000000
--- a/source/_static/apilist.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{# Filename: .static/apilist.html #}
-{% set parents = parents.pop() %}
-{% if parents %}
-<a href="{{ parents.link|e }}">{{ parents.title }}</a>
-{% endif %}
diff --git a/source/_static/index-style.css b/source/_static/index-style.css
new file mode 100644
index 0000000..d7c42b3
--- /dev/null
+++ b/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/source/_static/leaflabs-docs.css b/source/_static/leaflabs-docs.css
new file mode 100644
index 0000000..18f5bcc
--- /dev/null
+++ b/source/_static/leaflabs-docs.css
@@ -0,0 +1 @@
+/* Any custom CSS you want applied goes here */
diff --git a/source/_templates/indexcontent.html b/source/_templates/indexcontent.html
new file mode 100644
index 0000000..a043f8a
--- /dev/null
+++ b/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/source/_templates/layout.html b/source/_templates/layout.html
index 4d92d33..2fd81ce 100644
--- a/source/_templates/layout.html
+++ b/source/_templates/layout.html
@@ -1,5 +1,11 @@
{% extends "!layout.html" %}
+
+{% set css_files = css_files + ["_static/leaflabs-docs.css"] %}
+
{% block rootrellink %}
- <li><a href="http://leaflabs.com/">LeafLabs</a> |</li>
- {{ super() }}
+ <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/source/arm-gcc.rst b/source/arm-gcc.rst
index 1d55d07..30667a2 100644
--- a/source/arm-gcc.rst
+++ b/source/arm-gcc.rst
@@ -1,8 +1,8 @@
.. _arm-gcc:
-GCC for Maple
-=============
+GCC and libc
+============
This document provides notes on using ``arm-none-eabi-gcc``, the
`CodeSourcery <http://www.codesourcery.com/>`_ version of the GNU `GCC
diff --git a/source/bootloader.rst b/source/bootloader.rst
index e3eb65e..23b0448 100644
--- a/source/bootloader.rst
+++ b/source/bootloader.rst
@@ -584,8 +584,6 @@ DFU pipe and bringing up the USB serial port.
Flashing A Custom Bootloader
----------------------------
-.. FIXME [0.0.13] Update for Maple Native
-
.. 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
@@ -601,9 +599,6 @@ 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.
-This section applies to Maple Rev 3 (or higher), Maple Mini, and Maple
-RET6 Edition.
-
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>`_.
@@ -629,6 +624,7 @@ In order to follow these instructions, you will need:
- `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
diff --git a/source/conf.py b/source/conf.py
index 7380f8e..5b8f2d8 100644
--- a/source/conf.py
+++ b/source/conf.py
@@ -14,7 +14,6 @@
import sys, os
-
# 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.
@@ -37,7 +36,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest',
'sphinx.ext.coverage', 'breathe']
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates', '_static']
+templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
@@ -46,7 +45,7 @@ source_suffix = '.rst'
#source_encoding = 'utf-8-sig'
# The master toctree document.
-master_doc = 'index'
+master_doc = 'contents'
# General information about the project.
project = u'Maple'
@@ -132,11 +131,11 @@ html_theme_options = {
'relbarbgcolor' : 'green',
'headlinkcolor' : '#000000',
'linkcolor' : 'green',
- 'visitedlinkcolor' : 'green',
+ #'visitedlinkcolor' : 'green',
## Font
'headfont' : 'Georgia',
- 'bodyfont' : 'Lucidia'
+ 'bodyfont' : 'Lucida'
}
# Add any paths that contain custom themes here, relative to this directory.
@@ -144,14 +143,14 @@ html_theme_options = {
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-html_title = 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'
+# 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
@@ -172,16 +171,15 @@ html_last_updated_fmt = '%b %d, %Y'
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
-# re-add commented line when custom template for api finished
html_sidebars = {
'**': ['globaltoc.html', 'searchbox.html'],
- #'lang/api**':['searchbox.html', 'apilist.html'],
}
-
# Additional templates that should be rendered to pages, maps page names to
# template names.
-#html_additional_pages = {}
+html_additional_pages = {
+ 'index': 'indexcontent.html'
+}
# If false, no module index is generated.
#html_domain_indices = True
@@ -263,7 +261,7 @@ man_pages = [
# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'http://docs.python.org/': None}
+#intersphinx_mapping = {'http://docs.python.org/': None}
# -- Options for breathe integration ------------------------------------------
diff --git a/source/contents.rst b/source/contents.rst
new file mode 100644
index 0000000..7bb60b8
--- /dev/null
+++ b/source/contents.rst
@@ -0,0 +1,70 @@
+.. _index:
+
+Contents in Full
+================
+
+.. _index-usage:
+
+**Getting Started**
+
+.. toctree::
+ :maxdepth: 2
+
+ maple-quickstart
+ maple-ide-install
+ ide
+ unix-toolchain
+ 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/source/faq.rst b/source/faq.rst
index 937eae8..bd155ae 100644
--- a/source/faq.rst
+++ b/source/faq.rst
@@ -11,16 +11,16 @@
.. _faq-atoi:
-How can I use ``atoi()``, ``strol()``, etc.?
---------------------------------------------
+Can I use ``atoi()``, ``strol()``, etc.?
+----------------------------------------
Just ``#include <stdlib.h>``. See :ref:`arm-gcc-libc` for more
information.
.. _faq-dynamic-memory:
-How can I use ``malloc()``/``new``?
------------------------------------
+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
@@ -107,3 +107,9 @@ featuring a `detailed discussion on pin capability
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/source/hardware/maple-mini.rst b/source/hardware/maple-mini.rst
index 986ab4b..36702dd 100644
--- a/source/hardware/maple-mini.rst
+++ b/source/hardware/maple-mini.rst
@@ -15,7 +15,7 @@ breadboard.
Technical Specifications
------------------------
-* MCU: :ref:`STM32F103RCBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex
+* MCU: :ref:`STM32F103CBT6 <maple-mini-stdocs>`, a 32-bit ARM Cortex
M3 microprocessor
* Clock Speed: **72 MHz**
* **128 KB Flash** and **20 KB SRAM**
@@ -50,9 +50,40 @@ 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**.
-
- See :ref:`this erratum <maple-mini-vin>` for more information.
+ 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
+off 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:
@@ -339,14 +370,12 @@ This section lists known issues and warnings for the Maple Mini Rev 2
.. _maple-mini-vin:
* **Silkscreen Vin voltage mistake**: The silkscreen on the Maple Mini
- falsely indicates that Vin may be supplied with up to 16 V. We
- recommend an input voltage **no greater than 12 V**.
-
- The voltage regulator on the Mini is rated up to 16 V. However, our
- tests indicate that as its input voltage approaches 16 V, its output
- begins to rise to levels higher than those recommended by ST for
- supplying the STM32F103CB. The limit of 12 V keeps the voltage
- supplied to the processor at safe levels.
+ 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
-------------------
diff --git a/source/hardware/maple-native-beta.rst b/source/hardware/maple-native-beta.rst
index f120c05..f1b2284 100644
--- a/source/hardware/maple-native-beta.rst
+++ b/source/hardware/maple-native-beta.rst
@@ -46,20 +46,57 @@ Technical Specifications
Powering the Maple Native
-------------------------
-The Maple Native may be powered from the barrel jack connector, USB,
-or a LiPo battery. The power source is determined by the header
-labeled "PWRSEL" on the silkscreen. 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.
-
-You can also power the Maple Native via the pin labeled "Vin" on the
-vertical header to the right of the PWRSEL 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.
-
-We recommend an input voltage no greater than 12 V.
+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 amount
+off 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
----------------------------------
diff --git a/source/hardware/maple-ret6.rst b/source/hardware/maple-ret6.rst
index d5bf049..21c033b 100644
--- a/source/hardware/maple-ret6.rst
+++ b/source/hardware/maple-ret6.rst
@@ -58,9 +58,20 @@ 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 12 V**.
+ 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.
- See :ref:`this erratum <maple-barrel-jack>` for more information.
+ 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
----------------------------------
@@ -373,11 +384,17 @@ features only available on the STM32F103RET6.
.. _maple-ret6-barrel-jack:
-* **Barrel jack power supply voltage mistake**: The silkscreen next to
- the barrel jack connector incorrectly indicates that up to an 18 V
- input voltage is allowed. **We do not recommend exceeding 12 V**.
-
- See this :ref:`Maple erratum <maple-barrel-jack>` for more
+* **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
diff --git a/source/hardware/maple.rst b/source/hardware/maple.rst
index 610fdfc..aff64d5 100644
--- a/source/hardware/maple.rst
+++ b/source/hardware/maple.rst
@@ -103,15 +103,50 @@ 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 18 V. We recommend a barrel jack input voltage
- **no greater than 12 V**.
-
- Rev5s manufactured after Spring 2011 may still have this error on
- the silk, but it has been marked over.
-
- See :ref:`this erratum <maple-barrel-jack>` for more information.
+ 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 amount
+off 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
----------------------------------
@@ -423,15 +458,16 @@ General
* **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 7
- V — 18 V. In fact, **18 V is too high** and should not be supplied
- to your board. The recommended maximum voltage you should apply is
- **12 V**.
-
- The original voltage regulators used on the Maple were rated up to
- 18 V. However, the voltage regulators on current Maple Revs are
- rated up to 16 V. Our tests indicate that they operate correctly
- through 12 V. We do not recommend higher input voltages.
+ 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:
diff --git a/source/ide.rst b/source/ide.rst
index 6e36e47..e6d49fc 100644
--- a/source/ide.rst
+++ b/source/ide.rst
@@ -1,7 +1,7 @@
.. _ide:
-Maple 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
diff --git a/source/index.rst b/source/index.rst
deleted file mode 100644
index e8f0277..0000000
--- a/source/index.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. _index:
-
-LeafLabs Documentation Index
-============================
-
-Welcome to the LeafLabs documentation!
-
-If you're setting up a board for the first time, try the
-:ref:`quickstart <maple-quickstart>`. If you're having problems,
-check out the :ref:`troubleshooting <troubleshooting>` and :ref:`FAQ
-<faq>` pages.
-
-If you can't find what you're looking for here, try the `LeafLabs wiki
-<http://wiki.leaflabs.com/index.php?title=Main_Page>`_.
-
-.. _index-usage:
-
-**Usage Guides:**
-
-.. toctree::
- :maxdepth: 1
-
- Quickstart <maple-quickstart>
- IDE Installation <maple-ide-install>
- IDE Usage <ide>
- Command-Line Toolchain <unix-toolchain>
-
-.. _index-maple-programming:
-
-**Maple Programming:**
-
-.. toctree::
- :maxdepth: 1
-
- Language <language>
- Libraries <libraries>
- Arduino Compatibility <arduino-compatibility>
- libmaple
- Bootloader <bootloader>
- Troubleshooting <troubleshooting>
- FAQ <faq>
- GCC and libc for Maple <arm-gcc>
- Language Index <language-index>
-
-.. _index-hardware:
-
-**Hardware Peripherals:**
-
-.. toctree::
- :maxdepth: 1
-
- adc
- external-interrupts
- fsmc
- gpio
- i2c
- jtag
- pwm
- spi
- timers
- systick
- usb
- usart
-
-.. _index-boards:
-
-**Board Hardware Documentation:**
-
-.. toctree::
- :maxdepth: 1
-
- 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/source/lang/api/serial.rst b/source/lang/api/serial.rst
index 8c9ebc7..e287015 100644
--- a/source/lang/api/serial.rst
+++ b/source/lang/api/serial.rst
@@ -1,3 +1,4 @@
+.. FIXME [0.0.13] This doesn't include UART4/5, or USART6
.. highlight:: cpp
.. _lang-serial:
diff --git a/source/lang/cpp/built-in-types.rst b/source/lang/cpp/built-in-types.rst
index 28e8cdc..f14dce5 100644
--- a/source/lang/cpp/built-in-types.rst
+++ b/source/lang/cpp/built-in-types.rst
@@ -86,8 +86,8 @@ Floating-Point Types
64-bit, IEEE-754 double-precision floating-point type.
-Other Types
------------
+Miscellaneous Types
+-------------------
.. cpp:type:: voidFuncPtr
@@ -98,3 +98,11 @@ Other Types
.. 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/source/language-index.rst b/source/language-index.rst
index 6c20605..5e4c609 100644
--- a/source/language-index.rst
+++ b/source/language-index.rst
@@ -16,11 +16,7 @@ programmers familiar with the Arduino language.
with different kinds of hardware.
- 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.
+ ``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
diff --git a/source/language.rst b/source/language.rst
index 1a8ef30..a24bb5f 100644
--- a/source/language.rst
+++ b/source/language.rst
@@ -2,9 +2,9 @@
.. _language:
-==========================
- Maple Language Reference
-==========================
+====================
+ Language Reference
+====================
The Maple can be programmed in the `Wiring
<http://www.wiring.org.co/reference/>`_ language, which is the same
@@ -15,17 +15,18 @@ C or C++ programmers who are new to Wiring may wish to skip to the
.. contents:: Contents
:local:
-.. admonition:: **Looking for Something Else?**
+.. 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 the :ref:`unix-toolchain`.
+ - 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>`.
- - Low-level details are in :ref:`libmaple` and this page's
- :ref:`Recommended Reading <language-recommended-reading>`.
+ - An :ref:`stm32` and other :ref:`language-recommended-reading` are
+ also available.
.. _language-lang-docs:
@@ -272,7 +273,7 @@ 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 registers, you are encouraged to move on to the
+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
@@ -419,21 +420,12 @@ Which could plausibly be turned into the final source file ::
Recommended Reading
-------------------
-* :ref:`libmaple Documentation <libmaple>`
-* Your board's :ref:`Board Hardware Documentation <index-boards>` page
-* ST Documentation:
- * Reference Manual `RM0008
- <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_
- (PDF). This is the most important reference work on the STM32
- line, and covers the low-level hardware capabilities and
- interfaces in great detail.
- * `Programming Manual
- <http://www.st.com/stonline/products/literature/pm/15491.pdf>`_
- (PDF). This is an assembly language and register reference for
- the STM32 line.
-* ARM Documentation:
- * `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 much of the the Cortex M3
- Architecture, including instruction timings.
-* `newlib Documentation <http://sourceware.org/newlib/>`_
+* :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/source/libmaple.rst b/source/libmaple.rst
index b06e73e..458241e 100644
--- a/source/libmaple.rst
+++ b/source/libmaple.rst
@@ -5,33 +5,39 @@
``libmaple``
============
-LeafLabs' libmaple (`source code on GitHub
-<https://github.com/leaflabs/libmaple>`_) is the library we have
-developed for the `STM32 <http://www.st.com/stonline>`_ line of ARM
-Cortex M3 microcontrollers. Its high-level interfaces are
-:ref:`largely compatible <arduino-compatibility>` with the AVR
-libraries written for the `Arduino <http://arduino.cc>`_ and `Wiring
-<http://wiring.org.co/>`_ development boards.
+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 lower level layer written in pure
-C, which we call *libmaple proper* (in the `libmaple/
-<https://github.com/leaflabs/libmaple/tree/master/libmaple>`_
-directory of the source repository), and the Wiring-style C++ API
-written on top of it, called *Wirish* (in `wirish/
-<https://github.com/leaflabs/libmaple/tree/master/wirish>`_; the
-wirish APIs are :ref:`summarized here <language>`, with an :ref:`index
-here <language-index>`).
+Libmaple is split into two pieces:
-libmaple is bundled with the :ref:`Maple IDE <ide>`. However, we
-develop it separately, and :ref:`release it standalone
-<unix-toolchain>` for advanced users who might chafe at the "sketch"
-programming model of the IDE.
+- 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.
-As always, :ref:`patches are welcome <libmaple-contributing>`.
+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.
-**Contents:**
+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
@@ -40,4 +46,3 @@ As always, :ref:`patches are welcome <libmaple-contributing>`.
libmaple/apis
libmaple/contributing
libmaple/coding-standard
-
diff --git a/source/libmaple/api/adc.rst b/source/libmaple/api/adc.rst
index fecaece..2f06926 100644
--- a/source/libmaple/api/adc.rst
+++ b/source/libmaple/api/adc.rst
@@ -1,24 +1,31 @@
.. highlight:: c
.. _libmaple-adc:
-``adc.h``
-=========
+``<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
-Types
------
+Devices
+-------
+
+The individual ADC peripherals have the following device struct.
.. doxygenstruct:: adc_dev
-.. doxygenstruct:: adc_reg_map
-.. doxygenenum:: adc_extsel_event
-.. doxygenenum:: adc_smp_rate
-Devices
--------
+The available ADC peripherals vary by target. The complete list is
+``ADC1``, ``ADC2``, and ``ADC3``.
.. doxygenvariable:: ADC1
.. doxygenvariable:: ADC2
@@ -27,189 +34,198 @@ Devices
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
-.. doxygenfunction:: adc_calibrate
-.. doxygenfunction:: adc_set_extsel
+.. _adc-adc_enable:
.. doxygenfunction:: adc_enable
+.. _adc-adc_disable:
.. doxygenfunction:: adc_disable
+.. _adc-adc_disable_all:
.. doxygenfunction:: adc_disable_all
-.. doxygenfunction:: adc_foreach
-.. doxygenfunction:: adc_set_sample_rate
+
+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
-.. doxygenfunction:: adc_set_exttrig
+.. _adc-adc_set_extsel:
+.. doxygenfunction:: adc_set_extsel
-Register Map Base Pointers
---------------------------
+.. _adc-adc_extsel_event:
-.. doxygendefine:: ADC1_BASE
-.. doxygendefine:: ADC2_BASE
-.. doxygendefine:: ADC3_BASE
+The last of these, :ref:`adc_set_extsel() <adc-adc_set_extsel>`, takes
+a target-dependent ``adc_extsel_event`` argument.
-Register Bit Definitions
-------------------------
+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
-Status register
+.. _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
~~~~~~~~~~~~~~~
-.. doxygendefine:: ADC_SR_AWD_BIT
-.. doxygendefine:: ADC_SR_EOC_BIT
-.. doxygendefine:: ADC_SR_JEOC_BIT
-.. doxygendefine:: ADC_SR_JSTRT_BIT
-.. doxygendefine:: ADC_SR_STRT_BIT
-
-.. doxygendefine:: ADC_SR_AWD
-.. doxygendefine:: ADC_SR_EOC
-.. doxygendefine:: ADC_SR_JEOC
-.. doxygendefine:: ADC_SR_JSTRT
-.. doxygendefine:: ADC_SR_STRT
-
-Control register 1
-~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_CR1_EOCIE_BIT
-.. doxygendefine:: ADC_CR1_AWDIE_BIT
-.. doxygendefine:: ADC_CR1_JEOCIE_BIT
-.. doxygendefine:: ADC_CR1_SCAN_BIT
-.. doxygendefine:: ADC_CR1_AWDSGL_BIT
-.. doxygendefine:: ADC_CR1_JAUTO_BIT
-.. doxygendefine:: ADC_CR1_DISCEN_BIT
-.. doxygendefine:: ADC_CR1_JDISCEN_BIT
-.. doxygendefine:: ADC_CR1_JAWDEN_BIT
-.. doxygendefine:: ADC_CR1_AWDEN_BIT
-
-.. doxygendefine:: ADC_CR1_AWDCH
-.. doxygendefine:: ADC_CR1_EOCIE
-.. doxygendefine:: ADC_CR1_AWDIE
-.. doxygendefine:: ADC_CR1_JEOCIE
-.. doxygendefine:: ADC_CR1_SCAN
-.. doxygendefine:: ADC_CR1_AWDSGL
-.. doxygendefine:: ADC_CR1_JAUTO
-.. doxygendefine:: ADC_CR1_DISCEN
-.. doxygendefine:: ADC_CR1_JDISCEN
-.. doxygendefine:: ADC_CR1_DISCNUM
-.. doxygendefine:: ADC_CR1_JAWDEN
-.. doxygendefine:: ADC_CR1_AWDEN
-
-Control register 2
-~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_CR2_ADON_BIT
-.. doxygendefine:: ADC_CR2_CONT_BIT
-.. doxygendefine:: ADC_CR2_CAL_BIT
-.. doxygendefine:: ADC_CR2_RSTCAL_BIT
-.. doxygendefine:: ADC_CR2_DMA_BIT
-.. doxygendefine:: ADC_CR2_ALIGN_BIT
-.. doxygendefine:: ADC_CR2_JEXTTRIG_BIT
-.. doxygendefine:: ADC_CR2_EXTTRIG_BIT
-.. doxygendefine:: ADC_CR2_JSWSTART_BIT
-.. doxygendefine:: ADC_CR2_SWSTART_BIT
-.. doxygendefine:: ADC_CR2_TSEREFE_BIT
-
-.. doxygendefine:: ADC_CR2_ADON
-.. doxygendefine:: ADC_CR2_CONT
-.. doxygendefine:: ADC_CR2_CAL
-.. doxygendefine:: ADC_CR2_RSTCAL
-.. doxygendefine:: ADC_CR2_DMA
-.. doxygendefine:: ADC_CR2_ALIGN
-.. doxygendefine:: ADC_CR2_JEXTSEL
-.. doxygendefine:: ADC_CR2_JEXTTRIG
-.. doxygendefine:: ADC_CR2_EXTSEL
-.. doxygendefine:: ADC_CR2_EXTTRIG
-.. doxygendefine:: ADC_CR2_JSWSTART
-.. doxygendefine:: ADC_CR2_SWSTART
-.. doxygendefine:: ADC_CR2_TSEREFE
-
-Sample time register 1
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_SMPR1_SMP17
-.. doxygendefine:: ADC_SMPR1_SMP16
-.. doxygendefine:: ADC_SMPR1_SMP15
-.. doxygendefine:: ADC_SMPR1_SMP14
-.. doxygendefine:: ADC_SMPR1_SMP13
-.. doxygendefine:: ADC_SMPR1_SMP12
-.. doxygendefine:: ADC_SMPR1_SMP11
-.. doxygendefine:: ADC_SMPR1_SMP10
-
-Sample time register 2
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_SMPR2_SMP9
-.. doxygendefine:: ADC_SMPR2_SMP8
-.. doxygendefine:: ADC_SMPR2_SMP7
-.. doxygendefine:: ADC_SMPR2_SMP6
-.. doxygendefine:: ADC_SMPR2_SMP5
-.. doxygendefine:: ADC_SMPR2_SMP4
-.. doxygendefine:: ADC_SMPR2_SMP3
-.. doxygendefine:: ADC_SMPR2_SMP2
-.. doxygendefine:: ADC_SMPR2_SMP1
-.. doxygendefine:: ADC_SMPR2_SMP0
-
-Injected channel data offset register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_JOFR_JOFFSET
-
-Watchdog high threshold register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_HTR_HT
-
-Watchdog low threshold register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: ADC_LTR_LT
-
-Regular sequence register 1
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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.
-.. doxygendefine:: ADC_SQR1_L
-.. doxygendefine:: ADC_SQR1_SQ16
-.. doxygendefine:: ADC_SQR1_SQ15
-.. doxygendefine:: ADC_SQR1_SQ14
-.. doxygendefine:: ADC_SQR1_SQ13
+.. 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.
-Regular sequence register 2
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. 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.
-.. doxygendefine:: ADC_SQR2_SQ12
-.. doxygendefine:: ADC_SQR2_SQ11
-.. doxygendefine:: ADC_SQR2_SQ10
-.. doxygendefine:: ADC_SQR2_SQ9
-.. doxygendefine:: ADC_SQR2_SQ8
-.. doxygendefine:: ADC_SQR2_SQ7
+.. doxygenfunction:: adc_set_sample_rate
-Regular sequence register 3
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. _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
+~~~~~~~~~~~~~
-.. doxygendefine:: ADC_SQR3_SQ6
-.. doxygendefine:: ADC_SQR3_SQ5
-.. doxygendefine:: ADC_SQR3_SQ4
-.. doxygendefine:: ADC_SQR3_SQ3
-.. doxygendefine:: ADC_SQR3_SQ2
-.. doxygendefine:: ADC_SQR3_SQ1
+.. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up?
-Injected sequence register
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. _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
-.. doxygendefine:: ADC_JSQR_JL
-.. doxygendefine:: ADC_JSQR_JL_1CONV
-.. doxygendefine:: ADC_JSQR_JL_2CONV
-.. doxygendefine:: ADC_JSQR_JL_3CONV
-.. doxygendefine:: ADC_JSQR_JL_4CONV
-.. doxygendefine:: ADC_JSQR_JSQ4
-.. doxygendefine:: ADC_JSQR_JSQ3
-.. doxygendefine:: ADC_JSQR_JSQ2
-.. doxygendefine:: ADC_JSQR_JSQ1
+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
+------------------------
-Injected data registers
-~~~~~~~~~~~~~~~~~~~~~~~
+.. TODO [0.0.13]
-.. doxygendefine:: ADC_JDR_JDATA
+TODO
-Regular data register
-~~~~~~~~~~~~~~~~~~~~~
+.. rubric:: Footnotes
-.. doxygendefine:: ADC_DR_ADC2DATA
-.. doxygendefine:: ADC_DR_DATA
+.. [#fchansamp] Per-channel sample time configuration is possible,
+ but currently unsupported.
diff --git a/source/libmaple/api/bitband.rst b/source/libmaple/api/bitband.rst
index 5251015..768f678 100644
--- a/source/libmaple/api/bitband.rst
+++ b/source/libmaple/api/bitband.rst
@@ -1,8 +1,8 @@
.. highlight:: c
.. _libmaple-bitband:
-``bitband.h``
-=============
+``<libmaple/bitband.h>``
+========================
Bit-banding support.
diff --git a/source/libmaple/api/delay.rst b/source/libmaple/api/delay.rst
index 5d0397d..d11496b 100644
--- a/source/libmaple/api/delay.rst
+++ b/source/libmaple/api/delay.rst
@@ -1,12 +1,11 @@
.. highlight:: c
.. _libmaple-delay:
-``delay.h``
-===========
+``<libmaple/delay.h>``
+======================
-Simple busy-loop delaying.
-
-Functions
----------
+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/source/libmaple/api/flash.rst b/source/libmaple/api/flash.rst
index 8a7e79b..52ff4d2 100644
--- a/source/libmaple/api/flash.rst
+++ b/source/libmaple/api/flash.rst
@@ -1,97 +1,249 @@
.. highlight:: c
.. _libmaple-flash:
-``flash.h``
-===========
+``<libmaple/flash.h>``
+======================
-Flash support.
+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:
-Types
------
+Devices
+-------
-.. doxygenstruct:: flash_reg_map
+None at this time.
Functions
---------
-.. doxygenfunction:: flash_enable_prefetch
+The following functions can be used to portably manipulate Flash memory.
+
.. doxygenfunction:: flash_set_latency
+.. doxygenfunction:: flash_enable_features
+.. doxygenfunction:: flash_enable_prefetch
-Register Map Base Pointers
---------------------------
+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
------------------------
-Access control register
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FLASH_ACR_PRFTBS_BIT
-.. doxygendefine:: FLASH_ACR_PRFTBE_BIT
-.. doxygendefine:: FLASH_ACR_HLFCYA_BIT
+These are given as source code. Available register bit definitions
+vary by target.
-.. doxygendefine:: FLASH_ACR_PRFTBS
-.. doxygendefine:: FLASH_ACR_PRFTBE
-.. doxygendefine:: FLASH_ACR_HLFCYA
-.. doxygendefine:: FLASH_ACR_LATENCY
+STM32F1 Targets
+~~~~~~~~~~~~~~~
-Status register
+::
+
+ /* 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
~~~~~~~~~~~~~~~
-.. doxygendefine:: FLASH_SR_EOP_BIT
-.. doxygendefine:: FLASH_SR_WRPRTERR_BIT
-.. doxygendefine:: FLASH_SR_PGERR_BIT
-.. doxygendefine:: FLASH_SR_BSY_BIT
-
-.. doxygendefine:: FLASH_SR_EOP
-.. doxygendefine:: FLASH_SR_WRPRTERR
-.. doxygendefine:: FLASH_SR_PGERR
-.. doxygendefine:: FLASH_SR_BSY
-
-Control register
-~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FLASH_CR_EOPIE_BIT
-.. doxygendefine:: FLASH_CR_ERRIE_BIT
-.. doxygendefine:: FLASH_CR_OPTWRE_BIT
-.. doxygendefine:: FLASH_CR_LOCK_BIT
-.. doxygendefine:: FLASH_CR_STRT_BIT
-.. doxygendefine:: FLASH_CR_OPTER_BIT
-.. doxygendefine:: FLASH_CR_OPTPG_BIT
-.. doxygendefine:: FLASH_CR_MER_BIT
-.. doxygendefine:: FLASH_CR_PER_BIT
-.. doxygendefine:: FLASH_CR_PG_BIT
-
-.. doxygendefine:: FLASH_CR_EOPIE
-.. doxygendefine:: FLASH_CR_ERRIE
-.. doxygendefine:: FLASH_CR_OPTWRE
-.. doxygendefine:: FLASH_CR_LOCK
-.. doxygendefine:: FLASH_CR_STRT
-.. doxygendefine:: FLASH_CR_OPTER
-.. doxygendefine:: FLASH_CR_OPTPG
-.. doxygendefine:: FLASH_CR_MER
-.. doxygendefine:: FLASH_CR_PER
-.. doxygendefine:: FLASH_CR_PG
-
-Option byte register
-~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FLASH_OBR_nRST_STDBY_BIT
-.. doxygendefine:: FLASH_OBR_nRST_STOP_BIT
-.. doxygendefine:: FLASH_OBR_WDG_SW_BIT
-.. doxygendefine:: FLASH_OBR_RDPRT_BIT
-.. doxygendefine:: FLASH_OBR_OPTERR_BIT
-
-.. doxygendefine:: FLASH_OBR_DATA1
-.. doxygendefine:: FLASH_OBR_DATA0
-.. doxygendefine:: FLASH_OBR_USER
-.. doxygendefine:: FLASH_OBR_nRST_STDBY
-.. doxygendefine:: FLASH_OBR_nRST_STOP
-.. doxygendefine:: FLASH_OBR_WDG_SW
-.. doxygendefine:: FLASH_OBR_RDPRT
-.. doxygendefine:: FLASH_OBR_OPTERR
+::
+
+ /* 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/source/libmaple/api/fsmc.rst b/source/libmaple/api/fsmc.rst
index 3b356cc..e2bf87a 100644
--- a/source/libmaple/api/fsmc.rst
+++ b/source/libmaple/api/fsmc.rst
@@ -1,19 +1,43 @@
.. highlight:: c
.. _libmaple-fsmc:
-``fsmc.h``
-==========
+``<libmaple/fsmc.h>``
+=====================
-Flexible Static Memory Controller (FSMC) support.
+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:
-Types
------
+Usage Note
+----------
-.. doxygenstruct:: fsmc_reg_map
-.. doxygenstruct:: fsmc_nor_psram_reg_map
+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
-------
@@ -23,13 +47,49 @@ 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
@@ -40,150 +100,136 @@ Memory Bank Boundary Addresses
.. doxygendefine:: FSMC_NOR_PSRAM_REGION3
.. doxygendefine:: FSMC_NOR_PSRAM_REGION4
-Register Map Base Pointers
---------------------------
-
-.. doxygendefine:: FSMC_BASE
-
-.. doxygendefine:: FSMC_NOR_PSRAM1_BASE
-.. doxygendefine:: FSMC_NOR_PSRAM2_BASE
-.. doxygendefine:: FSMC_NOR_PSRAM3_BASE
-.. doxygendefine:: FSMC_NOR_PSRAM4_BASE
-
Register Bit Definitions
------------------------
-NOR/PSRAM Chip-Select Control Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_BCR_CBURSTRW_BIT
-.. doxygendefine:: FSMC_BCR_ASYNCWAIT_BIT
-.. doxygendefine:: FSMC_BCR_EXTMOD_BIT
-.. doxygendefine:: FSMC_BCR_WAITEN_BIT
-.. doxygendefine:: FSMC_BCR_WREN_BIT
-.. doxygendefine:: FSMC_BCR_WAITCFG_BIT
-.. doxygendefine:: FSMC_BCR_WRAPMOD_BIT
-.. doxygendefine:: FSMC_BCR_WAITPOL_BIT
-.. doxygendefine:: FSMC_BCR_BURSTEN_BIT
-.. doxygendefine:: FSMC_BCR_FACCEN_BIT
-.. doxygendefine:: FSMC_BCR_MUXEN_BIT
-.. doxygendefine:: FSMC_BCR_MBKEN_BIT
-
-.. doxygendefine:: FSMC_BCR_CBURSTRW
-.. doxygendefine:: FSMC_BCR_ASYNCWAIT
-.. doxygendefine:: FSMC_BCR_EXTMOD
-.. doxygendefine:: FSMC_BCR_WAITEN
-.. doxygendefine:: FSMC_BCR_WREN
-.. doxygendefine:: FSMC_BCR_WAITCFG
-.. doxygendefine:: FSMC_BCR_WRAPMOD
-.. doxygendefine:: FSMC_BCR_WAITPOL
-.. doxygendefine:: FSMC_BCR_BURSTEN
-.. doxygendefine:: FSMC_BCR_FACCEN
-.. doxygendefine:: FSMC_BCR_MWID
-.. doxygendefine:: FSMC_BCR_MWID_8BITS
-.. doxygendefine:: FSMC_BCR_MWID_16BITS
-.. doxygendefine:: FSMC_BCR_MTYP
-.. doxygendefine:: FSMC_BCR_MTYP_SRAM
-.. doxygendefine:: FSMC_BCR_MTYP_PSRAM
-.. doxygendefine:: FSMC_BCR_MTYP_NOR_FLASH
-.. doxygendefine:: FSMC_BCR_MUXEN
-.. doxygendefine:: FSMC_BCR_MBKEN
-
-SRAM/NOR-Flash Chip-Select Timing Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_BTR_ACCMOD
-.. doxygendefine:: FSMC_BTR_ACCMOD_A
-.. doxygendefine:: FSMC_BTR_ACCMOD_B
-.. doxygendefine:: FSMC_BTR_ACCMOD_C
-.. doxygendefine:: FSMC_BTR_ACCMOD_D
-.. doxygendefine:: FSMC_BTR_DATLAT
-.. doxygendefine:: FSMC_BTR_CLKDIV
-.. doxygendefine:: FSMC_BTR_BUSTURN
-.. doxygendefine:: FSMC_BTR_DATAST
-.. doxygendefine:: FSMC_BTR_ADDHLD
-.. doxygendefine:: FSMC_BTR_ADDSET
-
-SRAM/NOR-Flash Write Timing Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_BWTR_ACCMOD
-.. doxygendefine:: FSMC_BWTR_ACCMOD_A
-.. doxygendefine:: FSMC_BWTR_ACCMOD_B
-.. doxygendefine:: FSMC_BWTR_ACCMOD_C
-.. doxygendefine:: FSMC_BWTR_ACCMOD_D
-.. doxygendefine:: FSMC_BWTR_DATLAT
-.. doxygendefine:: FSMC_BWTR_CLKDIV
-.. doxygendefine:: FSMC_BWTR_DATAST
-.. doxygendefine:: FSMC_BWTR_ADDHLD
-.. doxygendefine:: FSMC_BWTR_ADDSET
-
-NAND Flash/PC Card Controller Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_PCR_ECCEN_BIT
-.. doxygendefine:: FSMC_PCR_PTYP_BIT
-.. doxygendefine:: FSMC_PCR_PBKEN_BIT
-.. doxygendefine:: FSMC_PCR_PWAITEN_BIT
-
-.. doxygendefine:: FSMC_PCR_ECCPS
-.. doxygendefine:: FSMC_PCR_ECCPS_256B
-.. doxygendefine:: FSMC_PCR_ECCPS_512B
-.. doxygendefine:: FSMC_PCR_ECCPS_1024B
-.. doxygendefine:: FSMC_PCR_ECCPS_2048B
-.. doxygendefine:: FSMC_PCR_ECCPS_4096B
-.. doxygendefine:: FSMC_PCR_ECCPS_8192B
-.. doxygendefine:: FSMC_PCR_TAR
-.. doxygendefine:: FSMC_PCR_TCLR
-.. doxygendefine:: FSMC_PCR_ECCEN
-.. doxygendefine:: FSMC_PCR_PWID
-.. doxygendefine:: FSMC_PCR_PWID_8BITS
-.. doxygendefine:: FSMC_PCR_PWID_16BITS
-.. doxygendefine:: FSMC_PCR_PTYP
-.. doxygendefine:: FSMC_PCR_PTYP_PC_CF_PCMCIA
-.. doxygendefine:: FSMC_PCR_PTYP_NAND
-.. doxygendefine:: FSMC_PCR_PBKEN
-.. doxygendefine:: FSMC_PCR_PWAITEN
-
-FIFO Status And Interrupt Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_SR_FEMPT_BIT
-.. doxygendefine:: FSMC_SR_IFEN_BIT
-.. doxygendefine:: FSMC_SR_ILEN_BIT
-.. doxygendefine:: FSMC_SR_IREN_BIT
-.. doxygendefine:: FSMC_SR_IFS_BIT
-.. doxygendefine:: FSMC_SR_ILS_BIT
-.. doxygendefine:: FSMC_SR_IRS_BIT
-
-.. doxygendefine:: FSMC_SR_FEMPT
-.. doxygendefine:: FSMC_SR_IFEN
-.. doxygendefine:: FSMC_SR_ILEN
-.. doxygendefine:: FSMC_SR_IREN
-.. doxygendefine:: FSMC_SR_IFS
-.. doxygendefine:: FSMC_SR_ILS
-.. doxygendefine:: FSMC_SR_IRS
-
-Common Memory Space Timing Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_PMEM_MEMHIZ
-.. doxygendefine:: FSMC_PMEM_MEMHOLD
-.. doxygendefine:: FSMC_PMEM_MEMWAIT
-.. doxygendefine:: FSMC_PMEM_MEMSET
-
-Attribute Memory Space Timing Registers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_PATT_ATTHIZ
-.. doxygendefine:: FSMC_PATT_ATTHOLD
-.. doxygendefine:: FSMC_PATT_ATTWAIT
-.. doxygendefine:: FSMC_PATT_ATTSET
-
-I/O Space Timing Register 4
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: FSMC_PIO_IOHIZ
-.. doxygendefine:: FSMC_PIO_IOHOLD
-.. doxygendefine:: FSMC_PIO_IOWAIT
-.. doxygendefine:: FSMC_PIO_IOSET
+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/source/libmaple/api/iwdg.rst b/source/libmaple/api/iwdg.rst
index 06691f8..65f9f7b 100644
--- a/source/libmaple/api/iwdg.rst
+++ b/source/libmaple/api/iwdg.rst
@@ -1,10 +1,11 @@
.. highlight:: c
.. _libmaple-iwdg:
-``iwdg.h``
-==========
+``<libmaple/iwdg.h>``
+=====================
-Independent Watchdog (IWDG) support.
+Independent Watchdog (IWDG) support. The IWDG peripheral is common
+across supported targets, so everything documented here is portable.
.. contents:: Contents
:local:
@@ -12,20 +13,15 @@ Independent Watchdog (IWDG) support.
Usage Note
----------
-To use the independent watchdog, first call :c:func:`iwdg_init()` with
-the appropriate prescaler and IWDG counter reload values for your
-application. Afterwards, you must periodically call
-:c:func:`iwdg_feed()` before the IWDG counter reaches 0 to reset the
-counter to its reload value. If you do not, the chip will reset.
+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.
-Types
------
-
-.. doxygenstruct:: iwdg_reg_map
-.. doxygenenum:: iwdg_prescaler
-
Devices
-------
@@ -34,40 +30,51 @@ None at this time.
Functions
---------
+.. _libmaple-iwdg-iwdg_init:
.. doxygenfunction:: iwdg_init
+.. _libmaple-iwdg-iwdg_feed:
.. doxygenfunction:: iwdg_feed
-Register Map Base Pointers
---------------------------
+Types
+-----
+
+.. doxygenenum:: iwdg_prescaler
+
+
+Register Maps
+-------------
.. doxygendefine:: IWDG_BASE
+.. doxygenstruct:: iwdg_reg_map
+
Register Bit Definitions
------------------------
-Key register
-~~~~~~~~~~~~
+These are given as source code.
+
+::
+
+ /* Key register */
-.. doxygendefine:: IWDG_KR_UNLOCK
-.. doxygendefine:: IWDG_KR_FEED
-.. doxygendefine:: IWDG_KR_START
+ #define IWDG_KR_UNLOCK 0x5555
+ #define IWDG_KR_FEED 0xAAAA
+ #define IWDG_KR_START 0xCCCC
-Prescaler register
-~~~~~~~~~~~~~~~~~~
+ /* Prescaler register */
-.. doxygendefine:: IWDG_PR_DIV_4
-.. doxygendefine:: IWDG_PR_DIV_8
-.. doxygendefine:: IWDG_PR_DIV_16
-.. doxygendefine:: IWDG_PR_DIV_32
-.. doxygendefine:: IWDG_PR_DIV_64
-.. doxygendefine:: IWDG_PR_DIV_128
-.. doxygendefine:: IWDG_PR_DIV_256
+ #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
-~~~~~~~~~~~~~~~
+ /* Status register */
-.. doxygendefine:: IWDG_SR_RVU_BIT
-.. doxygendefine:: IWDG_SR_PVU_BIT
+ #define IWDG_SR_RVU_BIT 1
+ #define IWDG_SR_PVU_BIT 0
-.. doxygendefine:: IWDG_SR_RVU
-.. doxygendefine:: IWDG_SR_PVU
+ #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT)
+ #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT)
diff --git a/source/libmaple/api/libmaple.rst b/source/libmaple/api/libmaple.rst
index c230cef..7deb659 100644
--- a/source/libmaple/api/libmaple.rst
+++ b/source/libmaple/api/libmaple.rst
@@ -1,8 +1,8 @@
.. highlight:: c
.. _libmaple-libmaple:
-``libmaple.h``
-==============
+``<libmaple/libmaple.h>``
+=========================
Base include file for libmaple.
diff --git a/source/libmaple/api/libmaple_types.rst b/source/libmaple/api/libmaple_types.rst
index 7fed5dc..5ca446e 100644
--- a/source/libmaple/api/libmaple_types.rst
+++ b/source/libmaple/api/libmaple_types.rst
@@ -1,12 +1,15 @@
.. highlight:: c
.. _libmaple-libmaple_types:
-``libmaple_types.h``
-====================
+``<libmaple/libmaple_types.h>``
+===============================
Defines the base types and type-related macros used throughout the
rest of libmaple.
+.. contents:: Contents
+ :local:
+
Integral Types
--------------
@@ -22,22 +25,61 @@ Integral Types
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
- This is a macro for ``volatile`` which is used to denote 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
+ 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:: __attr_flash
+.. c:macro:: __weak
- This is a macro for a GCC ``__attribute__`` which (when using the
- linker scripts provided with libmaple) will cause the variable
- being marked to be stored in Flash, rather than SRAM. The
- variable's value may be read like that of any other variable, but
- it may not be written.
+ Macro for ``__attribute__((weak))``.
-Other typedefs
---------------
+.. 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/source/libmaple/api/nvic.rst b/source/libmaple/api/nvic.rst
index b22c94b..505e36e 100644
--- a/source/libmaple/api/nvic.rst
+++ b/source/libmaple/api/nvic.rst
@@ -1,25 +1,44 @@
.. highlight:: c
.. _libmaple-nvic:
-``nvic.h``
-==========
+``<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:
-Types
------
-
-.. doxygenstruct:: nvic_reg_map
-.. doxygenenum:: nvic_irq_num
-
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
---------
@@ -33,10 +52,14 @@ Functions
.. doxygenfunction:: nvic_irq_disable_all
.. doxygenfunction:: nvic_sys_reset
-Register Map Base Pointers
---------------------------
+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
------------------------
diff --git a/source/libmaple/api/rcc-reg-bits.txt b/source/libmaple/api/rcc-reg-bits.txt
new file mode 100644
index 0000000..6b1133d
--- /dev/null
+++ b/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/source/libmaple/api/rcc.rst b/source/libmaple/api/rcc.rst
index 4b96c00..ce58ec8 100644
--- a/source/libmaple/api/rcc.rst
+++ b/source/libmaple/api/rcc.rst
@@ -1,377 +1,360 @@
.. highlight:: c
.. _libmaple-rcc:
-``rcc.h``
-=========
+``<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
-Types
------
+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>`.
-.. doxygenstruct:: rcc_reg_map
.. doxygenenum:: rcc_sysclk_src
-.. doxygenenum:: rcc_pllsrc
-.. doxygenenum:: rcc_pll_multiplier
-.. doxygenenum:: rcc_clk_id
-.. doxygenenum:: rcc_clk_domain
-.. doxygenenum:: rcc_prescaler
-.. doxygenenum:: rcc_adc_divider
-.. doxygenenum:: rcc_apb1_divider
-.. doxygenenum:: rcc_apb2_divider
-.. doxygenenum:: rcc_ahb_divider
-Devices
--------
+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
-None.
+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
---------
-.. doxygenfunction:: rcc_clk_init
+.. _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
-Register Map Base Pointers
---------------------------
+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
------------------------
-Clock control register
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_CR_PLLRDY_BIT
-.. doxygendefine:: RCC_CR_PLLON_BIT
-.. doxygendefine:: RCC_CR_CSSON_BIT
-.. doxygendefine:: RCC_CR_HSEBYP_BIT
-.. doxygendefine:: RCC_CR_HSERDY_BIT
-.. doxygendefine:: RCC_CR_HSEON_BIT
-.. doxygendefine:: RCC_CR_HSIRDY_BIT
-.. doxygendefine:: RCC_CR_HSION_BIT
-
-.. doxygendefine:: RCC_CR_PLLRDY
-.. doxygendefine:: RCC_CR_PLLON
-.. doxygendefine:: RCC_CR_CSSON
-.. doxygendefine:: RCC_CR_HSEBYP
-.. doxygendefine:: RCC_CR_HSERDY
-.. doxygendefine:: RCC_CR_HSEON
-.. doxygendefine:: RCC_CR_HSICAL
-.. doxygendefine:: RCC_CR_HSITRIM
-.. doxygendefine:: RCC_CR_HSIRDY
-.. doxygendefine:: RCC_CR_HSION
-
-Clock configuration register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_CFGR_USBPRE_BIT
-.. doxygendefine:: RCC_CFGR_PLLXTPRE_BIT
-.. doxygendefine:: RCC_CFGR_PLLSRC_BIT
-
-.. doxygendefine:: RCC_CFGR_MCO
-.. doxygendefine:: RCC_CFGR_USBPRE
-.. doxygendefine:: RCC_CFGR_PLLMUL
-.. doxygendefine:: RCC_CFGR_PLLXTPRE
-.. doxygendefine:: RCC_CFGR_PLLSRC
-.. doxygendefine:: RCC_CFGR_ADCPRE
-.. doxygendefine:: RCC_CFGR_PPRE2
-.. doxygendefine:: RCC_CFGR_PPRE1
-.. doxygendefine:: RCC_CFGR_HPRE
-.. doxygendefine:: RCC_CFGR_SWS
-.. doxygendefine:: RCC_CFGR_SWS_PLL
-.. doxygendefine:: RCC_CFGR_SWS_HSE
-.. doxygendefine:: RCC_CFGR_SW
-.. doxygendefine:: RCC_CFGR_SW_PLL
-.. doxygendefine:: RCC_CFGR_SW_HSE
-
-Clock interrupt register
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_CIR_CSSC_BIT
-.. doxygendefine:: RCC_CIR_PLLRDYC_BIT
-.. doxygendefine:: RCC_CIR_HSERDYC_BIT
-.. doxygendefine:: RCC_CIR_HSIRDYC_BIT
-.. doxygendefine:: RCC_CIR_LSERDYC_BIT
-.. doxygendefine:: RCC_CIR_LSIRDYC_BIT
-.. doxygendefine:: RCC_CIR_PLLRDYIE_BIT
-.. doxygendefine:: RCC_CIR_HSERDYIE_BIT
-.. doxygendefine:: RCC_CIR_HSIRDYIE_BIT
-.. doxygendefine:: RCC_CIR_LSERDYIE_BIT
-.. doxygendefine:: RCC_CIR_LSIRDYIE_BIT
-.. doxygendefine:: RCC_CIR_CSSF_BIT
-.. doxygendefine:: RCC_CIR_PLLRDYF_BIT
-.. doxygendefine:: RCC_CIR_HSERDYF_BIT
-.. doxygendefine:: RCC_CIR_HSIRDYF_BIT
-.. doxygendefine:: RCC_CIR_LSERDYF_BIT
-.. doxygendefine:: RCC_CIR_LSIRDYF_BIT
-
-.. doxygendefine:: RCC_CIR_CSSC
-.. doxygendefine:: RCC_CIR_PLLRDYC
-.. doxygendefine:: RCC_CIR_HSERDYC
-.. doxygendefine:: RCC_CIR_HSIRDYC
-.. doxygendefine:: RCC_CIR_LSERDYC
-.. doxygendefine:: RCC_CIR_LSIRDYC
-.. doxygendefine:: RCC_CIR_PLLRDYIE
-.. doxygendefine:: RCC_CIR_HSERDYIE
-.. doxygendefine:: RCC_CIR_HSIRDYIE
-.. doxygendefine:: RCC_CIR_LSERDYIE
-.. doxygendefine:: RCC_CIR_LSIRDYIE
-.. doxygendefine:: RCC_CIR_CSSF
-.. doxygendefine:: RCC_CIR_PLLRDYF
-.. doxygendefine:: RCC_CIR_HSERDYF
-.. doxygendefine:: RCC_CIR_HSIRDYF
-.. doxygendefine:: RCC_CIR_LSERDYF
-.. doxygendefine:: RCC_CIR_LSIRDYF
-
-APB2 peripheral reset register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_APB2RSTR_TIM11RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_TIM10RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_TIM9RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_ADC3RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_USART1RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_TIM8RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_SPI1RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_TIM1RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_ADC2RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_ADC1RST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPGRST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPFRST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPERST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPDRST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPCRST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPBRST_BIT
-.. doxygendefine:: RCC_APB2RSTR_IOPARST_BIT
-.. doxygendefine:: RCC_APB2RSTR_AFIORST_BIT
-
-.. doxygendefine:: RCC_APB2RSTR_TIM11RST
-.. doxygendefine:: RCC_APB2RSTR_TIM10RST
-.. doxygendefine:: RCC_APB2RSTR_TIM9RST
-.. doxygendefine:: RCC_APB2RSTR_ADC3RST
-.. doxygendefine:: RCC_APB2RSTR_USART1RST
-.. doxygendefine:: RCC_APB2RSTR_TIM8RST
-.. doxygendefine:: RCC_APB2RSTR_SPI1RST
-.. doxygendefine:: RCC_APB2RSTR_TIM1RST
-.. doxygendefine:: RCC_APB2RSTR_ADC2RST
-.. doxygendefine:: RCC_APB2RSTR_ADC1RST
-.. doxygendefine:: RCC_APB2RSTR_IOPGRST
-.. doxygendefine:: RCC_APB2RSTR_IOPFRST
-.. doxygendefine:: RCC_APB2RSTR_IOPERST
-.. doxygendefine:: RCC_APB2RSTR_IOPDRST
-.. doxygendefine:: RCC_APB2RSTR_IOPCRST
-.. doxygendefine:: RCC_APB2RSTR_IOPBRST
-.. doxygendefine:: RCC_APB2RSTR_IOPARST
-.. doxygendefine:: RCC_APB2RSTR_AFIORST
-
-APB1 peripheral reset register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_APB1RSTR_DACRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_PWRRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_BKPRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_CANRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_USBRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_I2C2RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_I2C1RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_UART5RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_UART4RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_USART3RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_USART2RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_SPI3RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_SPI2RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_WWDRST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM14RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM13RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM12RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM7RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM6RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM5RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM4RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM3RST_BIT
-.. doxygendefine:: RCC_APB1RSTR_TIM2RST_BIT
-
-.. doxygendefine:: RCC_APB1RSTR_DACRST
-.. doxygendefine:: RCC_APB1RSTR_PWRRST
-.. doxygendefine:: RCC_APB1RSTR_BKPRST
-.. doxygendefine:: RCC_APB1RSTR_CANRST
-.. doxygendefine:: RCC_APB1RSTR_USBRST
-.. doxygendefine:: RCC_APB1RSTR_I2C2RST
-.. doxygendefine:: RCC_APB1RSTR_I2C1RST
-.. doxygendefine:: RCC_APB1RSTR_UART5RST
-.. doxygendefine:: RCC_APB1RSTR_UART4RST
-.. doxygendefine:: RCC_APB1RSTR_USART3RST
-.. doxygendefine:: RCC_APB1RSTR_USART2RST
-.. doxygendefine:: RCC_APB1RSTR_SPI3RST
-.. doxygendefine:: RCC_APB1RSTR_SPI2RST
-.. doxygendefine:: RCC_APB1RSTR_WWDRST
-.. doxygendefine:: RCC_APB1RSTR_TIM14RST
-.. doxygendefine:: RCC_APB1RSTR_TIM13RST
-.. doxygendefine:: RCC_APB1RSTR_TIM12RST
-.. doxygendefine:: RCC_APB1RSTR_TIM7RST
-.. doxygendefine:: RCC_APB1RSTR_TIM6RST
-.. doxygendefine:: RCC_APB1RSTR_TIM5RST
-.. doxygendefine:: RCC_APB1RSTR_TIM4RST
-.. doxygendefine:: RCC_APB1RSTR_TIM3RST
-.. doxygendefine:: RCC_APB1RSTR_TIM2RST
-
-AHB peripheral clock enable register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_AHBENR_SDIOEN_BIT
-.. doxygendefine:: RCC_AHBENR_FSMCEN_BIT
-.. doxygendefine:: RCC_AHBENR_CRCEN_BIT
-.. doxygendefine:: RCC_AHBENR_FLITFEN_BIT
-.. doxygendefine:: RCC_AHBENR_SRAMEN_BIT
-.. doxygendefine:: RCC_AHBENR_DMA2EN_BIT
-.. doxygendefine:: RCC_AHBENR_DMA1EN_BIT
-
-.. doxygendefine:: RCC_AHBENR_SDIOEN
-.. doxygendefine:: RCC_AHBENR_FSMCEN
-.. doxygendefine:: RCC_AHBENR_CRCEN
-.. doxygendefine:: RCC_AHBENR_FLITFEN
-.. doxygendefine:: RCC_AHBENR_SRAMEN
-.. doxygendefine:: RCC_AHBENR_DMA2EN
-.. doxygendefine:: RCC_AHBENR_DMA1EN
-
-APB2 peripheral clock enable register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+These are given as source code. Available register bit definitions
+vary by target.
-.. doxygendefine:: RCC_APB2ENR_TIM11EN_BIT
-.. doxygendefine:: RCC_APB2ENR_TIM10EN_BIT
-.. doxygendefine:: RCC_APB2ENR_TIM9EN_BIT
-.. doxygendefine:: RCC_APB2ENR_ADC3EN_BIT
-.. doxygendefine:: RCC_APB2ENR_USART1EN_BIT
-.. doxygendefine:: RCC_APB2ENR_TIM8EN_BIT
-.. doxygendefine:: RCC_APB2ENR_SPI1EN_BIT
-.. doxygendefine:: RCC_APB2ENR_TIM1EN_BIT
-.. doxygendefine:: RCC_APB2ENR_ADC2EN_BIT
-.. doxygendefine:: RCC_APB2ENR_ADC1EN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPGEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPFEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPEEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPDEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPCEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPBEN_BIT
-.. doxygendefine:: RCC_APB2ENR_IOPAEN_BIT
-.. doxygendefine:: RCC_APB2ENR_AFIOEN_BIT
-
-.. doxygendefine:: RCC_APB2ENR_TIM11EN
-.. doxygendefine:: RCC_APB2ENR_TIM10EN
-.. doxygendefine:: RCC_APB2ENR_TIM9EN
-.. doxygendefine:: RCC_APB2ENR_ADC3EN
-.. doxygendefine:: RCC_APB2ENR_USART1EN
-.. doxygendefine:: RCC_APB2ENR_TIM8EN
-.. doxygendefine:: RCC_APB2ENR_SPI1EN
-.. doxygendefine:: RCC_APB2ENR_TIM1EN
-.. doxygendefine:: RCC_APB2ENR_ADC2EN
-.. doxygendefine:: RCC_APB2ENR_ADC1EN
-.. doxygendefine:: RCC_APB2ENR_IOPGEN
-.. doxygendefine:: RCC_APB2ENR_IOPFEN
-.. doxygendefine:: RCC_APB2ENR_IOPEEN
-.. doxygendefine:: RCC_APB2ENR_IOPDEN
-.. doxygendefine:: RCC_APB2ENR_IOPCEN
-.. doxygendefine:: RCC_APB2ENR_IOPBEN
-.. doxygendefine:: RCC_APB2ENR_IOPAEN
-.. doxygendefine:: RCC_APB2ENR_AFIOEN
-
-APB1 peripheral clock enable register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. We need this include to avoid crashing Emacs's ReST parser. Yuck.
+
+.. include:: rcc-reg-bits.txt
+
+Deprecated Functionality
+------------------------
-.. doxygendefine:: RCC_APB1ENR_DACEN_BIT
-.. doxygendefine:: RCC_APB1ENR_PWREN_BIT
-.. doxygendefine:: RCC_APB1ENR_BKPEN_BIT
-.. doxygendefine:: RCC_APB1ENR_CANEN_BIT
-.. doxygendefine:: RCC_APB1ENR_USBEN_BIT
-.. doxygendefine:: RCC_APB1ENR_I2C2EN_BIT
-.. doxygendefine:: RCC_APB1ENR_I2C1EN_BIT
-.. doxygendefine:: RCC_APB1ENR_UART5EN_BIT
-.. doxygendefine:: RCC_APB1ENR_UART4EN_BIT
-.. doxygendefine:: RCC_APB1ENR_USART3EN_BIT
-.. doxygendefine:: RCC_APB1ENR_USART2EN_BIT
-.. doxygendefine:: RCC_APB1ENR_SPI3EN_BIT
-.. doxygendefine:: RCC_APB1ENR_SPI2EN_BIT
-.. doxygendefine:: RCC_APB1ENR_WWDEN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM14EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM13EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM12EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM7EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM6EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM5EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM4EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM3EN_BIT
-.. doxygendefine:: RCC_APB1ENR_TIM2EN_BIT
-
-.. doxygendefine:: RCC_APB1ENR_DACEN
-.. doxygendefine:: RCC_APB1ENR_PWREN
-.. doxygendefine:: RCC_APB1ENR_BKPEN
-.. doxygendefine:: RCC_APB1ENR_CANEN
-.. doxygendefine:: RCC_APB1ENR_USBEN
-.. doxygendefine:: RCC_APB1ENR_I2C2EN
-.. doxygendefine:: RCC_APB1ENR_I2C1EN
-.. doxygendefine:: RCC_APB1ENR_UART5EN
-.. doxygendefine:: RCC_APB1ENR_UART4EN
-.. doxygendefine:: RCC_APB1ENR_USART3EN
-.. doxygendefine:: RCC_APB1ENR_USART2EN
-.. doxygendefine:: RCC_APB1ENR_SPI3EN
-.. doxygendefine:: RCC_APB1ENR_SPI2EN
-.. doxygendefine:: RCC_APB1ENR_WWDEN
-.. doxygendefine:: RCC_APB1ENR_TIM14EN
-.. doxygendefine:: RCC_APB1ENR_TIM13EN
-.. doxygendefine:: RCC_APB1ENR_TIM12EN
-.. doxygendefine:: RCC_APB1ENR_TIM7EN
-.. doxygendefine:: RCC_APB1ENR_TIM6EN
-.. doxygendefine:: RCC_APB1ENR_TIM5EN
-.. doxygendefine:: RCC_APB1ENR_TIM4EN
-.. doxygendefine:: RCC_APB1ENR_TIM3EN
-.. doxygendefine:: RCC_APB1ENR_TIM2EN
-
-Backup domain control register
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_BDCR_BDRST_BIT
-.. doxygendefine:: RCC_BDCR_RTCEN_BIT
-.. doxygendefine:: RCC_BDCR_LSEBYP_BIT
-.. doxygendefine:: RCC_BDCR_LSERDY_BIT
-.. doxygendefine:: RCC_BDCR_LSEON_BIT
-
-.. doxygendefine:: RCC_BDCR_BDRST
-.. doxygendefine:: RCC_BDCR_RTCEN
-.. doxygendefine:: RCC_BDCR_RTCSEL
-.. doxygendefine:: RCC_BDCR_RTCSEL_NONE
-.. doxygendefine:: RCC_BDCR_RTCSEL_LSE
-.. doxygendefine:: RCC_BDCR_RTCSEL_HSE
-.. doxygendefine:: RCC_BDCR_LSEBYP
-.. doxygendefine:: RCC_BDCR_LSERDY
-.. doxygendefine:: RCC_BDCR_LSEON
-
-Control/status register
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. doxygendefine:: RCC_CSR_LPWRRSTF_BIT
-.. doxygendefine:: RCC_CSR_WWDGRSTF_BIT
-.. doxygendefine:: RCC_CSR_IWDGRSTF_BIT
-.. doxygendefine:: RCC_CSR_SFTRSTF_BIT
-.. doxygendefine:: RCC_CSR_PORRSTF_BIT
-.. doxygendefine:: RCC_CSR_PINRSTF_BIT
-.. doxygendefine:: RCC_CSR_RMVF_BIT
-.. doxygendefine:: RCC_CSR_LSIRDY_BIT
-.. doxygendefine:: RCC_CSR_LSION_BIT
-
-.. doxygendefine:: RCC_CSR_LPWRRSTF
-.. doxygendefine:: RCC_CSR_WWDGRSTF
-.. doxygendefine:: RCC_CSR_IWDGRSTF
-.. doxygendefine:: RCC_CSR_SFTRSTF
-.. doxygendefine:: RCC_CSR_PORRSTF
-.. doxygendefine:: RCC_CSR_PINRSTF
-.. doxygendefine:: RCC_CSR_RMVF
-.. doxygendefine:: RCC_CSR_LSIRDY
-.. doxygendefine:: RCC_CSR_LSION
+.. _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/source/libmaple/api/ring_buffer.rst b/source/libmaple/api/ring_buffer.rst
index e9b6637..ef082dd 100644
--- a/source/libmaple/api/ring_buffer.rst
+++ b/source/libmaple/api/ring_buffer.rst
@@ -1,8 +1,8 @@
.. highlight:: c
.. _libmaple-ring_buffer:
-``ring_buffer.h``
-=================
+``<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.
diff --git a/source/libmaple/api/stm32.rst b/source/libmaple/api/stm32.rst
index 6e631b0..335bda4 100644
--- a/source/libmaple/api/stm32.rst
+++ b/source/libmaple/api/stm32.rst
@@ -1,26 +1,118 @@
.. highlight:: c
.. _libmaple-stm32:
-``stm32.h``
-===========
+``<libmaple/stm32.h>``
+======================
-General STM32-specific definitions. This file is currently somewhat
-incomplete, but it will form the future basis for MCU-specific (rather
-than board-specific, which belongs in :ref:`Wirish
-<libmaple-vs-wirish>`) configuration.
+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>`).
-Defines
--------
+.. 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
-.. doxygendefine:: STM32_NR_INTERRUPTS
-.. doxygendefine:: STM32_NR_GPIO_PORTS
+
+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
-.. doxygendefine:: STM32_SRAM_END
-Deprecated Defines
-------------------
+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
diff --git a/source/libmaple/api/usart.rst b/source/libmaple/api/usart.rst
index 1575a8f..68f2c37 100644
--- a/source/libmaple/api/usart.rst
+++ b/source/libmaple/api/usart.rst
@@ -34,6 +34,7 @@ Functions
.. doxygenfunction:: usart_disable
.. doxygenfunction:: usart_disable_all
.. doxygenfunction:: usart_foreach
+.. doxygenfunction:: usart_rx
.. doxygenfunction:: usart_tx
.. doxygenfunction:: usart_putudec
.. doxygenfunction:: usart_putc
diff --git a/source/libmaple/api/util.rst b/source/libmaple/api/util.rst
index 06c9246..54377c0 100644
--- a/source/libmaple/api/util.rst
+++ b/source/libmaple/api/util.rst
@@ -1,8 +1,8 @@
.. highlight:: c
.. _libmaple-util:
-``util.h``
-==========
+``<libmaple/util.h>``
+=====================
.. TODO [0.2.0?] clean this up.
@@ -14,17 +14,20 @@ Miscellaneous utility macros and procedures.
Bit Manipulation
----------------
-::
+The following macros are useful for bit manipulation.
- #define BIT(shift) (1UL << (shift))
- #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift))
- /** Gets bits m to n of x */
- #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m)))
- #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1)))
+.. 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
diff --git a/source/libmaple/apis.rst b/source/libmaple/apis.rst
index f493406..31f4902 100644
--- a/source/libmaple/apis.rst
+++ b/source/libmaple/apis.rst
@@ -1,7 +1,7 @@
.. _libmaple-apis:
-APIs
-====
+``libmaple`` API Index
+======================
This is the master index for libmaple proper's APIs.
diff --git a/source/libmaple/overview.rst b/source/libmaple/overview.rst
index 21d1a72..006f1d8 100644
--- a/source/libmaple/overview.rst
+++ b/source/libmaple/overview.rst
@@ -5,9 +5,12 @@
Overview
========
-This page is a general overview of libmaple proper. It provides a
-general perspective of the library's goals and design. Examples are
-given from libmaple's sources.
+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:
@@ -15,170 +18,321 @@ given from libmaple's sources.
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/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf>`_.
-That document is the single most important tool in your toolbox. It
-is the authoritative documentation for the capabilities and register
-interfaces of the STM32 line.
-
-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.
-
-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. */
+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; /**< Register map */
- rcc_clk_id clk_id; /**< RCC clock information */
+ adc_reg_map *regs;
+ rcc_clk_id clk_id;
} 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 regs; /**< Register map */
- rcc_clk_id clk_id; /**< RCC clock information */
- timer_type type; /**< Timer's type */
- voidFuncPtr handlers[]; /**< User IRQ 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::
+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::
- /* From usart.h */
- void usart_enable(usart_dev *dev);
-
- /* From i2c.h */
- void i2c_master_enable(i2c_dev *dev, uint32 flags);
+ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
-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``::
+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);
+ }
- void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate);
- uint32 adc_read(const adc_dev *dev, uint8 channel);
+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.
-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.
+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
-------------
-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)::
+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)::
- /** DAC register map. */
typedef struct dac_reg_map {
__io uint32 CR; /**< Control register */
__io uint32 SWTRIGR; /**< Software trigger register */
@@ -204,89 +358,87 @@ saying ``volatile`` when referring to register values)::
__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.
-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.
+.. _libmaple-overview-regmaps-base-pts:
-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::
+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 XXX_BASE ((struct xxx_reg_map*)0xDEADBEEF)
+ #define FOO_BASE ((struct foo_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``::
+``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)
+ #define DAC_BASE ((struct dac_reg_map*)0x40007400)
-How can you use these? This is perhaps best explained by example.
+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 (RM0008: DAC_DHR12L1), you could write::
+ holding register (DAC_DHR12L1), you would write::
DAC_BASE->DHR12L1 = 2048;
-* In order to read the DAC control register, you could write::
+* In order to read the DAC control register, you would 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::
+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 XXX1_BASE ((struct xxx_reg_map*)0xDEADBEEF)
- #define XXX2_BASE ((struct xxx_reg_map*)0xF00DF00D)
+ #define FOO1_BASE ((struct foo_reg_map*)0xDEADBEEF)
+ #define FOO2_BASE ((struct foo_reg_map*)0xF00DF00D)
...
- #define XXXn_BASE ((struct xxx_reg_map*)0x13AF1AB5)
+ #define FOOn_BASE ((struct foo_reg_map*)0x1EAF1AB5)
-Here are some examples from ``adc.h``::
+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)
+ #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 might write::
+results of ADC conversion are stored), you would write::
uint32 converted_result = ADC1_BASE->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 */
+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 BIT(DMA_CCR_MEM2MEM_BIT)
+ #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)
@@ -294,7 +446,7 @@ register bit definitions for those fields::
#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::
+channel configuration register 2 (DMA_CCR2), you can write::
if (DMA1_BASE->CCR2 & DMA_CCR_MEM2MEM) {
/* MEM2MEM is set */
@@ -304,33 +456,61 @@ 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 */
- }
+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!
+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::
-What Next?
-----------
+ /* From <libmaple/dma.h> */
+ void dma_init(dma_dev *dev);
-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>`_.
+ /* 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] For consistency with RM0008, GPIO ports are given letters
- instead of numbers (``GPIOA`` and ``GPIOB`` instead of
- ``GPIO1`` and ``GPIO2``, etc.).
+.. [#fgpio] As an exception, GPIO ports are given letters instead of
+ numbers (``GPIOA`` and ``GPIOB`` instead of ``GPIO1`` and
+ ``GPIO2``, etc.).
diff --git a/source/libraries.rst b/source/libraries.rst
index 44a72f7..1ae0e87 100644
--- a/source/libraries.rst
+++ b/source/libraries.rst
@@ -73,7 +73,7 @@ bugs, and reported on the forums.
Wire
----
-.. FIXME [0.1.0] Update with hard Wire implementation info
+.. 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
diff --git a/source/stm32.rst b/source/stm32.rst
new file mode 100644
index 0000000..d918655
--- /dev/null
+++ b/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/source/unix-toolchain.rst b/source/unix-toolchain.rst
index a397cc1..4fc21ea 100644
--- a/source/unix-toolchain.rst
+++ b/source/unix-toolchain.rst
@@ -67,14 +67,21 @@ The following are **mandatory**:
the `OpenMoko`_ project. It is used 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.
+
+.. _OpenMoko: http://openmoko.com/
+
* `make <http://www.gnu.org/software/make/>`_ is used to direct
compilation.
* `Python <http://python.org>`_ 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. (Most Linux distributions these days include Python by
- default).
+ 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
@@ -176,6 +183,11 @@ You will need the following tools\ [#fpackman]_ to get started:
* `dfu-util <http://wiki.openmoko.org/wiki/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>`_.
diff --git a/source/whats-new.rst b/source/whats-new.rst
new file mode 100644
index 0000000..c1f0bd5
--- /dev/null
+++ b/source/whats-new.rst
@@ -0,0 +1,78 @@
+.. highlight:: c
+
+What's New
+==========
+
+.. FIXME [RELEASE] finish.
+
+This page tracks updates to libmaple and MapleIDE.
+
+.. contents::
+ :local:
+ :depth: 1
+
+v0.0.13
+-------
+
+**General Changes**
+
+.. 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.
+
+- 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).
+
+**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
+
+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>`.