aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/libmaple/api
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/libmaple/api')
-rw-r--r--docs/source/libmaple/api/adc.rst231
-rw-r--r--docs/source/libmaple/api/bitband.rst15
-rw-r--r--docs/source/libmaple/api/bkp.rst79
-rw-r--r--docs/source/libmaple/api/dac.rst123
-rw-r--r--docs/source/libmaple/api/delay.rst11
-rw-r--r--docs/source/libmaple/api/dma.rst215
-rw-r--r--docs/source/libmaple/api/exti.rst37
-rw-r--r--docs/source/libmaple/api/flash.rst249
-rw-r--r--docs/source/libmaple/api/fsmc.rst235
-rw-r--r--docs/source/libmaple/api/gpio.rst243
-rw-r--r--docs/source/libmaple/api/i2c.rst124
-rw-r--r--docs/source/libmaple/api/iwdg.rst80
-rw-r--r--docs/source/libmaple/api/libmaple.rst11
-rw-r--r--docs/source/libmaple/api/libmaple_types.rst85
-rw-r--r--docs/source/libmaple/api/nvic.rst67
-rw-r--r--docs/source/libmaple/api/pwr.rst51
-rw-r--r--docs/source/libmaple/api/rcc-reg-bits.txt1017
-rw-r--r--docs/source/libmaple/api/rcc.rst360
-rw-r--r--docs/source/libmaple/api/ring_buffer.rst27
-rw-r--r--docs/source/libmaple/api/scb.rst156
-rw-r--r--docs/source/libmaple/api/spi.rst187
-rw-r--r--docs/source/libmaple/api/stm32.rst121
-rw-r--r--docs/source/libmaple/api/systick.rst62
-rw-r--r--docs/source/libmaple/api/timer.rst453
-rw-r--r--docs/source/libmaple/api/usart.rst197
-rw-r--r--docs/source/libmaple/api/util.rst54
26 files changed, 4490 insertions, 0 deletions
diff --git a/docs/source/libmaple/api/adc.rst b/docs/source/libmaple/api/adc.rst
new file mode 100644
index 0000000..2f06926
--- /dev/null
+++ b/docs/source/libmaple/api/adc.rst
@@ -0,0 +1,231 @@
+.. highlight:: c
+.. _libmaple-adc:
+
+``<libmaple/adc.h>``
+====================
+
+:ref:`Analog to Digital Conversion <adc>` (ADC) support.
+
+A common API for basic ADC functionality is available, but the
+characteristics of the ADC peripherals vary slightly across
+targets. To manage this, each target defines a small set of datatypes
+expressing its capabilities (namely :ref:`adc_extsel_event
+<adc-adc_extsel_event>`, :ref:`adc_smp_rate <adc-adc_smp_rate>`, and
+:ref:`adc_prescaler <adc-adc_prescaler>`).
+
+.. contents:: Contents
+ :local:
+ :depth: 2
+
+Devices
+-------
+
+The individual ADC peripherals have the following device struct.
+
+.. doxygenstruct:: adc_dev
+
+The available ADC peripherals vary by target. The complete list is
+``ADC1``, ``ADC2``, and ``ADC3``.
+
+.. doxygenvariable:: ADC1
+.. doxygenvariable:: ADC2
+.. doxygenvariable:: ADC3
+
+Functions
+---------
+
+Activation and Deactivation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``adc_enable_single_swstart()`` is simple, portable function, which
+enables an ADC and sets it up for its basic usage: performing single
+conversions using :ref:`adc_read() <adc-adc_read>`.
+
+.. _adc-adc_enable_single_swstart:
+.. doxygenfunction:: adc_enable_single_swstart
+
+The precise software sequence used varies by target, so this is a good
+function to use if your program needs to support multiple MCUs. By
+default, Wirish calls ``adc_enable_single_swstart()`` on all available
+ADCs at ``init()`` time, so Wirish users don't have to call this
+function.
+
+There are several other lower-level routines used for activating and
+deactivating ADCs:
+
+.. _adc-adc_init:
+.. doxygenfunction:: adc_init
+.. _adc-adc_enable:
+.. doxygenfunction:: adc_enable
+.. _adc-adc_disable:
+.. doxygenfunction:: adc_disable
+.. _adc-adc_disable_all:
+.. doxygenfunction:: adc_disable_all
+
+ADC Conversion
+~~~~~~~~~~~~~~
+
+``adc_read()`` is a simple function which starts conversion on a
+single ADC channel, blocks until it has completed, and returns the
+converted result. Don't use the ADC device for any other purpose while
+it's running.
+
+.. _adc-adc_read:
+.. doxygenfunction:: adc_read
+
+To use ``adc_read()``, the device must be configured appropriately.
+You can do this with :ref:`adc_enable_single_swstart()
+<adc-adc_enable_single_swstart>`.
+
+Note that for an ADC device to perform conversion on a GPIO input
+(which is the usual case; the notable exception being taking
+temperature reading), the pin must be configured for analog
+conversion. Do this with :ref:`adc_config_gpio()
+<adc-adc_config_gpio>`.
+
+Other routines helpful for ADC conversion:
+
+.. _adc-adc_set_reg_seqlen:
+.. doxygenfunction:: adc_set_reg_seqlen
+.. _adc-adc_set_extsel:
+.. doxygenfunction:: adc_set_extsel
+
+.. _adc-adc_extsel_event:
+
+The last of these, :ref:`adc_set_extsel() <adc-adc_set_extsel>`, takes
+a target-dependent ``adc_extsel_event`` argument.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_extsel_event
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_extsel_event
+
+ADC Clock Prescaler
+~~~~~~~~~~~~~~~~~~~
+
+``adc_set_prescaler()`` is available for setting the prescaler which
+determines the common ADC clock rate. (Wirish sets a sensible default
+for this, so Wirish users ordinarily don't need to call this
+function.)
+
+.. warning:: Increasing the ADC clock rate does speed conversion time,
+ but the ADC peripherals have a maximum clock rate which must not be
+ exceeded. Make sure to configure your system and ADC clocks to
+ respect your device's maximum rate.
+
+.. _adc_adc_set_prescaler:
+.. doxygenfunction:: adc_set_prescaler
+
+.. _adc-adc_prescaler:
+
+ADC prescaler values are target-dependent.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_prescaler
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_prescaler
+
+.. _adc-adc_set_sample_rate:
+
+ADC Sample Time
+~~~~~~~~~~~~~~~
+
+You can control the sampling time (in ADC cycles) for an entire ADC
+device using ``adc_set_sample_rate()`` [#fchansamp]_. This function
+**only controls the sample rate**; the total conversion time is equal
+to the sample time plus an additional number of ADC cycles. Consult
+the reference manual for your chip for more details.
+
+.. warning:: Decreasing ADC sample time speeds conversion, but it also
+ decreases the maximum allowable impedance of the voltage source you
+ are measuring. If your voltage source has a high impedance
+ (e.g. you're measuring Vcc through a potentiometer), and your
+ sample time is too low, you will get inaccurate results. Consult
+ the datasheet for your target for more details.
+
+.. note:: Wirish sets a sensible default sample rate to allow for
+ high-impedance inputs at ``init()`` time, but Wirish users who know
+ what they're doing may want to call this function to speed up ADC
+ conversion.
+
+.. doxygenfunction:: adc_set_sample_rate
+
+.. _adc-adc_smp_rate:
+
+The ``adc_smp_rate`` argument to :ref:`adc_set_sample_rate()
+<adc-adc_set_sample_rate>` is target-dependent.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::adc_smp_rate
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::adc_smp_rate
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+.. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up?
+
+.. _adc-adc_foreach:
+.. doxygenfunction:: adc_foreach
+
+.. _adc-adc_config_gpio:
+.. doxygenfunction:: adc_config_gpio
+
+STM32F1 only
+~~~~~~~~~~~~
+
+The following routines are available only on STM32F1 targets.
+
+.. _adc-adc_set_exttrig:
+.. doxygenfunction:: adc_set_exttrig
+
+``adc_calibrate()`` performs calibration necessary on STM32F1 before
+using an ADC. Note that on STM32F1 targets,
+:ref:`adc_enable_single_swstart() <adc-adc_enable_single_swstart>`
+calls ``adc_calibrate()``, so there's no need to do it separately.
+
+.. _adc-adc_calibrate:
+.. doxygenfunction:: adc_calibrate
+
+Register Maps
+-------------
+
+Individual ADC peripherals have the following register map. The base
+pointers are ``ADC1_BASE``, ``ADC2_BASE``, and ``ADC3_BASE``.
+
+.. _adc-adc_reg_map:
+.. doxygenstruct:: adc_reg_map
+
+On **STM32F2 targets**, there is an additional common set of registers
+shared by all ADC peripherals. Its base pointer is
+``ADC_COMMON_BASE``.
+
+.. _adc-adc_common_reg_map:
+.. doxygenstruct:: stm32f2::adc_common_reg_map
+
+Register Bit Definitions
+------------------------
+
+.. TODO [0.0.13]
+
+TODO
+
+.. rubric:: Footnotes
+
+.. [#fchansamp] Per-channel sample time configuration is possible,
+ but currently unsupported.
diff --git a/docs/source/libmaple/api/bitband.rst b/docs/source/libmaple/api/bitband.rst
new file mode 100644
index 0000000..768f678
--- /dev/null
+++ b/docs/source/libmaple/api/bitband.rst
@@ -0,0 +1,15 @@
+.. highlight:: c
+.. _libmaple-bitband:
+
+``<libmaple/bitband.h>``
+========================
+
+Bit-banding support.
+
+Functions
+---------
+
+.. doxygenfunction:: bb_sram_get_bit
+.. doxygenfunction:: bb_sram_set_bit
+.. doxygenfunction:: bb_peri_get_bit
+.. doxygenfunction:: bb_peri_set_bit
diff --git a/docs/source/libmaple/api/bkp.rst b/docs/source/libmaple/api/bkp.rst
new file mode 100644
index 0000000..4f0115b
--- /dev/null
+++ b/docs/source/libmaple/api/bkp.rst
@@ -0,0 +1,79 @@
+.. highlight:: c
+.. _libmaple-bkp:
+
+``bkp.h``
+=========
+
+Backup register (BKP) suport.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: bkp_dev
+.. doxygenstruct:: bkp_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: BKP
+
+Convenience Functions
+---------------------
+
+.. doxygenfunction:: bkp_init
+.. doxygenfunction:: bkp_enable_writes
+.. doxygenfunction:: bkp_disable_writes
+.. doxygenfunction:: bkp_read
+.. doxygenfunction:: bkp_write
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: BKP_BASE
+
+Register Bit Definitions
+------------------------
+
+Data Registers
+~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_DR_D
+
+RTC Clock Calibration Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_RTCCR_ASOS_BIT
+.. doxygendefine:: BKP_RTCCR_ASOE_BIT
+.. doxygendefine:: BKP_RTCCR_CCO_BIT
+
+.. doxygendefine:: BKP_RTCCR_ASOS
+.. doxygendefine:: BKP_RTCCR_ASOE
+.. doxygendefine:: BKP_RTCCR_CCO
+.. doxygendefine:: BKP_RTCCR_CAL
+
+Backup control register
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_CR_TPAL_BIT
+.. doxygendefine:: BKP_CR_TPE_BIT
+
+.. doxygendefine:: BKP_CR_TPAL
+.. doxygendefine:: BKP_CR_TPE
+
+Backup control/status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: BKP_CSR_TIF_BIT
+.. doxygendefine:: BKP_CSR_TEF_BIT
+.. doxygendefine:: BKP_CSR_TPIE_BIT
+.. doxygendefine:: BKP_CSR_CTI_BIT
+.. doxygendefine:: BKP_CSR_CTE_BIT
+
+.. doxygendefine:: BKP_CSR_TIF
+.. doxygendefine:: BKP_CSR_TEF
+.. doxygendefine:: BKP_CSR_TPIE
+.. doxygendefine:: BKP_CSR_CTI
+.. doxygendefine:: BKP_CSR_CTE
diff --git a/docs/source/libmaple/api/dac.rst b/docs/source/libmaple/api/dac.rst
new file mode 100644
index 0000000..55c8faf
--- /dev/null
+++ b/docs/source/libmaple/api/dac.rst
@@ -0,0 +1,123 @@
+.. highlight:: c
+.. _libmaple-dac:
+
+``dac.h``
+=========
+
+Digital to Analog Conversion (DAC) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: dac_dev
+.. doxygenstruct:: dac_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: DAC
+
+Functions
+---------
+
+.. doxygenfunction:: dac_init
+.. doxygenfunction:: dac_write_channel
+.. doxygenfunction:: dac_enable_channel
+.. doxygenfunction:: dac_disable_channel
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: DAC_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register
+~~~~~~~~~~~~~~~~
+
+**Channel 1**:
+
+.. doxygendefine:: DAC_CR_EN1
+.. doxygendefine:: DAC_CR_BOFF1
+.. doxygendefine:: DAC_CR_TEN1
+.. doxygendefine:: DAC_CR_TSEL1
+.. doxygendefine:: DAC_CR_WAVE1
+.. doxygendefine:: DAC_CR_MAMP1
+.. doxygendefine:: DAC_CR_DMAEN1
+
+**Channel 2**:
+
+.. doxygendefine:: DAC_CR_EN2
+.. doxygendefine:: DAC_CR_BOFF2
+.. doxygendefine:: DAC_CR_TEN2
+.. doxygendefine:: DAC_CR_TSEL2
+.. doxygendefine:: DAC_CR_WAVE2
+.. doxygendefine:: DAC_CR_MAMP2
+.. doxygendefine:: DAC_CR_DMAEN2
+
+Software trigger register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_SWTRIGR_SWTRIG1
+.. doxygendefine:: DAC_SWTRIGR_SWTRIG2
+
+Channel 1 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12R1_DACC1DHR
+
+Channel 1 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12L1_DACC1DHR
+
+Channel 1 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8R1_DACC1DHR
+
+Channel 2 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12R2_DACC2DHR
+
+Channel 2 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12L2_DACC2DHR
+
+Channel 2 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8R2_DACC2DHR
+
+Dual DAC 12-bit right-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12RD_DACC1DHR
+.. doxygendefine:: DAC_DHR12RD_DACC2DHR
+
+Dual DAC 12-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR12LD_DACC1DHR
+.. doxygendefine:: DAC_DHR12LD_DACC2DHR
+
+Dual DAC 8-bit left-aligned data holding register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DHR8RD_DACC1DHR
+.. doxygendefine:: DAC_DHR8RD_DACC2DHR
+
+Channel 1 data output register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DAC_DOR1_DACC1DOR
+
+Channel 1 data output register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. doxygendefine:: DAC_DOR2_DACC2DOR
diff --git a/docs/source/libmaple/api/delay.rst b/docs/source/libmaple/api/delay.rst
new file mode 100644
index 0000000..d11496b
--- /dev/null
+++ b/docs/source/libmaple/api/delay.rst
@@ -0,0 +1,11 @@
+.. highlight:: c
+.. _libmaple-delay:
+
+``<libmaple/delay.h>``
+======================
+
+Provides a simple busy-loop delay function. Note that this function
+does not account for time spent in interrupts, so actual delay times
+may vary depending on your application.
+
+.. doxygenfunction:: delay_us
diff --git a/docs/source/libmaple/api/dma.rst b/docs/source/libmaple/api/dma.rst
new file mode 100644
index 0000000..a9893e2
--- /dev/null
+++ b/docs/source/libmaple/api/dma.rst
@@ -0,0 +1,215 @@
+.. highlight:: c
+.. _libmaple-dma:
+
+``dma.h``
+=========
+
+Direct Memory Access (DMA) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: dma_reg_map
+.. doxygenstruct:: dma_dev
+.. doxygenstruct:: dma_handler_config
+.. doxygenenum:: dma_mode_flags
+.. doxygenenum:: dma_xfer_size
+.. doxygenenum:: dma_channel
+.. doxygenenum:: dma_priority
+.. doxygenenum:: dma_irq_cause
+.. doxygenstruct:: dma_channel_reg_map
+
+Devices
+-------
+
+.. doxygenvariable:: DMA1
+.. doxygenvariable:: DMA2
+
+Functions
+---------
+
+.. doxygenfunction:: dma_init
+.. doxygenfunction:: dma_setup_transfer
+.. doxygenfunction:: dma_set_num_transfers
+.. doxygenfunction:: dma_set_priority
+.. doxygenfunction:: dma_attach_interrupt
+.. doxygenfunction:: dma_detach_interrupt
+.. doxygenfunction:: dma_get_irq_cause
+.. doxygenfunction:: dma_enable
+.. doxygenfunction:: dma_disable
+.. doxygenfunction:: dma_set_mem_addr
+.. doxygenfunction:: dma_set_per_addr
+.. doxygenfunction:: dma_channel_regs
+.. doxygenfunction:: dma_is_channel_enabled
+.. doxygenfunction:: dma_get_isr_bits
+.. doxygenfunction:: dma_clear_isr_bits
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: DMA1_BASE
+.. doxygendefine:: DMA2_BASE
+
+Register Bit Definitions
+------------------------
+
+Interrupt status register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_ISR_TEIF7_BIT
+.. doxygendefine:: DMA_ISR_HTIF7_BIT
+.. doxygendefine:: DMA_ISR_TCIF7_BIT
+.. doxygendefine:: DMA_ISR_GIF7_BIT
+.. doxygendefine:: DMA_ISR_TEIF6_BIT
+.. doxygendefine:: DMA_ISR_HTIF6_BIT
+.. doxygendefine:: DMA_ISR_TCIF6_BIT
+.. doxygendefine:: DMA_ISR_GIF6_BIT
+.. doxygendefine:: DMA_ISR_TEIF5_BIT
+.. doxygendefine:: DMA_ISR_HTIF5_BIT
+.. doxygendefine:: DMA_ISR_TCIF5_BIT
+.. doxygendefine:: DMA_ISR_GIF5_BIT
+.. doxygendefine:: DMA_ISR_TEIF4_BIT
+.. doxygendefine:: DMA_ISR_HTIF4_BIT
+.. doxygendefine:: DMA_ISR_TCIF4_BIT
+.. doxygendefine:: DMA_ISR_GIF4_BIT
+.. doxygendefine:: DMA_ISR_TEIF3_BIT
+.. doxygendefine:: DMA_ISR_HTIF3_BIT
+.. doxygendefine:: DMA_ISR_TCIF3_BIT
+.. doxygendefine:: DMA_ISR_GIF3_BIT
+.. doxygendefine:: DMA_ISR_TEIF2_BIT
+.. doxygendefine:: DMA_ISR_HTIF2_BIT
+.. doxygendefine:: DMA_ISR_TCIF2_BIT
+.. doxygendefine:: DMA_ISR_GIF2_BIT
+.. doxygendefine:: DMA_ISR_TEIF1_BIT
+.. doxygendefine:: DMA_ISR_HTIF1_BIT
+.. doxygendefine:: DMA_ISR_TCIF1_BIT
+.. doxygendefine:: DMA_ISR_GIF1_BIT
+
+.. doxygendefine:: DMA_ISR_TEIF7
+.. doxygendefine:: DMA_ISR_HTIF7
+.. doxygendefine:: DMA_ISR_TCIF7
+.. doxygendefine:: DMA_ISR_GIF7
+.. doxygendefine:: DMA_ISR_TEIF6
+.. doxygendefine:: DMA_ISR_HTIF6
+.. doxygendefine:: DMA_ISR_TCIF6
+.. doxygendefine:: DMA_ISR_GIF6
+.. doxygendefine:: DMA_ISR_TEIF5
+.. doxygendefine:: DMA_ISR_HTIF5
+.. doxygendefine:: DMA_ISR_TCIF5
+.. doxygendefine:: DMA_ISR_GIF5
+.. doxygendefine:: DMA_ISR_TEIF4
+.. doxygendefine:: DMA_ISR_HTIF4
+.. doxygendefine:: DMA_ISR_TCIF4
+.. doxygendefine:: DMA_ISR_GIF4
+.. doxygendefine:: DMA_ISR_TEIF3
+.. doxygendefine:: DMA_ISR_HTIF3
+.. doxygendefine:: DMA_ISR_TCIF3
+.. doxygendefine:: DMA_ISR_GIF3
+.. doxygendefine:: DMA_ISR_TEIF2
+.. doxygendefine:: DMA_ISR_HTIF2
+.. doxygendefine:: DMA_ISR_TCIF2
+.. doxygendefine:: DMA_ISR_GIF2
+.. doxygendefine:: DMA_ISR_TEIF1
+.. doxygendefine:: DMA_ISR_HTIF1
+.. doxygendefine:: DMA_ISR_TCIF1
+.. doxygendefine:: DMA_ISR_GIF1
+
+Interrupt flag clear register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_IFCR_CTEIF7_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF7_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF7_BIT
+.. doxygendefine:: DMA_IFCR_CGIF7_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF6_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF6_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF6_BIT
+.. doxygendefine:: DMA_IFCR_CGIF6_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF5_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF5_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF5_BIT
+.. doxygendefine:: DMA_IFCR_CGIF5_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF4_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF4_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF4_BIT
+.. doxygendefine:: DMA_IFCR_CGIF4_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF3_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF3_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF3_BIT
+.. doxygendefine:: DMA_IFCR_CGIF3_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF2_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF2_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF2_BIT
+.. doxygendefine:: DMA_IFCR_CGIF2_BIT
+.. doxygendefine:: DMA_IFCR_CTEIF1_BIT
+.. doxygendefine:: DMA_IFCR_CHTIF1_BIT
+.. doxygendefine:: DMA_IFCR_CTCIF1_BIT
+.. doxygendefine:: DMA_IFCR_CGIF1_BIT
+
+.. doxygendefine:: DMA_IFCR_CTEIF7
+.. doxygendefine:: DMA_IFCR_CHTIF7
+.. doxygendefine:: DMA_IFCR_CTCIF7
+.. doxygendefine:: DMA_IFCR_CGIF7
+.. doxygendefine:: DMA_IFCR_CTEIF6
+.. doxygendefine:: DMA_IFCR_CHTIF6
+.. doxygendefine:: DMA_IFCR_CTCIF6
+.. doxygendefine:: DMA_IFCR_CGIF6
+.. doxygendefine:: DMA_IFCR_CTEIF5
+.. doxygendefine:: DMA_IFCR_CHTIF5
+.. doxygendefine:: DMA_IFCR_CTCIF5
+.. doxygendefine:: DMA_IFCR_CGIF5
+.. doxygendefine:: DMA_IFCR_CTEIF4
+.. doxygendefine:: DMA_IFCR_CHTIF4
+.. doxygendefine:: DMA_IFCR_CTCIF4
+.. doxygendefine:: DMA_IFCR_CGIF4
+.. doxygendefine:: DMA_IFCR_CTEIF3
+.. doxygendefine:: DMA_IFCR_CHTIF3
+.. doxygendefine:: DMA_IFCR_CTCIF3
+.. doxygendefine:: DMA_IFCR_CGIF3
+.. doxygendefine:: DMA_IFCR_CTEIF2
+.. doxygendefine:: DMA_IFCR_CHTIF2
+.. doxygendefine:: DMA_IFCR_CTCIF2
+.. doxygendefine:: DMA_IFCR_CGIF2
+.. doxygendefine:: DMA_IFCR_CTEIF1
+.. doxygendefine:: DMA_IFCR_CHTIF1
+.. doxygendefine:: DMA_IFCR_CTCIF1
+.. doxygendefine:: DMA_IFCR_CGIF1
+
+Channel configuration register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: DMA_CCR_MEM2MEM_BIT
+.. doxygendefine:: DMA_CCR_MINC_BIT
+.. doxygendefine:: DMA_CCR_PINC_BIT
+.. doxygendefine:: DMA_CCR_CIRC_BIT
+.. doxygendefine:: DMA_CCR_DIR_BIT
+.. doxygendefine:: DMA_CCR_TEIE_BIT
+.. doxygendefine:: DMA_CCR_HTIE_BIT
+.. doxygendefine:: DMA_CCR_TCIE_BIT
+.. doxygendefine:: DMA_CCR_EN_BIT
+
+.. doxygendefine:: DMA_CCR_MEM2MEM
+.. doxygendefine:: DMA_CCR_PL
+.. doxygendefine:: DMA_CCR_PL_LOW
+.. doxygendefine:: DMA_CCR_PL_MEDIUM
+.. doxygendefine:: DMA_CCR_PL_HIGH
+.. doxygendefine:: DMA_CCR_PL_VERY_HIGH
+.. doxygendefine:: DMA_CCR_MSIZE
+.. doxygendefine:: DMA_CCR_MSIZE_8BITS
+.. doxygendefine:: DMA_CCR_MSIZE_16BITS
+.. doxygendefine:: DMA_CCR_MSIZE_32BITS
+.. doxygendefine:: DMA_CCR_PSIZE
+.. doxygendefine:: DMA_CCR_PSIZE_8BITS
+.. doxygendefine:: DMA_CCR_PSIZE_16BITS
+.. doxygendefine:: DMA_CCR_PSIZE_32BITS
+.. doxygendefine:: DMA_CCR_MINC
+.. doxygendefine:: DMA_CCR_PINC
+.. doxygendefine:: DMA_CCR_CIRC
+.. doxygendefine:: DMA_CCR_DIR
+.. doxygendefine:: DMA_CCR_TEIE
+.. doxygendefine:: DMA_CCR_HTIE
+.. doxygendefine:: DMA_CCR_TCIE
+.. doxygendefine:: DMA_CCR_EN
diff --git a/docs/source/libmaple/api/exti.rst b/docs/source/libmaple/api/exti.rst
new file mode 100644
index 0000000..1038fbf
--- /dev/null
+++ b/docs/source/libmaple/api/exti.rst
@@ -0,0 +1,37 @@
+.. highlight:: c
+.. _libmaple-exti:
+
+``exti.h``
+==========
+
+:ref:`External interrupt <external-interrupts>` support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: exti_reg_map
+.. doxygenenum:: exti_trigger_mode
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. doxygenfunction:: exti_attach_interrupt
+.. doxygenfunction:: exti_detach_interrupt
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: EXTI_BASE
+
+Register Bit Definitions
+------------------------
+
+None at this time.
diff --git a/docs/source/libmaple/api/flash.rst b/docs/source/libmaple/api/flash.rst
new file mode 100644
index 0000000..52ff4d2
--- /dev/null
+++ b/docs/source/libmaple/api/flash.rst
@@ -0,0 +1,249 @@
+.. highlight:: c
+.. _libmaple-flash:
+
+``<libmaple/flash.h>``
+======================
+
+Flash memory support.
+
+The built-in Flash on different STM32 MCUs varies in terms of its
+eraseable page/sector size and read/write protections. There isn't
+currently much support for dealing with this. This header is mostly
+useful for its functions that control Flash features which affect
+system performance, like wait states and prefetch buffers.
+
+.. contents:: Contents
+ :local:
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+The following functions can be used to portably manipulate Flash memory.
+
+.. doxygenfunction:: flash_set_latency
+.. doxygenfunction:: flash_enable_features
+.. doxygenfunction:: flash_enable_prefetch
+
+Register Maps
+-------------
+
+Register maps vary by target. The base pointer is always ``FLASH_BASE``.
+
+Base Pointer
+~~~~~~~~~~~~
+
+.. doxygendefine:: FLASH_BASE
+
+STM32F1 targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f1::flash_reg_map
+
+STM32F2 targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f2::flash_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code. Available register bit definitions
+vary by target.
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+::
+
+ /* Access control register */
+
+ #define FLASH_ACR_PRFTBS_BIT 5
+ #define FLASH_ACR_PRFTBE_BIT 4
+ #define FLASH_ACR_HLFCYA_BIT 3
+
+ #define FLASH_ACR_PRFTBS (1U << FLASH_ACR_PRFTBS_BIT)
+ #define FLASH_ACR_PRFTBE (1U << FLASH_ACR_PRFTBE_BIT)
+ #define FLASH_ACR_HLFCYA (1U << FLASH_ACR_HLFCYA_BIT)
+ #define FLASH_ACR_LATENCY 0x7
+
+ /* Status register */
+
+ #define FLASH_SR_EOP_BIT 5
+ #define FLASH_SR_WRPRTERR_BIT 4
+ #define FLASH_SR_PGERR_BIT 2
+ #define FLASH_SR_BSY_BIT 0
+
+ #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
+ #define FLASH_SR_WRPRTERR (1U << FLASH_SR_WRPRTERR_BIT)
+ #define FLASH_SR_PGERR (1U << FLASH_SR_PGERR_BIT)
+ #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
+
+ /* Control register */
+
+ #define FLASH_CR_EOPIE_BIT 12
+ #define FLASH_CR_ERRIE_BIT 10
+ #define FLASH_CR_OPTWRE_BIT 9
+ #define FLASH_CR_LOCK_BIT 7
+ #define FLASH_CR_STRT_BIT 6
+ #define FLASH_CR_OPTER_BIT 5
+ #define FLASH_CR_OPTPG_BIT 4
+ #define FLASH_CR_MER_BIT 2
+ #define FLASH_CR_PER_BIT 1
+ #define FLASH_CR_PG_BIT 0
+
+ #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
+ #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
+ #define FLASH_CR_OPTWRE (1U << FLASH_CR_OPTWRE_BIT)
+ #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
+ #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
+ #define FLASH_CR_OPTER (1U << FLASH_CR_OPTER_BIT)
+ #define FLASH_CR_OPTPG (1U << FLASH_CR_OPTPG_BIT)
+ #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
+ #define FLASH_CR_PER (1U << FLASH_CR_PER_BIT)
+ #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
+
+ /* Option byte register */
+
+ #define FLASH_OBR_nRST_STDBY_BIT 4
+ #define FLASH_OBR_nRST_STOP_BIT 3
+ #define FLASH_OBR_WDG_SW_BIT 2
+ #define FLASH_OBR_RDPRT_BIT 1
+ #define FLASH_OBR_OPTERR_BIT 0
+
+ #define FLASH_OBR_DATA1 (0xFF << 18)
+ #define FLASH_OBR_DATA0 (0xFF << 10)
+ #define FLASH_OBR_USER 0x3FF
+ #define FLASH_OBR_nRST_STDBY (1U << FLASH_OBR_nRST_STDBY_BIT)
+ #define FLASH_OBR_nRST_STOP (1U << FLASH_OBR_nRST_STOP_BIT)
+ #define FLASH_OBR_WDG_SW (1U << FLASH_OBR_WDG_SW_BIT)
+ #define FLASH_OBR_RDPRT (1U << FLASH_OBR_RDPRT_BIT)
+ #define FLASH_OBR_OPTERR (1U << FLASH_OBR_OPTERR_BIT)
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+::
+
+ /* Access control register */
+
+ #define FLASH_ACR_DCRST_BIT 12
+ #define FLASH_ACR_ICRST_BIT 11
+ #define FLASH_ACR_DCEN_BIT 10
+ #define FLASH_ACR_ICEN_BIT 9
+ #define FLASH_ACR_PRFTEN_BIT 8
+
+ #define FLASH_ACR_DCRST (1U << FLASH_ACR_DCRST_BIT)
+ #define FLASH_ACR_ICRST (1U << FLASH_ACR_ICRST_BIT)
+ #define FLASH_ACR_DCEN (1U << FLASH_ACR_DCEN_BIT)
+ #define FLASH_ACR_ICEN (1U << FLASH_ACR_ICEN_BIT)
+ #define FLASH_ACR_PRFTEN (1U << FLASH_ACR_PRFTEN_BIT)
+ #define FLASH_ACR_LATENCY 0x7
+ #define FLASH_ACR_LATENCY_0WS 0x0
+ #define FLASH_ACR_LATENCY_1WS 0x1
+ #define FLASH_ACR_LATENCY_2WS 0x2
+ #define FLASH_ACR_LATENCY_3WS 0x3
+ #define FLASH_ACR_LATENCY_4WS 0x4
+ #define FLASH_ACR_LATENCY_5WS 0x5
+ #define FLASH_ACR_LATENCY_6WS 0x6
+ #define FLASH_ACR_LATENCY_7WS 0x7
+
+ /* Key register */
+
+ #define FLASH_KEYR_KEY1 0x45670123
+ #define FLASH_KEYR_KEY2 0xCDEF89AB
+
+ /* Option key register */
+
+ #define FLASH_OPTKEYR_OPTKEY1 0x08192A3B
+ #define FLASH_OPTKEYR_OPTKEY2 0x4C5D6E7F
+
+ /* Status register */
+
+ #define FLASH_SR_BSY_BIT 16
+ #define FLASH_SR_PGSERR_BIT 7
+ #define FLASH_SR_PGPERR_BIT 6
+ #define FLASH_SR_PGAERR_BIT 5
+ #define FLASH_SR_WRPERR_BIT 4
+ #define FLASH_SR_OPERR_BIT 1
+ #define FLASH_SR_EOP_BIT 0
+
+ #define FLASH_SR_BSY (1U << FLASH_SR_BSY_BIT)
+ #define FLASH_SR_PGSERR (1U << FLASH_SR_PGSERR_BIT)
+ #define FLASH_SR_PGPERR (1U << FLASH_SR_PGPERR_BIT)
+ #define FLASH_SR_PGAERR (1U << FLASH_SR_PGAERR_BIT)
+ #define FLASH_SR_WRPERR (1U << FLASH_SR_WRPERR_BIT)
+ #define FLASH_SR_OPERR (1U << FLASH_SR_OPERR_BIT)
+ #define FLASH_SR_EOP (1U << FLASH_SR_EOP_BIT)
+
+ /* Control register */
+
+ #define FLASH_CR_LOCK_BIT 31
+ #define FLASH_CR_ERRIE_BIT 25
+ #define FLASH_CR_EOPIE_BIT 24
+ #define FLASH_CR_STRT_BIT 16
+ #define FLASH_CR_MER_BIT 2
+ #define FLASH_CR_SER_BIT 1
+ #define FLASH_CR_PG_BIT 0
+
+ #define FLASH_CR_LOCK (1U << FLASH_CR_LOCK_BIT)
+ #define FLASH_CR_ERRIE (1U << FLASH_CR_ERRIE_BIT)
+ #define FLASH_CR_EOPIE (1U << FLASH_CR_EOPIE_BIT)
+ #define FLASH_CR_STRT (1U << FLASH_CR_STRT_BIT)
+
+ #define FLASH_CR_PSIZE (0x3 << 8)
+ #define FLASH_CR_PSIZE_MUL8 (0x0 << 8)
+ #define FLASH_CR_PSIZE_MUL16 (0x1 << 8)
+ #define FLASH_CR_PSIZE_MUL32 (0x2 << 8)
+ #define FLASH_CR_PSIZE_MUL64 (0x3 << 8)
+
+ #define FLASH_CR_SNB (0xF << 3)
+ #define FLASH_CR_SNB_0 (0x0 << 3)
+ #define FLASH_CR_SNB_1 (0x1 << 3)
+ #define FLASH_CR_SNB_2 (0x2 << 3)
+ #define FLASH_CR_SNB_3 (0x3 << 3)
+ #define FLASH_CR_SNB_4 (0x4 << 3)
+ #define FLASH_CR_SNB_5 (0x5 << 3)
+ #define FLASH_CR_SNB_6 (0x6 << 3)
+ #define FLASH_CR_SNB_7 (0x7 << 3)
+ #define FLASH_CR_SNB_8 (0x8 << 3)
+ #define FLASH_CR_SNB_9 (0x9 << 3)
+ #define FLASH_CR_SNB_10 (0xA << 3)
+ #define FLASH_CR_SNB_11 (0xB << 3)
+
+ #define FLASH_CR_MER (1U << FLASH_CR_MER_BIT)
+ #define FLASH_CR_SER (1U << FLASH_CR_SER_BIT)
+ #define FLASH_CR_PG (1U << FLASH_CR_PG_BIT)
+
+ /* Option control register */
+
+ #define FLASH_OPTCR_NRST_STDBY_BIT 7
+ #define FLASH_OPTCR_NRST_STOP_BIT 6
+ #define FLASH_OPTCR_WDG_SW_BIT 5
+ #define FLASH_OPTCR_OPTSTRT_BIT 1
+ #define FLASH_OPTCR_OPTLOCK_BIT 0
+
+ #define FLASH_OPTCR_NWRP (0x3FF << 16)
+
+ /* Excluded: The many level 1 values */
+ #define FLASH_OPTCR_RDP (0xFF << 8)
+ #define FLASH_OPTCR_RDP_LEVEL0 (0xAA << 8)
+ #define FLASH_OPTCR_RDP_LEVEL2 (0xCC << 8)
+
+ #define FLASH_OPTCR_USER (0x7 << 5)
+ #define FLASH_OPTCR_nRST_STDBY (1U << FLASH_OPTCR_nRST_STDBY_BIT)
+ #define FLASH_OPTCR_nRST_STOP (1U << FLASH_OPTCR_nRST_STOP_BIT)
+ #define FLASH_OPTCR_WDG_SW (1U << FLASH_OPTCR_WDG_SW_BIT)
+
+ #define FLASH_OPTCR_BOR_LEV (0x3 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL3 (0x0 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL2 (0x1 << 2)
+ #define FLASH_OPTCR_BOR_LEVEL1 (0x2 << 2)
+ #define FLASH_OPTCR_BOR_OFF (0x3 << 2)
+
+ #define FLASH_OPTCR_OPTSTRT (1U << FLASH_OPTCR_OPTSTRT_BIT)
+ #define FLASH_OPTCR_OPTLOCK (1U << FLASH_OPTCR_OPTLOCK_BIT)
diff --git a/docs/source/libmaple/api/fsmc.rst b/docs/source/libmaple/api/fsmc.rst
new file mode 100644
index 0000000..e2bf87a
--- /dev/null
+++ b/docs/source/libmaple/api/fsmc.rst
@@ -0,0 +1,235 @@
+.. highlight:: c
+.. _libmaple-fsmc:
+
+``<libmaple/fsmc.h>``
+=====================
+
+Flexible Static Memory Controller (FSMC) support. The FSMC peripheral
+is only available on some targets. Including this header on a target
+without an FSMC will cause a compilation error. Check your target's
+documentation to determine if it's available. You can also use
+:ref:`STM32_HAVE_FSMC <libmaple-stm32-STM32_HAVE_FSMC>` from
+``<libmaple/stm32.h>`` to determine whether your target has an FSMC at
+build time.
+
+All functionality documented here is portable.
+
+.. contents:: Contents
+ :local:
+
+Usage Note
+----------
+
+FSMC support is fairly limited at this time. Current Leaflabs boards
+only use the FSMC to interface with external SRAM chips, so that's
+what there's the most support for (:ref:`patches welcome!
+<libmaple-contributing>`). Even for use with SRAM, you will still need
+to program some registers directly.
+
+To use the FSMC with an SRAM chip, first call
+:ref:`fsmc_sram_init_gpios() <libmaple-fsmc-fsmc_sram_init_gpios>` to
+configure its data, address, and control lines. Then, turn on the
+FSMC clock (by calling :ref:`rcc_clk_enable(RCC_FSMC)
+<libmaple-rcc-rcc_clk_enable>`). You can then configure the relevant
+:ref:`fsmc_nor_psram_reg_map <libmaple-fsmc-fsmc_nor_psram_reg_map>`
+``BCR`` register yourself for the SRAM chip you are using.
+
+You can additionally use :ref:`fsmc_nor_psram_set_datast()
+<libmaple-fsmc-fsmc_nor_psram_set_datast>` and
+:ref:`fsmc_nor_psram_set_datast() <libmaple-fsmc-fsmc_nor_psram_set_datast>`
+to control read/write timing.
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. _libmaple-fsmc-fsmc_sram_init_gpios:
+.. doxygenfunction:: fsmc_sram_init_gpios
+.. _libmaple-fsmc-fsmc_nor_psram_set_datast:
+.. doxygenfunction:: fsmc_nor_psram_set_datast
+.. _libmaple-fsmc-fsmc_nor_psram_set_addset:
+.. doxygenfunction:: fsmc_nor_psram_set_addset
+
+Register Maps
+-------------
+
+The general purpose register map type is ``fsmc_reg_map``; its base
+pointer is ``FSMC_BASE``. The ``fsmc_nor_psram_reg_map`` type is for
+use configuring the registers for an individual NOR/PSRAM region
+(``FSMC_BCRx``, ``FSMC_BTRx``, and ``FSMC_BWTRx``); the relevant base
+pointers are ``FSMC_NOR_PSRAM_REGION1`` through
+``FSMC_NOR_PSRAM_REGION4``.
+
+.. doxygendefine:: FSMC_BASE
+
+.. doxygendefine:: FSMC_NOR_PSRAM1_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM2_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM3_BASE
+.. doxygendefine:: FSMC_NOR_PSRAM4_BASE
+
+.. doxygenstruct:: fsmc_reg_map
+.. _libmaple-fsmc-fsmc_nor_psram_reg_map:
+.. doxygenstruct:: fsmc_nor_psram_reg_map
+
+Memory Bank Boundary Addresses
+------------------------------
+
+Reading and writing data on an external memory chip using FSMC is done
+by reading and writing from addresses in special memory-mapped
+sections of the address space called *memory banks*.
+
+This is convenient, since it implies that the usual load and store
+instructions used for I/O with the internal SRAM are also used to
+perform bus transactions with the external memory chip. (Which means
+you can use ``memcpy()`` etc. on external memory.)
+
+Pointers to the memory banks' base addresses are given by the
+following macros.
+
+.. doxygendefine:: FSMC_BANK1
+.. doxygendefine:: FSMC_BANK2
+.. doxygendefine:: FSMC_BANK3
+.. doxygendefine:: FSMC_BANK4
+
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION1
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION2
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION3
+.. doxygendefine:: FSMC_NOR_PSRAM_REGION4
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* NOR/PSRAM chip-select control registers */
+
+ #define FSMC_BCR_CBURSTRW_BIT 19
+ #define FSMC_BCR_ASYNCWAIT_BIT 15
+ #define FSMC_BCR_EXTMOD_BIT 14
+ #define FSMC_BCR_WAITEN_BIT 13
+ #define FSMC_BCR_WREN_BIT 12
+ #define FSMC_BCR_WAITCFG_BIT 11
+ #define FSMC_BCR_WRAPMOD_BIT 10
+ #define FSMC_BCR_WAITPOL_BIT 9
+ #define FSMC_BCR_BURSTEN_BIT 8
+ #define FSMC_BCR_FACCEN_BIT 6
+ #define FSMC_BCR_MUXEN_BIT 1
+ #define FSMC_BCR_MBKEN_BIT 0
+
+ #define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT)
+ #define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT)
+ #define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT)
+ #define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT)
+ #define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT)
+ #define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT)
+ #define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT)
+ #define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT)
+ #define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT)
+ #define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT)
+ #define FSMC_BCR_MWID (0x3 << 4)
+ #define FSMC_BCR_MWID_8BITS (0x0 << 4)
+ #define FSMC_BCR_MWID_16BITS (0x1 << 4)
+ #define FSMC_BCR_MTYP (0x3 << 2)
+ #define FSMC_BCR_MTYP_SRAM (0x0 << 2)
+ #define FSMC_BCR_MTYP_PSRAM (0x1 << 2)
+ #define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2)
+ #define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT)
+ #define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT)
+
+ /* SRAM/NOR-Flash chip-select timing registers */
+
+ #define FSMC_BTR_ACCMOD (0x3 << 28)
+ #define FSMC_BTR_ACCMOD_A (0x0 << 28)
+ #define FSMC_BTR_ACCMOD_B (0x1 << 28)
+ #define FSMC_BTR_ACCMOD_C (0x2 << 28)
+ #define FSMC_BTR_ACCMOD_D (0x3 << 28)
+ #define FSMC_BTR_DATLAT (0xF << 24)
+ #define FSMC_BTR_CLKDIV (0xF << 20)
+ #define FSMC_BTR_BUSTURN (0xF << 16)
+ #define FSMC_BTR_DATAST (0xFF << 8)
+ #define FSMC_BTR_ADDHLD (0xF << 4)
+ #define FSMC_BTR_ADDSET 0xF
+
+ /* SRAM/NOR-Flash write timing registers */
+
+ #define FSMC_BWTR_ACCMOD (0x3 << 28)
+ #define FSMC_BWTR_ACCMOD_A (0x0 << 28)
+ #define FSMC_BWTR_ACCMOD_B (0x1 << 28)
+ #define FSMC_BWTR_ACCMOD_C (0x2 << 28)
+ #define FSMC_BWTR_ACCMOD_D (0x3 << 28)
+ #define FSMC_BWTR_DATLAT (0xF << 24)
+ #define FSMC_BWTR_CLKDIV (0xF << 20)
+ #define FSMC_BWTR_DATAST (0xFF << 8)
+ #define FSMC_BWTR_ADDHLD (0xF << 4)
+ #define FSMC_BWTR_ADDSET 0xF
+
+ /* NAND Flash/PC Card controller registers */
+
+ #define FSMC_PCR_ECCEN_BIT 6
+ #define FSMC_PCR_PTYP_BIT 3
+ #define FSMC_PCR_PBKEN_BIT 2
+ #define FSMC_PCR_PWAITEN_BIT 1
+
+ #define FSMC_PCR_ECCPS (0x7 << 17)
+ #define FSMC_PCR_ECCPS_256B (0x0 << 17)
+ #define FSMC_PCR_ECCPS_512B (0x1 << 17)
+ #define FSMC_PCR_ECCPS_1024B (0x2 << 17)
+ #define FSMC_PCR_ECCPS_2048B (0x3 << 17)
+ #define FSMC_PCR_ECCPS_4096B (0x4 << 17)
+ #define FSMC_PCR_ECCPS_8192B (0x5 << 17)
+ #define FSMC_PCR_TAR (0xF << 13)
+ #define FSMC_PCR_TCLR (0xF << 9)
+ #define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT)
+ #define FSMC_PCR_PWID (0x3 << 4)
+ #define FSMC_PCR_PWID_8BITS (0x0 << 4)
+ #define FSMC_PCR_PWID_16BITS (0x1 << 4)
+ #define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT)
+ #define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT)
+ #define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT)
+
+ /* FIFO status and interrupt registers */
+
+ #define FSMC_SR_FEMPT_BIT 6
+ #define FSMC_SR_IFEN_BIT 5
+ #define FSMC_SR_ILEN_BIT 4
+ #define FSMC_SR_IREN_BIT 3
+ #define FSMC_SR_IFS_BIT 2
+ #define FSMC_SR_ILS_BIT 1
+ #define FSMC_SR_IRS_BIT 0
+
+ #define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT)
+ #define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT)
+ #define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT)
+ #define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT)
+ #define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT)
+ #define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT)
+ #define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT)
+
+ /* Common memory space timing registers */
+
+ #define FSMC_PMEM_MEMHIZ (0xFF << 24)
+ #define FSMC_PMEM_MEMHOLD (0xFF << 16)
+ #define FSMC_PMEM_MEMWAIT (0xFF << 8)
+ #define FSMC_PMEM_MEMSET 0xFF
+
+ /* Attribute memory space timing registers */
+
+ #define FSMC_PATT_ATTHIZ (0xFF << 24)
+ #define FSMC_PATT_ATTHOLD (0xFF << 16)
+ #define FSMC_PATT_ATTWAIT (0xFF << 8)
+ #define FSMC_PATT_ATTSET 0xFF
+
+ /* I/O space timing register 4 */
+
+ #define FSMC_PIO_IOHIZ (0xFF << 24)
+ #define FSMC_PIO_IOHOLD (0xFF << 16)
+ #define FSMC_PIO_IOWAIT (0xFF << 8)
+ #define FSMC_PIO_IOSET 0xF
diff --git a/docs/source/libmaple/api/gpio.rst b/docs/source/libmaple/api/gpio.rst
new file mode 100644
index 0000000..faf0ad2
--- /dev/null
+++ b/docs/source/libmaple/api/gpio.rst
@@ -0,0 +1,243 @@
+.. highlight:: c
+.. _libmaple-gpio:
+
+``gpio.h``
+==========
+
+General Purpose Input/Output (GPIO) port and Alternate Function
+Input/Output (AFIO) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: gpio_reg_map
+.. doxygenstruct:: gpio_dev
+.. doxygenenum:: gpio_pin_mode
+
+.. doxygenstruct:: afio_reg_map
+.. doxygenenum:: afio_exti_port
+.. doxygenenum:: afio_exti_num
+.. doxygenenum:: afio_remap_peripheral
+.. doxygenenum:: afio_debug_cfg
+
+Devices
+-------
+
+.. doxygenvariable:: GPIOA
+.. doxygenvariable:: GPIOB
+.. doxygenvariable:: GPIOC
+.. doxygenvariable:: GPIOD
+.. doxygenvariable:: GPIOE
+.. doxygenvariable:: GPIOF
+.. doxygenvariable:: GPIOG
+
+Functions
+---------
+
+.. doxygenfunction:: gpio_init
+.. doxygenfunction:: gpio_init_all
+.. doxygenfunction:: gpio_set_mode
+.. doxygenfunction:: gpio_exti_port
+.. doxygenfunction:: gpio_write_bit
+.. doxygenfunction:: gpio_read_bit
+.. doxygenfunction:: gpio_toggle_bit
+
+.. doxygenfunction:: afio_init
+.. doxygenfunction:: afio_exti_select
+
+.. _gpio-h-afio-remap:
+.. doxygenfunction:: afio_remap
+.. doxygenfunction:: afio_cfg_debug_ports
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: GPIOA_BASE
+.. doxygendefine:: GPIOB_BASE
+.. doxygendefine:: GPIOC_BASE
+.. doxygendefine:: GPIOD_BASE
+.. doxygendefine:: GPIOE_BASE
+.. doxygendefine:: GPIOF_BASE
+.. doxygendefine:: GPIOG_BASE
+
+.. doxygendefine:: AFIO_BASE
+
+Register Bit Definitions
+------------------------
+
+GPIO Control Registers
+~~~~~~~~~~~~~~~~~~~~~~
+
+These values apply to both the low and high configuration registers
+(ST RM0008: GPIOx_CRL and GPIOx_CRH). You can shift them right by the
+appropriate number of bits for the GPIO port bit you're interested in
+to obtain a bit mask.
+
+For example, to mask out just the value of GPIOA_CRH_CNF12, note that
+GPIO port bit 12's configuration starts at bit 18 in the corresponding
+CRH. Thus, an appropriate mask is ``GPIOA_BASE->CRH & (GPIO_CR_CNF <<
+18)``.
+
+.. doxygendefine:: GPIO_CR_CNF_INPUT_ANALOG
+.. doxygendefine:: GPIO_CR_CNF_INPUT_FLOATING
+.. doxygendefine:: GPIO_CR_CNF_INPUT_PU_PD
+.. doxygendefine:: GPIO_CR_CNF_OUTPUT_PP
+.. doxygendefine:: GPIO_CR_CNF_OUTPUT_OD
+.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_PP
+.. doxygendefine:: GPIO_CR_CNF_AF_OUTPUT_OD
+.. doxygendefine:: GPIO_CR_MODE_INPUT
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_10MHZ
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_2MHZ
+.. doxygendefine:: GPIO_CR_MODE_OUTPUT_50MHZ
+
+Event Control Register
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EVCR_EVOE
+.. doxygendefine:: AFIO_EVCR_PORT_PA
+.. doxygendefine:: AFIO_EVCR_PORT_PB
+.. doxygendefine:: AFIO_EVCR_PORT_PC
+.. doxygendefine:: AFIO_EVCR_PORT_PD
+.. doxygendefine:: AFIO_EVCR_PORT_PE
+.. doxygendefine:: AFIO_EVCR_PIN_0
+.. doxygendefine:: AFIO_EVCR_PIN_1
+.. doxygendefine:: AFIO_EVCR_PIN_2
+.. doxygendefine:: AFIO_EVCR_PIN_3
+.. doxygendefine:: AFIO_EVCR_PIN_4
+.. doxygendefine:: AFIO_EVCR_PIN_5
+.. doxygendefine:: AFIO_EVCR_PIN_6
+.. doxygendefine:: AFIO_EVCR_PIN_7
+.. doxygendefine:: AFIO_EVCR_PIN_8
+.. doxygendefine:: AFIO_EVCR_PIN_9
+.. doxygendefine:: AFIO_EVCR_PIN_10
+.. doxygendefine:: AFIO_EVCR_PIN_11
+.. doxygendefine:: AFIO_EVCR_PIN_12
+.. doxygendefine:: AFIO_EVCR_PIN_13
+.. doxygendefine:: AFIO_EVCR_PIN_14
+.. doxygendefine:: AFIO_EVCR_PIN_15
+
+AF Remap and Debug I/O Configuration Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_SW
+.. doxygendefine:: AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW
+.. doxygendefine:: AFIO_MAPR_ADC2_ETRGREG_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC2_ETRGINJ_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC1_ETRGREG_REMAP
+.. doxygendefine:: AFIO_MAPR_ADC1_ETRGINJ_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM5CH4_IREMAP
+.. doxygendefine:: AFIO_MAPR_PD01_REMAP
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PB8_PB9
+.. doxygendefine:: AFIO_MAPR_CAN_REMAP_PD0_PD1
+.. doxygendefine:: AFIO_MAPR_TIM4_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_TIM3_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11
+.. doxygendefine:: AFIO_MAPR_TIM2_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_TIM1_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_NONE
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_PARTIAL
+.. doxygendefine:: AFIO_MAPR_USART3_REMAP_FULL
+.. doxygendefine:: AFIO_MAPR_USART2_REMAP
+.. doxygendefine:: AFIO_MAPR_USART1_REMAP
+.. doxygendefine:: AFIO_MAPR_I2C1_REMAP
+.. doxygendefine:: AFIO_MAPR_SPI1_REMAP
+
+External Interrupt Configuration Register 1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EXTICR1_EXTI3
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI3_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI2
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI2_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI1
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI1_PG
+.. doxygendefine:: AFIO_EXTICR1_EXTI0
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PA
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PB
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PC
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PD
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PE
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PF
+.. doxygendefine:: AFIO_EXTICR1_EXTI0_PG
+
+External Interrupt Configuration Register 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_EXTICR2_EXTI7
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI7_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI6
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI6_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI5
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI5_PG
+.. doxygendefine:: AFIO_EXTICR2_EXTI4
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PA
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PB
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PC
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PD
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PE
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PF
+.. doxygendefine:: AFIO_EXTICR2_EXTI4_PG
+
+AF Remap and Debug I/O Configuration Register 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: AFIO_MAPR2_FSMC_NADV
+.. doxygendefine:: AFIO_MAPR2_TIM14_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM13_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM11_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM10_REMAP
+.. doxygendefine:: AFIO_MAPR2_TIM9_REMAP
diff --git a/docs/source/libmaple/api/i2c.rst b/docs/source/libmaple/api/i2c.rst
new file mode 100644
index 0000000..ff380cc
--- /dev/null
+++ b/docs/source/libmaple/api/i2c.rst
@@ -0,0 +1,124 @@
+.. highlight:: c
+.. _libmaple-i2c:
+
+``i2c.h``
+=========
+
+Inter-Integrated Circuit (|i2c|) peripheral support.
+
+.. contents:: Contents
+ :local:
+
+Important Note
+--------------
+
+There are some important known problems with the built-in I2C
+peripherals. For more information, see STM32F10xx8 and STM32F10xxB
+Errata sheet (ST Doc ID 14574 Rev 8), Section 2.11.1, 2.11.2. An
+important consequence of these problems is that the |i2c| interrupt
+must not be preempted. Consequently, (by default) Wirish uses an
+|i2c| interrupt priority which is the highest in the system (priority
+level 0). Other interrupt priorities are set lower.
+
+Types
+-----
+
+.. doxygenstruct:: i2c_reg_map
+.. doxygenenum:: i2c_state
+.. doxygenstruct:: i2c_msg
+.. doxygenstruct:: i2c_dev
+
+Devices
+-------
+
+.. doxygenvariable:: I2C1
+.. doxygenvariable:: I2C2
+
+Functions
+---------
+
+.. doxygenfunction:: i2c_init
+.. doxygenfunction:: i2c_master_enable
+.. doxygenfunction:: i2c_master_xfer
+.. doxygenfunction:: i2c_bus_reset
+.. doxygenfunction:: i2c_disable
+.. doxygenfunction:: i2c_peripheral_enable
+.. doxygenfunction:: i2c_peripheral_disable
+.. doxygenfunction:: i2c_write
+.. doxygenfunction:: i2c_set_input_clk
+.. doxygenfunction:: i2c_set_clk_control
+.. doxygenfunction:: i2c_set_trise
+.. doxygenfunction:: i2c_start_condition
+.. doxygenfunction:: i2c_stop_condition
+.. doxygenfunction:: i2c_enable_irq
+.. doxygenfunction:: i2c_disable_irq
+.. doxygenfunction:: i2c_enable_ack
+.. doxygenfunction:: i2c_disable_ack
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: I2C1_BASE
+.. doxygendefine:: I2C2_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CR1_SWRST
+.. doxygendefine:: I2C_CR1_ALERT
+.. doxygendefine:: I2C_CR1_PEC
+.. doxygendefine:: I2C_CR1_POS
+.. doxygendefine:: I2C_CR1_ACK
+.. doxygendefine:: I2C_CR1_START
+.. doxygendefine:: I2C_CR1_STOP
+.. doxygendefine:: I2C_CR1_PE
+
+Control register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CR2_LAST
+.. doxygendefine:: I2C_CR2_DMAEN
+.. doxygendefine:: I2C_CR2_ITBUFEN
+.. doxygendefine:: I2C_CR2_ITEVTEN
+.. doxygendefine:: I2C_CR2_ITERREN
+.. doxygendefine:: I2C_CR2_FREQ
+
+Clock control register
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_CCR_FS
+.. doxygendefine:: I2C_CCR_DUTY
+.. doxygendefine:: I2C_CCR_CCR
+
+Status register 1
+~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_SR1_SB
+.. doxygendefine:: I2C_SR1_ADDR
+.. doxygendefine:: I2C_SR1_BTF
+.. doxygendefine:: I2C_SR1_ADD10
+.. doxygendefine:: I2C_SR1_STOPF
+.. doxygendefine:: I2C_SR1_RXNE
+.. doxygendefine:: I2C_SR1_TXE
+.. doxygendefine:: I2C_SR1_BERR
+.. doxygendefine:: I2C_SR1_ARLO
+.. doxygendefine:: I2C_SR1_AF
+.. doxygendefine:: I2C_SR1_OVR
+.. doxygendefine:: I2C_SR1_PECERR
+.. doxygendefine:: I2C_SR1_TIMEOUT
+.. doxygendefine:: I2C_SR1_SMBALERT
+
+Status register 2
+~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: I2C_SR2_MSL
+.. doxygendefine:: I2C_SR2_BUSY
+.. doxygendefine:: I2C_SR2_TRA
+.. doxygendefine:: I2C_SR2_GENCALL
+.. doxygendefine:: I2C_SR2_SMBDEFAULT
+.. doxygendefine:: I2C_SR2_SMBHOST
+.. doxygendefine:: I2C_SR2_DUALF
+.. doxygendefine:: I2C_SR2_PEC
diff --git a/docs/source/libmaple/api/iwdg.rst b/docs/source/libmaple/api/iwdg.rst
new file mode 100644
index 0000000..65f9f7b
--- /dev/null
+++ b/docs/source/libmaple/api/iwdg.rst
@@ -0,0 +1,80 @@
+.. highlight:: c
+.. _libmaple-iwdg:
+
+``<libmaple/iwdg.h>``
+=====================
+
+Independent Watchdog (IWDG) support. The IWDG peripheral is common
+across supported targets, so everything documented here is portable.
+
+.. contents:: Contents
+ :local:
+
+Usage Note
+----------
+
+To use the independent watchdog, first call :ref:`iwdg_init()
+<libmaple-iwdg-iwdg_init>` with the appropriate prescaler and IWDG
+counter reload values for your application. Afterwards, you must
+periodically call :ref:`iwdg_feed() <libmaple-iwdg-iwdg_feed>` before
+the IWDG counter reaches zero to reset the counter to its reload
+value. If you do not, the chip will reset.
+
+Once started, the independent watchdog cannot be turned off.
+
+Devices
+-------
+
+None at this time.
+
+Functions
+---------
+
+.. _libmaple-iwdg-iwdg_init:
+.. doxygenfunction:: iwdg_init
+.. _libmaple-iwdg-iwdg_feed:
+.. doxygenfunction:: iwdg_feed
+
+Types
+-----
+
+.. doxygenenum:: iwdg_prescaler
+
+
+Register Maps
+-------------
+
+.. doxygendefine:: IWDG_BASE
+
+.. doxygenstruct:: iwdg_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* Key register */
+
+ #define IWDG_KR_UNLOCK 0x5555
+ #define IWDG_KR_FEED 0xAAAA
+ #define IWDG_KR_START 0xCCCC
+
+ /* Prescaler register */
+
+ #define IWDG_PR_DIV_4 0x0
+ #define IWDG_PR_DIV_8 0x1
+ #define IWDG_PR_DIV_16 0x2
+ #define IWDG_PR_DIV_32 0x3
+ #define IWDG_PR_DIV_64 0x4
+ #define IWDG_PR_DIV_128 0x5
+ #define IWDG_PR_DIV_256 0x6
+
+ /* Status register */
+
+ #define IWDG_SR_RVU_BIT 1
+ #define IWDG_SR_PVU_BIT 0
+
+ #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT)
+ #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT)
diff --git a/docs/source/libmaple/api/libmaple.rst b/docs/source/libmaple/api/libmaple.rst
new file mode 100644
index 0000000..7deb659
--- /dev/null
+++ b/docs/source/libmaple/api/libmaple.rst
@@ -0,0 +1,11 @@
+.. highlight:: c
+.. _libmaple-libmaple:
+
+``<libmaple/libmaple.h>``
+=========================
+
+Base include file for libmaple.
+
+This file includes :ref:`libmaple-libmaple_types`,
+:ref:`libmaple-stm32`, and :ref:`libmaple-util`. You shouldn't rely
+on it doing anything else, however.
diff --git a/docs/source/libmaple/api/libmaple_types.rst b/docs/source/libmaple/api/libmaple_types.rst
new file mode 100644
index 0000000..5ca446e
--- /dev/null
+++ b/docs/source/libmaple/api/libmaple_types.rst
@@ -0,0 +1,85 @@
+.. highlight:: c
+.. _libmaple-libmaple_types:
+
+``<libmaple/libmaple_types.h>``
+===============================
+
+Defines the base types and type-related macros used throughout the
+rest of libmaple.
+
+.. contents:: Contents
+ :local:
+
+Integral Types
+--------------
+
+.. doxygentypedef:: uint8
+.. doxygentypedef:: uint16
+.. doxygentypedef:: uint32
+.. doxygentypedef:: uint64
+.. doxygentypedef:: int8
+.. doxygentypedef:: int16
+.. doxygentypedef:: int32
+.. doxygentypedef:: int64
+
+Attributes and Type Qualifiers
+------------------------------
+
+In the case of macros for GCC's ``__attribute__``\ s, we have our own
+macros mostly to save typing, but also in hopes that they might be
+expressible using different compiler extensions, or to give them
+different interpretations when running e.g. Doxygen on libmaple.
+
+.. c:macro:: __always_inline
+
+ Macro for ``inline __attribute__((always_inline))``. This can be
+ used to defeat GCC's ``-Os`` when you Really Mean Inline.
+
+.. c:macro:: __attr_flash
+
+ Macro for a GCC ``__attribute__`` which (when using libmaple's
+ linker scripts) will cause the variable being marked to be stored
+ in Flash, rather than SRAM. It's useful for read-only variables
+ like look-up tables.
+
+.. c:macro:: __deprecated
+
+ Macro for ``__attribute__((deprecated))``. Its use causes GCC to
+ emit deprecation warnings when the deprecated functionality is
+ used. It's not used for everything that gets deprecated, so don't
+ rely on it to catch all uses of deprecated APIs.
+
+.. c:macro:: __packed
+
+ Macro for ``__attribute__((packed))``.
+
+.. c:macro:: __io
+
+ Macro for ``volatile`` which denotes that the variable whose type
+ is being qualified is IO-mapped. Its most common use is in the
+ individual members of each :ref:`register map
+ <libmaple-overview-regmaps>` struct.
+
+.. c:macro:: __weak
+
+ Macro for ``__attribute__((weak))``.
+
+.. c:macro:: __unused
+
+ Macro for ``__attribute__((unused))``. This can be used
+ (sparingly!) to silence unused function warnings when GCC is
+ mistaken.
+
+Miscellaneous
+-------------
+
+.. doxygentypedef:: voidFuncPtr
+
+.. c:macro:: offsetof(type, member)
+
+ If left undefined, this is defined to ``__builtin_ofsetof(type,
+ member)``.
+
+.. c:macro:: NULL
+
+ If left undefined, this is defined to ``0``.
diff --git a/docs/source/libmaple/api/nvic.rst b/docs/source/libmaple/api/nvic.rst
new file mode 100644
index 0000000..505e36e
--- /dev/null
+++ b/docs/source/libmaple/api/nvic.rst
@@ -0,0 +1,67 @@
+.. highlight:: c
+.. _libmaple-nvic:
+
+``<libmaple/nvic.h>``
+=====================
+
+Nested Vector Interrupt Controller (NVIC) support.
+
+The same API is used on all targets, but the available interrupts are
+target-dependent. To manage this, each target series defines an
+:ref:`nvic_irq_num <libmaple-nvic-nvic_irq_num>` enumerator for each
+available interrupt.
+
+.. contents:: Contents
+ :local:
+
+Devices
+-------
+
+None at this time.
+
+.. _libmaple-nvic-nvic_irq_num:
+
+``nvic_irq_num``
+----------------
+
+This target-dependent enum is used to identify an interrupt vector
+number. Interrupts which are common across series have the same token
+(though not necessarily the same value) for their ``nvic_irq_num``\ s.
+The available values on each supported target series are as follows.
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenenum:: stm32f1::nvic_irq_num
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenenum:: stm32f2::nvic_irq_num
+
+Functions
+---------
+
+.. doxygenfunction:: nvic_init
+.. doxygenfunction:: nvic_set_vector_table
+.. doxygenfunction:: nvic_irq_set_priority
+.. doxygenfunction:: nvic_globalirq_enable
+.. doxygenfunction:: nvic_globalirq_disable
+.. doxygenfunction:: nvic_irq_enable
+.. doxygenfunction:: nvic_irq_disable
+.. doxygenfunction:: nvic_irq_disable_all
+.. doxygenfunction:: nvic_sys_reset
+
+Register Maps
+-------------
+
+Since the NVIC is part of the ARM core, its registers and base pointer
+are common across all targes.
+
+.. doxygendefine:: NVIC_BASE
+.. doxygenstruct:: nvic_reg_map
+
+Register Bit Definitions
+------------------------
+
+None at this time.
diff --git a/docs/source/libmaple/api/pwr.rst b/docs/source/libmaple/api/pwr.rst
new file mode 100644
index 0000000..6a2cf22
--- /dev/null
+++ b/docs/source/libmaple/api/pwr.rst
@@ -0,0 +1,51 @@
+.. highlight:: c
+.. _libmaple-pwr:
+
+``pwr.h``
+=========
+
+Power control (PWR) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: pwr_reg_map
+
+Devices
+-------
+
+None.
+
+Functions
+---------
+
+.. doxygenfunction:: pwr_init
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: PWR_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register
+~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: PWR_CR_DBP
+.. doxygendefine:: PWR_CR_PVDE
+.. doxygendefine:: PWR_CR_CSBF
+.. doxygendefine:: PWR_CR_CWUF
+.. doxygendefine:: PWR_CR_PDDS
+.. doxygendefine:: PWR_CR_LPDS
+
+Control and status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: PWR_CSR_EWUP
+.. doxygendefine:: PWR_CSR_PVDO
+.. doxygendefine:: PWR_CSR_SBF
+.. doxygendefine:: PWR_CSR_WUF
diff --git a/docs/source/libmaple/api/rcc-reg-bits.txt b/docs/source/libmaple/api/rcc-reg-bits.txt
new file mode 100644
index 0000000..6b1133d
--- /dev/null
+++ b/docs/source/libmaple/api/rcc-reg-bits.txt
@@ -0,0 +1,1017 @@
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+Clock control register
+++++++++++++++++++++++
+
+::
+
+ #define RCC_CR_PLLRDY_BIT 25
+ #define RCC_CR_PLLON_BIT 24
+ #define RCC_CR_CSSON_BIT 19
+ #define RCC_CR_HSEBYP_BIT 18
+ #define RCC_CR_HSERDY_BIT 17
+ #define RCC_CR_HSEON_BIT 16
+ #define RCC_CR_HSIRDY_BIT 1
+ #define RCC_CR_HSION_BIT 0
+
+ #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
+ #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
+ #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
+ #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
+ #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
+ #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
+ #define RCC_CR_HSICAL (0xFF << 8)
+ #define RCC_CR_HSITRIM (0x1F << 3)
+ #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
+ #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
+
+Clock configuration register
+++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CFGR_USBPRE_BIT 22
+ #define RCC_CFGR_PLLXTPRE_BIT 17
+ #define RCC_CFGR_PLLSRC_BIT 16
+
+ #define RCC_CFGR_MCO (0x3 << 24)
+ #define RCC_CFGR_USBPRE (1U << RCC_CFGR_USBPRE_BIT)
+ #define RCC_CFGR_PLLMUL (0xF << 18)
+ #define RCC_CFGR_PLLXTPRE (1U << RCC_CFGR_PLLXTPRE_BIT)
+ #define RCC_CFGR_PLLSRC (1U << RCC_CFGR_PLLSRC_BIT)
+ #define RCC_CFGR_ADCPRE (0x3 << 14)
+ #define RCC_CFGR_PPRE2 (0x7 << 11)
+ #define RCC_CFGR_PPRE1 (0x7 << 8)
+ #define RCC_CFGR_HPRE (0xF << 4)
+ #define RCC_CFGR_SWS (0x3 << 2)
+ #define RCC_CFGR_SWS_PLL (0x2 << 2)
+ #define RCC_CFGR_SWS_HSE (0x1 << 2)
+ #define RCC_CFGR_SW 0x3
+ #define RCC_CFGR_SW_PLL 0x2
+ #define RCC_CFGR_SW_HSE 0x1
+
+Clock interrupt register
+++++++++++++++++++++++++
+
+::
+
+ #define RCC_CIR_CSSC_BIT 23
+ #define RCC_CIR_PLLRDYC_BIT 20
+ #define RCC_CIR_HSERDYC_BIT 19
+ #define RCC_CIR_HSIRDYC_BIT 18
+ #define RCC_CIR_LSERDYC_BIT 17
+ #define RCC_CIR_LSIRDYC_BIT 16
+ #define RCC_CIR_PLLRDYIE_BIT 12
+ #define RCC_CIR_HSERDYIE_BIT 11
+ #define RCC_CIR_HSIRDYIE_BIT 10
+ #define RCC_CIR_LSERDYIE_BIT 9
+ #define RCC_CIR_LSIRDYIE_BIT 8
+ #define RCC_CIR_CSSF_BIT 7
+ #define RCC_CIR_PLLRDYF_BIT 4
+ #define RCC_CIR_HSERDYF_BIT 3
+ #define RCC_CIR_HSIRDYF_BIT 2
+ #define RCC_CIR_LSERDYF_BIT 1
+ #define RCC_CIR_LSIRDYF_BIT 0
+
+ #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
+ #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
+ #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
+ #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
+ #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
+ #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
+ #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
+ #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
+ #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
+ #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
+ #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
+ #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
+ #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
+ #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
+ #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
+ #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
+ #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
+
+Peripheral reset registers
+++++++++++++++++++++++++++
+
+::
+
+ #define RCC_APB2RSTR_TIM11RST_BIT 21
+ #define RCC_APB2RSTR_TIM10RST_BIT 20
+ #define RCC_APB2RSTR_TIM9RST_BIT 19
+ #define RCC_APB2RSTR_ADC3RST_BIT 15
+ #define RCC_APB2RSTR_USART1RST_BIT 14
+ #define RCC_APB2RSTR_TIM8RST_BIT 13
+ #define RCC_APB2RSTR_SPI1RST_BIT 12
+ #define RCC_APB2RSTR_TIM1RST_BIT 11
+ #define RCC_APB2RSTR_ADC2RST_BIT 10
+ #define RCC_APB2RSTR_ADC1RST_BIT 9
+ #define RCC_APB2RSTR_IOPGRST_BIT 8
+ #define RCC_APB2RSTR_IOPFRST_BIT 7
+ #define RCC_APB2RSTR_IOPERST_BIT 6
+ #define RCC_APB2RSTR_IOPDRST_BIT 5
+ #define RCC_APB2RSTR_IOPCRST_BIT 4
+ #define RCC_APB2RSTR_IOPBRST_BIT 3
+ #define RCC_APB2RSTR_IOPARST_BIT 2
+ #define RCC_APB2RSTR_AFIORST_BIT 0
+
+ #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
+ #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
+ #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
+ #define RCC_APB2RSTR_ADC3RST (1U << RCC_APB2RSTR_ADC3RST_BIT)
+ #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
+ #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
+ #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
+ #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
+ #define RCC_APB2RSTR_ADC2RST (1U << RCC_APB2RSTR_ADC2RST_BIT)
+ #define RCC_APB2RSTR_ADC1RST (1U << RCC_APB2RSTR_ADC1RST_BIT)
+ #define RCC_APB2RSTR_IOPGRST (1U << RCC_APB2RSTR_IOPGRST_BIT)
+ #define RCC_APB2RSTR_IOPFRST (1U << RCC_APB2RSTR_IOPFRST_BIT)
+ #define RCC_APB2RSTR_IOPERST (1U << RCC_APB2RSTR_IOPERST_BIT)
+ #define RCC_APB2RSTR_IOPDRST (1U << RCC_APB2RSTR_IOPDRST_BIT)
+ #define RCC_APB2RSTR_IOPCRST (1U << RCC_APB2RSTR_IOPCRST_BIT)
+ #define RCC_APB2RSTR_IOPBRST (1U << RCC_APB2RSTR_IOPBRST_BIT)
+ #define RCC_APB2RSTR_IOPARST (1U << RCC_APB2RSTR_IOPARST_BIT)
+ #define RCC_APB2RSTR_AFIORST (1U << RCC_APB2RSTR_AFIORST_BIT)
+
+ #define RCC_APB1RSTR_DACRST_BIT 29
+ #define RCC_APB1RSTR_PWRRST_BIT 28
+ #define RCC_APB1RSTR_BKPRST_BIT 27
+ #define RCC_APB1RSTR_CANRST_BIT 25
+ #define RCC_APB1RSTR_USBRST_BIT 23
+ #define RCC_APB1RSTR_I2C2RST_BIT 22
+ #define RCC_APB1RSTR_I2C1RST_BIT 21
+ #define RCC_APB1RSTR_UART5RST_BIT 20
+ #define RCC_APB1RSTR_UART4RST_BIT 19
+ #define RCC_APB1RSTR_USART3RST_BIT 18
+ #define RCC_APB1RSTR_USART2RST_BIT 17
+ #define RCC_APB1RSTR_SPI3RST_BIT 15
+ #define RCC_APB1RSTR_SPI2RST_BIT 14
+ #define RCC_APB1RSTR_WWDRST_BIT 11
+ #define RCC_APB1RSTR_TIM14RST_BIT 8
+ #define RCC_APB1RSTR_TIM13RST_BIT 7
+ #define RCC_APB1RSTR_TIM12RST_BIT 6
+ #define RCC_APB1RSTR_TIM7RST_BIT 5
+ #define RCC_APB1RSTR_TIM6RST_BIT 4
+ #define RCC_APB1RSTR_TIM5RST_BIT 3
+ #define RCC_APB1RSTR_TIM4RST_BIT 2
+ #define RCC_APB1RSTR_TIM3RST_BIT 1
+ #define RCC_APB1RSTR_TIM2RST_BIT 0
+
+ #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
+ #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
+ #define RCC_APB1RSTR_BKPRST (1U << RCC_APB1RSTR_BKPRST_BIT)
+ #define RCC_APB1RSTR_CANRST (1U << RCC_APB1RSTR_CANRST_BIT)
+ #define RCC_APB1RSTR_USBRST (1U << RCC_APB1RSTR_USBRST_BIT)
+ #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
+ #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
+ #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
+ #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
+ #define RCC_APB1RSTR_USART3RST (1U << RCC_APB1RSTR_USART3RST_BIT)
+ #define RCC_APB1RSTR_USART2RST (1U << RCC_APB1RSTR_USART2RST_BIT)
+ #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
+ #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
+ #define RCC_APB1RSTR_WWDRST (1U << RCC_APB1RSTR_WWDRST_BIT)
+ #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
+ #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
+ #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
+ #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
+ #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
+ #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
+ #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
+ #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
+ #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
+
+Peripheral clock enable registers
++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_AHBENR_SDIOEN_BIT 10
+ #define RCC_AHBENR_FSMCEN_BIT 8
+ #define RCC_AHBENR_CRCEN_BIT 7
+ #define RCC_AHBENR_FLITFEN_BIT 4
+ #define RCC_AHBENR_SRAMEN_BIT 2
+ #define RCC_AHBENR_DMA2EN_BIT 1
+ #define RCC_AHBENR_DMA1EN_BIT 0
+
+ #define RCC_AHBENR_SDIOEN (1U << RCC_AHBENR_SDIOEN_BIT)
+ #define RCC_AHBENR_FSMCEN (1U << RCC_AHBENR_FSMCEN_BIT)
+ #define RCC_AHBENR_CRCEN (1U << RCC_AHBENR_CRCEN_BIT)
+ #define RCC_AHBENR_FLITFEN (1U << RCC_AHBENR_FLITFEN_BIT)
+ #define RCC_AHBENR_SRAMEN (1U << RCC_AHBENR_SRAMEN_BIT)
+ #define RCC_AHBENR_DMA2EN (1U << RCC_AHBENR_DMA2EN_BIT)
+ #define RCC_AHBENR_DMA1EN (1U << RCC_AHBENR_DMA1EN_BIT)
+
+ #define RCC_APB2ENR_TIM11EN_BIT 21
+ #define RCC_APB2ENR_TIM10EN_BIT 20
+ #define RCC_APB2ENR_TIM9EN_BIT 19
+ #define RCC_APB2ENR_ADC3EN_BIT 15
+ #define RCC_APB2ENR_USART1EN_BIT 14
+ #define RCC_APB2ENR_TIM8EN_BIT 13
+ #define RCC_APB2ENR_SPI1EN_BIT 12
+ #define RCC_APB2ENR_TIM1EN_BIT 11
+ #define RCC_APB2ENR_ADC2EN_BIT 10
+ #define RCC_APB2ENR_ADC1EN_BIT 9
+ #define RCC_APB2ENR_IOPGEN_BIT 8
+ #define RCC_APB2ENR_IOPFEN_BIT 7
+ #define RCC_APB2ENR_IOPEEN_BIT 6
+ #define RCC_APB2ENR_IOPDEN_BIT 5
+ #define RCC_APB2ENR_IOPCEN_BIT 4
+ #define RCC_APB2ENR_IOPBEN_BIT 3
+ #define RCC_APB2ENR_IOPAEN_BIT 2
+ #define RCC_APB2ENR_AFIOEN_BIT 0
+
+ #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
+ #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
+ #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
+ #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
+ #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
+ #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
+ #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
+ #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
+ #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
+ #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
+ #define RCC_APB2ENR_IOPGEN (1U << RCC_APB2ENR_IOPGEN_BIT)
+ #define RCC_APB2ENR_IOPFEN (1U << RCC_APB2ENR_IOPFEN_BIT)
+ #define RCC_APB2ENR_IOPEEN (1U << RCC_APB2ENR_IOPEEN_BIT)
+ #define RCC_APB2ENR_IOPDEN (1U << RCC_APB2ENR_IOPDEN_BIT)
+ #define RCC_APB2ENR_IOPCEN (1U << RCC_APB2ENR_IOPCEN_BIT)
+ #define RCC_APB2ENR_IOPBEN (1U << RCC_APB2ENR_IOPBEN_BIT)
+ #define RCC_APB2ENR_IOPAEN (1U << RCC_APB2ENR_IOPAEN_BIT)
+ #define RCC_APB2ENR_AFIOEN (1U << RCC_APB2ENR_AFIOEN_BIT)
+
+ #define RCC_APB1ENR_DACEN_BIT 29
+ #define RCC_APB1ENR_PWREN_BIT 28
+ #define RCC_APB1ENR_BKPEN_BIT 27
+ #define RCC_APB1ENR_CANEN_BIT 25
+ #define RCC_APB1ENR_USBEN_BIT 23
+ #define RCC_APB1ENR_I2C2EN_BIT 22
+ #define RCC_APB1ENR_I2C1EN_BIT 21
+ #define RCC_APB1ENR_UART5EN_BIT 20
+ #define RCC_APB1ENR_UART4EN_BIT 19
+ #define RCC_APB1ENR_USART3EN_BIT 18
+ #define RCC_APB1ENR_USART2EN_BIT 17
+ #define RCC_APB1ENR_SPI3EN_BIT 15
+ #define RCC_APB1ENR_SPI2EN_BIT 14
+ #define RCC_APB1ENR_WWDEN_BIT 11
+ #define RCC_APB1ENR_TIM14EN_BIT 8
+ #define RCC_APB1ENR_TIM13EN_BIT 7
+ #define RCC_APB1ENR_TIM12EN_BIT 6
+ #define RCC_APB1ENR_TIM7EN_BIT 5
+ #define RCC_APB1ENR_TIM6EN_BIT 4
+ #define RCC_APB1ENR_TIM5EN_BIT 3
+ #define RCC_APB1ENR_TIM4EN_BIT 2
+ #define RCC_APB1ENR_TIM3EN_BIT 1
+ #define RCC_APB1ENR_TIM2EN_BIT 0
+
+ #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
+ #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
+ #define RCC_APB1ENR_BKPEN (1U << RCC_APB1ENR_BKPEN_BIT)
+ #define RCC_APB1ENR_CANEN (1U << RCC_APB1ENR_CANEN_BIT)
+ #define RCC_APB1ENR_USBEN (1U << RCC_APB1ENR_USBEN_BIT)
+ #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
+ #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
+ #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
+ #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
+ #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
+ #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
+ #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
+ #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
+ #define RCC_APB1ENR_WWDEN (1U << RCC_APB1ENR_WWDEN_BIT)
+ #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
+ #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
+ #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
+ #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
+ #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
+ #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
+ #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
+ #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
+ #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
+
+Backup domain control register
+++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_BDCR_BDRST_BIT 16
+ #define RCC_BDCR_RTCEN_BIT 15
+ #define RCC_BDCR_LSEBYP_BIT 2
+ #define RCC_BDCR_LSERDY_BIT 1
+ #define RCC_BDCR_LSEON_BIT 0
+
+ #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
+ #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTC_BIT)
+ #define RCC_BDCR_RTCSEL (0x3 << 8)
+ #define RCC_BDCR_RTCSEL_NONE (0x0 << 8)
+ #define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
+ #define RCC_BDCR_RTCSEL_HSE (0x3 << 8)
+ #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
+ #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
+ #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
+
+Control/status register
++++++++++++++++++++++++
+
+::
+
+ #define RCC_CSR_LPWRRSTF_BIT 31
+ #define RCC_CSR_WWDGRSTF_BIT 30
+ #define RCC_CSR_IWDGRSTF_BIT 29
+ #define RCC_CSR_SFTRSTF_BIT 28
+ #define RCC_CSR_PORRSTF_BIT 27
+ #define RCC_CSR_PINRSTF_BIT 26
+ #define RCC_CSR_RMVF_BIT 24
+ #define RCC_CSR_LSIRDY_BIT 1
+ #define RCC_CSR_LSION_BIT 0
+
+ #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
+ #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
+ #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
+ #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
+ #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
+ #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
+ #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
+ #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
+ #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+Clock control register
+++++++++++++++++++++++
+
+::
+
+ #define RCC_CR_PLLI2SRDY_BIT 27
+ #define RCC_CR_PLLI2SON_BIT 26
+ #define RCC_CR_PLLRDY_BIT 25
+ #define RCC_CR_PLLON_BIT 24
+ #define RCC_CR_CSSON_BIT 19
+ #define RCC_CR_HSEBYP_BIT 18
+ #define RCC_CR_HSERDY_BIT 17
+ #define RCC_CR_HSEON_BIT 16
+ #define RCC_CR_HSIRDY_BIT 1
+ #define RCC_CR_HSION_BIT 0
+
+ #define RCC_CR_PLLI2SRDY (1U << RCC_CR_PLLI2SRDY_BIT)
+ #define RCC_CR_PLLI2SON (1U << RCC_CR_PLLI2SON_BIT)
+ #define RCC_CR_PLLRDY (1U << RCC_CR_PLLRDY_BIT)
+ #define RCC_CR_PLLON (1U << RCC_CR_PLLON_BIT)
+ #define RCC_CR_CSSON (1U << RCC_CR_CSSON_BIT)
+ #define RCC_CR_HSEBYP (1U << RCC_CR_HSEBYP_BIT)
+ #define RCC_CR_HSERDY (1U << RCC_CR_HSERDY_BIT)
+ #define RCC_CR_HSEON (1U << RCC_CR_HSEON_BIT)
+ #define RCC_CR_HSICAL (0xFF << 8)
+ #define RCC_CR_HSITRIM (0x1F << 3)
+ #define RCC_CR_HSIRDY (1U << RCC_CR_HSIRDY_BIT)
+ #define RCC_CR_HSION (1U << RCC_CR_HSION_BIT)
+
+PLL configuration register
+++++++++++++++++++++++++++
+
+::
+
+ #define RCC_PLLCFGR_PLLSRC_BIT 22
+
+ #define RCC_PLLCFGR_PLLQ (0xF << 24)
+ #define RCC_PLLCFGR_PLLSRC (1U << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLSRC_HSI (0x0 << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLSRC_HSE (0x1 << RCC_PLLCFGR_PLLSRC_BIT)
+ #define RCC_PLLCFGR_PLLP (0x3 << 16)
+ #define RCC_PLLCFGR_PLLN (0x1FF << 6)
+ #define RCC_PLLCFGR_PLLM 0x1F
+
+Clock configuration register
+++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CFGR_I2SSRC_BIT 23
+
+ #define RCC_CFGR_MCO2 (0x3 << 30)
+ #define RCC_CFGR_MCO2_SYSCLK (0x0 << 30)
+ #define RCC_CFGR_MCO2_PLLI2S (0x1 << 30)
+ #define RCC_CFGR_MCO2_HSE (0x2 << 30)
+ #define RCC_CFGR_MCO2_PLL (0x3 << 30)
+
+ #define RCC_CFGR_MCO2PRE (0x7 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_1 (0x0 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_2 (0x4 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_3 (0x5 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_4 (0x6 << 27)
+ #define RCC_CFGR_MCO2PRE_DIV_5 (0x7 << 27)
+
+ #define RCC_CFGR_MCO1PRE (0x7 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_1 (0x0 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_2 (0x4 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_3 (0x5 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_4 (0x6 << 24)
+ #define RCC_CFGR_MCO1PRE_DIV_5 (0x7 << 24)
+
+ #define RCC_CFGR_I2SSRC (1U << RCC_CFGR_I2SSRC_BIT)
+ #define RCC_CFGR_I2SSRC_PLLI2S (0 << RCC_CFGR_I2SSRC_BIT)
+ #define RCC_CFGR_I2SSRC_I2S_CKIN (1 << RCC_CFGR_I2SSRC_BIT)
+
+ #define RCC_CFGR_MCO1 (0x3 << 21)
+ #define RCC_CFGR_MCO1_HSI (0x0 << 21)
+ #define RCC_CFGR_MCO1_LSE (0x1 << 21)
+ #define RCC_CFGR_MCO1_HSE (0x2 << 21)
+ #define RCC_CFGR_MCO1_PLL (0x3 << 21)
+
+ #define RCC_CFGR_RTCPRE (0x1F << 16)
+
+ /* Skipped: all the 0b0xx values meaning "not divided" */
+ #define RCC_CFGR_PPRE2 (0x7 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_2 (0x4 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_4 (0x5 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_8 (0x6 << 13)
+ #define RCC_CFGR_PPRE2_AHB_DIV_16 (0x7 << 13)
+
+ /* Skipped: all the 0b0xx values meaning "not divided" */
+ #define RCC_CFGR_PPRE1 (0x7 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_2 (0x4 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_4 (0x5 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_8 (0x6 << 10)
+ #define RCC_CFGR_PPRE1_AHB_DIV_16 (0x7 << 10)
+
+ /* Skipped: all the 0b0xxx values meaning "not divided" */
+ #define RCC_CFGR_HPRE (0xF << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_2 (0x8 << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_4 (0x9 << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_8 (0xA << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_16 (0xB << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_64 (0xC << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_128 (0xD << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_256 (0xE << 4)
+ #define RCC_CFGR_HPRE_SYSCLK_DIV_512 (0xF << 4)
+
+ #define RCC_CFGR_SWS (0x3 << 2)
+ #define RCC_CFGR_SWS_HSI (0x0 << 2)
+ #define RCC_CFGR_SWS_HSE (0x1 << 2)
+ #define RCC_CFGR_SWS_PLL (0x2 << 2)
+
+ #define RCC_CFGR_SW 0x3
+ #define RCC_CFGR_SW_HSI 0x0
+ #define RCC_CFGR_SW_HSE 0x1
+ #define RCC_CFGR_SW_PLL 0x2
+
+Clock interrupt register
+++++++++++++++++++++++++
+
+::
+
+ #define RCC_CIR_CSSC_BIT 23
+
+ #define RCC_CIR_PLLI2SRDYC_BIT 21
+ #define RCC_CIR_PLLRDYC_BIT 20
+ #define RCC_CIR_HSERDYC_BIT 19
+ #define RCC_CIR_HSIRDYC_BIT 18
+ #define RCC_CIR_LSERDYC_BIT 17
+ #define RCC_CIR_LSIRDYC_BIT 16
+
+ #define RCC_CIR_PLLI2SRDYIE_BIT 13
+ #define RCC_CIR_PLLRDYIE_BIT 12
+ #define RCC_CIR_HSERDYIE_BIT 11
+ #define RCC_CIR_HSIRDYIE_BIT 10
+ #define RCC_CIR_LSERDYIE_BIT 9
+ #define RCC_CIR_LSIRDYIE_BIT 8
+
+ #define RCC_CIR_CSSF_BIT 7
+
+ #define RCC_CIR_PLLI2SRDYF_BIT 5
+ #define RCC_CIR_PLLRDYF_BIT 4
+ #define RCC_CIR_HSERDYF_BIT 3
+ #define RCC_CIR_HSIRDYF_BIT 2
+ #define RCC_CIR_LSERDYF_BIT 1
+ #define RCC_CIR_LSIRDYF_BIT 0
+
+ #define RCC_CIR_CSSC (1U << RCC_CIR_CSSC_BIT)
+
+ #define RCC_CIR_PLLI2SRDYC (1U << RCC_CIR_PLLI2SRDYC_BIT)
+ #define RCC_CIR_PLLRDYC (1U << RCC_CIR_PLLRDYC_BIT)
+ #define RCC_CIR_HSERDYC (1U << RCC_CIR_HSERDYC_BIT)
+ #define RCC_CIR_HSIRDYC (1U << RCC_CIR_HSIRDYC_BIT)
+ #define RCC_CIR_LSERDYC (1U << RCC_CIR_LSERDYC_BIT)
+ #define RCC_CIR_LSIRDYC (1U << RCC_CIR_LSIRDYC_BIT)
+
+ #define RCC_CIR_PLLI2SRDYIE (1U << RCC_CIR_PLLI2SRDYIE_BIT)
+ #define RCC_CIR_PLLRDYIE (1U << RCC_CIR_PLLRDYIE_BIT)
+ #define RCC_CIR_HSERDYIE (1U << RCC_CIR_HSERDYIE_BIT)
+ #define RCC_CIR_HSIRDYIE (1U << RCC_CIR_HSIRDYIE_BIT)
+ #define RCC_CIR_LSERDYIE (1U << RCC_CIR_LSERDYIE_BIT)
+ #define RCC_CIR_LSIRDYIE (1U << RCC_CIR_LSIRDYIE_BIT)
+
+ #define RCC_CIR_CSSF (1U << RCC_CIR_CSSF_BIT)
+
+ #define RCC_CIR_PLLI2SRDYF (1U << RCC_CIR_PLLI2SRDYF_BIT)
+ #define RCC_CIR_PLLRDYF (1U << RCC_CIR_PLLRDYF_BIT)
+ #define RCC_CIR_HSERDYF (1U << RCC_CIR_HSERDYF_BIT)
+ #define RCC_CIR_HSIRDYF (1U << RCC_CIR_HSIRDYF_BIT)
+ #define RCC_CIR_LSERDYF (1U << RCC_CIR_LSERDYF_BIT)
+ #define RCC_CIR_LSIRDYF (1U << RCC_CIR_LSIRDYF_BIT)
+
+Peripheral reset registers
+++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1RSTR_OTGHSRST_BIT 29
+ #define RCC_AHB1RSTR_ETHMACRST_BIT 25
+ #define RCC_AHB1RSTR_DMA2RST_BIT 22
+ #define RCC_AHB1RSTR_DMA1RST_BIT 21
+ #define RCC_AHB1RSTR_CRCRST_BIT 12
+ #define RCC_AHB1RSTR_GPIOIRST_BIT 8
+ #define RCC_AHB1RSTR_GPIOHRST_BIT 7
+ #define RCC_AHB1RSTR_GPIOGRST_BIT 6
+ #define RCC_AHB1RSTR_GPIOFRST_BIT 5
+ #define RCC_AHB1RSTR_GPIOERST_BIT 4
+ #define RCC_AHB1RSTR_GPIODRST_BIT 3
+ #define RCC_AHB1RSTR_GPIOCRST_BIT 2
+ #define RCC_AHB1RSTR_GPIOBRST_BIT 1
+ #define RCC_AHB1RSTR_GPIOARST_BIT 0
+
+ #define RCC_AHB1RSTR_OTGHSRST (1U << RCC_AHB1RSTR_OTGHSRST_BIT)
+ #define RCC_AHB1RSTR_ETHMACRST (1U << RCC_AHB1RSTR_ETHMACRST_BIT)
+ #define RCC_AHB1RSTR_DMA2RST (1U << RCC_AHB1RSTR_DMA2RST_BIT)
+ #define RCC_AHB1RSTR_DMA1RST (1U << RCC_AHB1RSTR_DMA1RST_BIT)
+ #define RCC_AHB1RSTR_CRCRST (1U << RCC_AHB1RSTR_CRCRST_BIT)
+ #define RCC_AHB1RSTR_GPIOIRST (1U << RCC_AHB1RSTR_GPIOIRST_BIT)
+ #define RCC_AHB1RSTR_GPIOHRST (1U << RCC_AHB1RSTR_GPIOHRST_BIT)
+ #define RCC_AHB1RSTR_GPIOGRST (1U << RCC_AHB1RSTR_GPIOGRST_BIT)
+ #define RCC_AHB1RSTR_GPIOFRST (1U << RCC_AHB1RSTR_GPIOFRST_BIT)
+ #define RCC_AHB1RSTR_GPIOERST (1U << RCC_AHB1RSTR_GPIOERST_BIT)
+ #define RCC_AHB1RSTR_GPIODRST (1U << RCC_AHB1RSTR_GPIODRST_BIT)
+ #define RCC_AHB1RSTR_GPIOCRST (1U << RCC_AHB1RSTR_GPIOCRST_BIT)
+ #define RCC_AHB1RSTR_GPIOBRST (1U << RCC_AHB1RSTR_GPIOBRST_BIT)
+ #define RCC_AHB1RSTR_GPIOARST (1U << RCC_AHB1RSTR_GPIOARST_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2RSTR_OTGFSRST_BIT 7
+ #define RCC_AHB2RSTR_RNGRST_BIT 6
+ #define RCC_AHB2RSTR_HASHRST_BIT 5
+ #define RCC_AHB2RSTR_CRYPRST_BIT 4
+ #define RCC_AHB2RSTR_DCMIRST_BIT 0
+
+ #define RCC_AHB2RSTR_OTGFSRST (1U << RCC_AHB2RSTR_OTGFSRST_BIT)
+ #define RCC_AHB2RSTR_RNGRST (1U << RCC_AHB2RSTR_RNGRST_BIT)
+ #define RCC_AHB2RSTR_HASHRST (1U << RCC_AHB2RSTR_HASHRST_BIT)
+ #define RCC_AHB2RSTR_CRYPRST (1U << RCC_AHB2RSTR_CRYPRST_BIT)
+ #define RCC_AHB2RSTR_DCMIRST (1U << RCC_AHB2RSTR_DCMIRST_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3RSTR_FSMCRST_BIT 0
+
+ #define RCC_AHB3RSTR_FSMCRST (1U << RCC_AHB3RSTR_FSMCRST_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1RSTR_DACRST_BIT 29
+ #define RCC_APB1RSTR_PWRRST_BIT 28
+ #define RCC_APB1RSTR_CAN2RST_BIT 26
+ #define RCC_APB1RSTR_CAN1RST_BIT 25
+ #define RCC_APB1RSTR_I2C3RST_BIT 23
+ #define RCC_APB1RSTR_I2C2RST_BIT 22
+ #define RCC_APB1RSTR_I2C1RST_BIT 21
+ #define RCC_APB1RSTR_UART5RST_BIT 20
+ #define RCC_APB1RSTR_UART4RST_BIT 19
+ #define RCC_APB1RSTR_UART3RST_BIT 18
+ #define RCC_APB1RSTR_UART2RST_BIT 17
+ #define RCC_APB1RSTR_SPI3RST_BIT 15
+ #define RCC_APB1RSTR_SPI2RST_BIT 14
+ #define RCC_APB1RSTR_WWDGRST_BIT 11
+ #define RCC_APB1RSTR_TIM14RST_BIT 8
+ #define RCC_APB1RSTR_TIM13RST_BIT 7
+ #define RCC_APB1RSTR_TIM12RST_BIT 6
+ #define RCC_APB1RSTR_TIM7RST_BIT 5
+ #define RCC_APB1RSTR_TIM6RST_BIT 4
+ #define RCC_APB1RSTR_TIM5RST_BIT 3
+ #define RCC_APB1RSTR_TIM4RST_BIT 2
+ #define RCC_APB1RSTR_TIM3RST_BIT 1
+ #define RCC_APB1RSTR_TIM2RST_BIT 0
+
+ #define RCC_APB1RSTR_DACRST (1U << RCC_APB1RSTR_DACRST_BIT)
+ #define RCC_APB1RSTR_PWRRST (1U << RCC_APB1RSTR_PWRRST_BIT)
+ #define RCC_APB1RSTR_CAN2RST (1U << RCC_APB1RSTR_CAN2RST_BIT)
+ #define RCC_APB1RSTR_CAN1RST (1U << RCC_APB1RSTR_CAN1RST_BIT)
+ #define RCC_APB1RSTR_I2C3RST (1U << RCC_APB1RSTR_I2C3RST_BIT)
+ #define RCC_APB1RSTR_I2C2RST (1U << RCC_APB1RSTR_I2C2RST_BIT)
+ #define RCC_APB1RSTR_I2C1RST (1U << RCC_APB1RSTR_I2C1RST_BIT)
+ #define RCC_APB1RSTR_UART5RST (1U << RCC_APB1RSTR_UART5RST_BIT)
+ #define RCC_APB1RSTR_UART4RST (1U << RCC_APB1RSTR_UART4RST_BIT)
+ #define RCC_APB1RSTR_UART3RST (1U << RCC_APB1RSTR_UART3RST_BIT)
+ #define RCC_APB1RSTR_UART2RST (1U << RCC_APB1RSTR_UART2RST_BIT)
+ #define RCC_APB1RSTR_SPI3RST (1U << RCC_APB1RSTR_SPI3RST_BIT)
+ #define RCC_APB1RSTR_SPI2RST (1U << RCC_APB1RSTR_SPI2RST_BIT)
+ #define RCC_APB1RSTR_WWDGRST (1U << RCC_APB1RSTR_WWDGRST_BIT)
+ #define RCC_APB1RSTR_TIM14RST (1U << RCC_APB1RSTR_TIM14RST_BIT)
+ #define RCC_APB1RSTR_TIM13RST (1U << RCC_APB1RSTR_TIM13RST_BIT)
+ #define RCC_APB1RSTR_TIM12RST (1U << RCC_APB1RSTR_TIM12RST_BIT)
+ #define RCC_APB1RSTR_TIM7RST (1U << RCC_APB1RSTR_TIM7RST_BIT)
+ #define RCC_APB1RSTR_TIM6RST (1U << RCC_APB1RSTR_TIM6RST_BIT)
+ #define RCC_APB1RSTR_TIM5RST (1U << RCC_APB1RSTR_TIM5RST_BIT)
+ #define RCC_APB1RSTR_TIM4RST (1U << RCC_APB1RSTR_TIM4RST_BIT)
+ #define RCC_APB1RSTR_TIM3RST (1U << RCC_APB1RSTR_TIM3RST_BIT)
+ #define RCC_APB1RSTR_TIM2RST (1U << RCC_APB1RSTR_TIM2RST_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2RSTR_TIM11RST_BIT 18
+ #define RCC_APB2RSTR_TIM10RST_BIT 17
+ #define RCC_APB2RSTR_TIM9RST_BIT 16
+ #define RCC_APB2RSTR_SYSCFGRST_BIT 14
+ #define RCC_APB2RSTR_SPI1RST_BIT 12
+ #define RCC_APB2RSTR_SDIORST_BIT 11
+ #define RCC_APB2RSTR_ADCRST_BIT 8
+ #define RCC_APB2RSTR_USART6RST_BIT 5
+ #define RCC_APB2RSTR_USART1RST_BIT 4
+ #define RCC_APB2RSTR_TIM8RST_BIT 1
+ #define RCC_APB2RSTR_TIM1RST_BIT 0
+
+ #define RCC_APB2RSTR_TIM11RST (1U << RCC_APB2RSTR_TIM11RST_BIT)
+ #define RCC_APB2RSTR_TIM10RST (1U << RCC_APB2RSTR_TIM10RST_BIT)
+ #define RCC_APB2RSTR_TIM9RST (1U << RCC_APB2RSTR_TIM9RST_BIT)
+ #define RCC_APB2RSTR_SYSCFGRST (1U << RCC_APB2RSTR_SYSCFGRST_BIT)
+ #define RCC_APB2RSTR_SPI1RST (1U << RCC_APB2RSTR_SPI1RST_BIT)
+ #define RCC_APB2RSTR_SDIORST (1U << RCC_APB2RSTR_SDIORST_BIT)
+ #define RCC_APB2RSTR_ADCRST (1U << RCC_APB2RSTR_ADCRST_BIT)
+ #define RCC_APB2RSTR_USART6RST (1U << RCC_APB2RSTR_USART6RST_BIT)
+ #define RCC_APB2RSTR_USART1RST (1U << RCC_APB2RSTR_USART1RST_BIT)
+ #define RCC_APB2RSTR_TIM8RST (1U << RCC_APB2RSTR_TIM8RST_BIT)
+ #define RCC_APB2RSTR_TIM1RST (1U << RCC_APB2RSTR_TIM1RST_BIT)
+
+Peripheral clock enable registers
++++++++++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1ENR_OTGHSULPIEN_BIT 30
+ #define RCC_AHB1ENR_OTGHSEN_BIT 29
+ #define RCC_AHB1ENR_ETHMACPTPEN_BIT 28
+ #define RCC_AHB1ENR_ETHMACRXEN_BIT 27
+ #define RCC_AHB1ENR_ETHMACTXEN_BIT 26
+ #define RCC_AHB1ENR_ETHMACEN_BIT 25
+ #define RCC_AHB1ENR_DMA2EN_BIT 22
+ #define RCC_AHB1ENR_DMA1EN_BIT 21
+ #define RCC_AHB1ENR_BKPSRAMEN_BIT 18
+ #define RCC_AHB1ENR_CRCEN_BIT 12
+ #define RCC_AHB1ENR_GPIOIEN_BIT 8
+ #define RCC_AHB1ENR_GPIOHEN_BIT 7
+ #define RCC_AHB1ENR_GPIOGEN_BIT 6
+ #define RCC_AHB1ENR_GPIOFEN_BIT 5
+ #define RCC_AHB1ENR_GPIOEEN_BIT 4
+ #define RCC_AHB1ENR_GPIODEN_BIT 3
+ #define RCC_AHB1ENR_GPIOCEN_BIT 2
+ #define RCC_AHB1ENR_GPIOBEN_BIT 1
+ #define RCC_AHB1ENR_GPIOAEN_BIT 0
+
+ #define RCC_AHB1ENR_OTGHSULPIEN (1U << RCC_AHB1ENR_OTGHSULPIEN_BIT)
+ #define RCC_AHB1ENR_OTGHSEN (1U << RCC_AHB1ENR_OTGHSEN_BIT)
+ #define RCC_AHB1ENR_ETHMACPTPEN (1U << RCC_AHB1ENR_ETHMACPTPEN_BIT)
+ #define RCC_AHB1ENR_ETHMACRXEN (1U << RCC_AHB1ENR_ETHMACRXEN_BIT)
+ #define RCC_AHB1ENR_ETHMACTXEN (1U << RCC_AHB1ENR_ETHMACTXEN_BIT)
+ #define RCC_AHB1ENR_ETHMACEN (1U << RCC_AHB1ENR_ETHMACEN_BIT)
+ #define RCC_AHB1ENR_DMA2EN (1U << RCC_AHB1ENR_DMA2EN_BIT)
+ #define RCC_AHB1ENR_DMA1EN (1U << RCC_AHB1ENR_DMA1EN_BIT)
+ #define RCC_AHB1ENR_BKPSRAMEN (1U << RCC_AHB1ENR_BKPSRAMEN_BIT)
+ #define RCC_AHB1ENR_CRCEN (1U << RCC_AHB1ENR_CRCEN_BIT)
+ #define RCC_AHB1ENR_GPIOIEN (1U << RCC_AHB1ENR_GPIOIEN_BIT)
+ #define RCC_AHB1ENR_GPIOHEN (1U << RCC_AHB1ENR_GPIOHEN_BIT)
+ #define RCC_AHB1ENR_GPIOGEN (1U << RCC_AHB1ENR_GPIOGEN_BIT)
+ #define RCC_AHB1ENR_GPIOFEN (1U << RCC_AHB1ENR_GPIOFEN_BIT)
+ #define RCC_AHB1ENR_GPIOEEN (1U << RCC_AHB1ENR_GPIOEEN_BIT)
+ #define RCC_AHB1ENR_GPIODEN (1U << RCC_AHB1ENR_GPIODEN_BIT)
+ #define RCC_AHB1ENR_GPIOCEN (1U << RCC_AHB1ENR_GPIOCEN_BIT)
+ #define RCC_AHB1ENR_GPIOBEN (1U << RCC_AHB1ENR_GPIOBEN_BIT)
+ #define RCC_AHB1ENR_GPIOAEN (1U << RCC_AHB1ENR_GPIOAEN_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2ENR_OTGFSEN_BIT 7
+ #define RCC_AHB2ENR_RNGEN_BIT 6
+ #define RCC_AHB2ENR_HASHEN_BIT 5
+ #define RCC_AHB2ENR_CRYPEN_BIT 4
+ #define RCC_AHB2ENR_DCMIEN_BIT 0
+
+ #define RCC_AHB2ENR_OTGFSEN (1U << RCC_AHB2ENR_OTGFSEN_BIT)
+ #define RCC_AHB2ENR_RNGEN (1U << RCC_AHB2ENR_RNGEN_BIT)
+ #define RCC_AHB2ENR_HASHEN (1U << RCC_AHB2ENR_HASHEN_BIT)
+ #define RCC_AHB2ENR_CRYPEN (1U << RCC_AHB2ENR_CRYPEN_BIT)
+ #define RCC_AHB2ENR_DCMIEN (1U << RCC_AHB2ENR_DCMIEN_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3ENR_FSMCEN_BIT 0
+
+ #define RCC_AHB3ENR_FSMCEN (1U << RCC_AHB3ENR_FSMCEN_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1ENR_DACEN_BIT 29
+ #define RCC_APB1ENR_PWREN_BIT 28
+ #define RCC_APB1ENR_CAN2EN_BIT 26
+ #define RCC_APB1ENR_CAN1EN_BIT 25
+ #define RCC_APB1ENR_I2C3EN_BIT 23
+ #define RCC_APB1ENR_I2C2EN_BIT 22
+ #define RCC_APB1ENR_I2C1EN_BIT 21
+ #define RCC_APB1ENR_UART5EN_BIT 20
+ #define RCC_APB1ENR_UART4EN_BIT 19
+ #define RCC_APB1ENR_USART3EN_BIT 18
+ #define RCC_APB1ENR_USART2EN_BIT 17
+ #define RCC_APB1ENR_SPI3EN_BIT 15
+ #define RCC_APB1ENR_SPI2EN_BIT 14
+ #define RCC_APB1ENR_WWDGEN_BIT 11
+ #define RCC_APB1ENR_TIM14EN_BIT 8
+ #define RCC_APB1ENR_TIM13EN_BIT 7
+ #define RCC_APB1ENR_TIM12EN_BIT 6
+ #define RCC_APB1ENR_TIM7EN_BIT 5
+ #define RCC_APB1ENR_TIM6EN_BIT 4
+ #define RCC_APB1ENR_TIM5EN_BIT 3
+ #define RCC_APB1ENR_TIM4EN_BIT 2
+ #define RCC_APB1ENR_TIM3EN_BIT 1
+ #define RCC_APB1ENR_TIM2EN_BIT 0
+
+ #define RCC_APB1ENR_DACEN (1U << RCC_APB1ENR_DACEN_BIT)
+ #define RCC_APB1ENR_PWREN (1U << RCC_APB1ENR_PWREN_BIT)
+ #define RCC_APB1ENR_CAN2EN (1U << RCC_APB1ENR_CAN2EN_BIT)
+ #define RCC_APB1ENR_CAN1EN (1U << RCC_APB1ENR_CAN1EN_BIT)
+ #define RCC_APB1ENR_I2C3EN (1U << RCC_APB1ENR_I2C3EN_BIT)
+ #define RCC_APB1ENR_I2C2EN (1U << RCC_APB1ENR_I2C2EN_BIT)
+ #define RCC_APB1ENR_I2C1EN (1U << RCC_APB1ENR_I2C1EN_BIT)
+ #define RCC_APB1ENR_UART5EN (1U << RCC_APB1ENR_UART5EN_BIT)
+ #define RCC_APB1ENR_UART4EN (1U << RCC_APB1ENR_UART4EN_BIT)
+ #define RCC_APB1ENR_USART3EN (1U << RCC_APB1ENR_USART3EN_BIT)
+ #define RCC_APB1ENR_USART2EN (1U << RCC_APB1ENR_USART2EN_BIT)
+ #define RCC_APB1ENR_SPI3EN (1U << RCC_APB1ENR_SPI3EN_BIT)
+ #define RCC_APB1ENR_SPI2EN (1U << RCC_APB1ENR_SPI2EN_BIT)
+ #define RCC_APB1ENR_WWDGEN (1U << RCC_APB1ENR_WWDGEN_BIT)
+ #define RCC_APB1ENR_TIM14EN (1U << RCC_APB1ENR_TIM14EN_BIT)
+ #define RCC_APB1ENR_TIM13EN (1U << RCC_APB1ENR_TIM13EN_BIT)
+ #define RCC_APB1ENR_TIM12EN (1U << RCC_APB1ENR_TIM12EN_BIT)
+ #define RCC_APB1ENR_TIM7EN (1U << RCC_APB1ENR_TIM7EN_BIT)
+ #define RCC_APB1ENR_TIM6EN (1U << RCC_APB1ENR_TIM6EN_BIT)
+ #define RCC_APB1ENR_TIM5EN (1U << RCC_APB1ENR_TIM5EN_BIT)
+ #define RCC_APB1ENR_TIM4EN (1U << RCC_APB1ENR_TIM4EN_BIT)
+ #define RCC_APB1ENR_TIM3EN (1U << RCC_APB1ENR_TIM3EN_BIT)
+ #define RCC_APB1ENR_TIM2EN (1U << RCC_APB1ENR_TIM2EN_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2ENR_TIM11EN_BIT 18
+ #define RCC_APB2ENR_TIM10EN_BIT 17
+ #define RCC_APB2ENR_TIM9EN_BIT 16
+ #define RCC_APB2ENR_SYSCFGEN_BIT 14
+ #define RCC_APB2ENR_SPI1EN_BIT 12
+ #define RCC_APB2ENR_SDIOEN_BIT 11
+ #define RCC_APB2ENR_ADC3EN_BIT 10
+ #define RCC_APB2ENR_ADC2EN_BIT 9
+ #define RCC_APB2ENR_ADC1EN_BIT 8
+ #define RCC_APB2ENR_USART6EN_BIT 5
+ #define RCC_APB2ENR_USART1EN_BIT 4
+ #define RCC_APB2ENR_TIM8EN_BIT 1
+ #define RCC_APB2ENR_TIM1EN_BIT 0
+
+ #define RCC_APB2ENR_TIM11EN (1U << RCC_APB2ENR_TIM11EN_BIT)
+ #define RCC_APB2ENR_TIM10EN (1U << RCC_APB2ENR_TIM10EN_BIT)
+ #define RCC_APB2ENR_TIM9EN (1U << RCC_APB2ENR_TIM9EN_BIT)
+ #define RCC_APB2ENR_SYSCFGEN (1U << RCC_APB2ENR_SYSCFGEN_BIT)
+ #define RCC_APB2ENR_SPI1EN (1U << RCC_APB2ENR_SPI1EN_BIT)
+ #define RCC_APB2ENR_SDIOEN (1U << RCC_APB2ENR_SDIOEN_BIT)
+ #define RCC_APB2ENR_ADC3EN (1U << RCC_APB2ENR_ADC3EN_BIT)
+ #define RCC_APB2ENR_ADC2EN (1U << RCC_APB2ENR_ADC2EN_BIT)
+ #define RCC_APB2ENR_ADC1EN (1U << RCC_APB2ENR_ADC1EN_BIT)
+ #define RCC_APB2ENR_USART6EN (1U << RCC_APB2ENR_USART6EN_BIT)
+ #define RCC_APB2ENR_USART1EN (1U << RCC_APB2ENR_USART1EN_BIT)
+ #define RCC_APB2ENR_TIM8EN (1U << RCC_APB2ENR_TIM8EN_BIT)
+ #define RCC_APB2ENR_TIM1EN (1U << RCC_APB2ENR_TIM1EN_BIT)
+
+Peripheral clock enable in low power mode registers
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ /* AHB1 */
+
+ #define RCC_AHB1LPENR_OTGHSULPILPEN_BIT 30
+ #define RCC_AHB1LPENR_OTGHSLPEN_BIT 29
+ #define RCC_AHB1LPENR_ETHMACPTPLPEN_BIT 28
+ #define RCC_AHB1LPENR_ETHMACRXLPEN_BIT 27
+ #define RCC_AHB1LPENR_ETHMACTXLPEN_BIT 26
+ #define RCC_AHB1LPENR_ETHMACLPEN_BIT 25
+ #define RCC_AHB1LPENR_DMA2LPEN_BIT 22
+ #define RCC_AHB1LPENR_DMA1LPEN_BIT 21
+ #define RCC_AHB1LPENR_BKPSRAMLPEN_BIT 18
+ #define RCC_AHB1LPENR_SRAM2LPEN_BIT 17
+ #define RCC_AHB1LPENR_SRAM1LPEN_BIT 16
+ #define RCC_AHB1LPENR_FLITFLPEN_BIT 15
+ #define RCC_AHB1LPENR_CRCLPEN_BIT 12
+ #define RCC_AHB1LPENR_GPIOILPEN_BIT 8
+ #define RCC_AHB1LPENR_GPIOGLPEN_BIT 6
+ #define RCC_AHB1LPENR_GPIOFLPEN_BIT 5
+ #define RCC_AHB1LPENR_GPIOELPEN_BIT 4
+ #define RCC_AHB1LPENR_GPIODLPEN_BIT 3
+ #define RCC_AHB1LPENR_GPIOCLPEN_BIT 2
+ #define RCC_AHB1LPENR_GPIOBLPEN_BIT 1
+ #define RCC_AHB1LPENR_GPIOALPEN_BIT 0
+
+ #define RCC_AHB1LPENR_OTGHSULPILPEN (1U << RCC_AHB1LPENR_OTGHSULPILPEN_BIT)
+ #define RCC_AHB1LPENR_OTGHSLPEN (1U << RCC_AHB1LPENR_OTGHSLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACPTPLPEN (1U << RCC_AHB1LPENR_ETHMACPTPLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACRXLPEN (1U << RCC_AHB1LPENR_ETHMACRXLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACTXLPEN (1U << RCC_AHB1LPENR_ETHMACTXLPEN_BIT)
+ #define RCC_AHB1LPENR_ETHMACLPEN (1U << RCC_AHB1LPENR_ETHMACLPEN_BIT)
+ #define RCC_AHB1LPENR_DMA2LPEN (1U << RCC_AHB1LPENR_DMA2LPEN_BIT)
+ #define RCC_AHB1LPENR_DMA1LPEN (1U << RCC_AHB1LPENR_DMA1LPEN_BIT)
+ #define RCC_AHB1LPENR_BKPSRAMLPEN (1U << RCC_AHB1LPENR_BKPSRAMLPEN_BIT)
+ #define RCC_AHB1LPENR_SRAM2LPEN (1U << RCC_AHB1LPENR_SRAM2LPEN_BIT)
+ #define RCC_AHB1LPENR_SRAM1LPEN (1U << RCC_AHB1LPENR_SRAM1LPEN_BIT)
+ #define RCC_AHB1LPENR_FLITFLPEN (1U << RCC_AHB1LPENR_FLITFLPEN_BIT)
+ #define RCC_AHB1LPENR_CRCLPEN (1U << RCC_AHB1LPENR_CRCLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOILPEN (1U << RCC_AHB1LPENR_GPIOILPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOGLPEN (1U << RCC_AHB1LPENR_GPIOGLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOFLPEN (1U << RCC_AHB1LPENR_GPIOFLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOELPEN (1U << RCC_AHB1LPENR_GPIOELPEN_BIT)
+ #define RCC_AHB1LPENR_GPIODLPEN (1U << RCC_AHB1LPENR_GPIODLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOCLPEN (1U << RCC_AHB1LPENR_GPIOCLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOBLPEN (1U << RCC_AHB1LPENR_GPIOBLPEN_BIT)
+ #define RCC_AHB1LPENR_GPIOALPEN (1U << RCC_AHB1LPENR_GPIOALPEN_BIT)
+
+ /* AHB2 */
+
+ #define RCC_AHB2LPENR_OTGFSLPEN_BIT 7
+ #define RCC_AHB2LPENR_RNGLPEN_BIT 6
+ #define RCC_AHB2LPENR_HASHLPEN_BIT 5
+ #define RCC_AHB2LPENR_CRYPLPEN_BIT 4
+ #define RCC_AHB2LPENR_DCMILPEN_BIT 0
+
+ #define RCC_AHB2LPENR_OTGFSLPEN (1U << RCC_AHB2LPENR_OTGFSLPEN_BIT)
+ #define RCC_AHB2LPENR_RNGLPEN (1U << RCC_AHB2LPENR_RNGLPEN_BIT)
+ #define RCC_AHB2LPENR_HASHLPEN (1U << RCC_AHB2LPENR_HASHLPEN_BIT)
+ #define RCC_AHB2LPENR_CRYPLPEN (1U << RCC_AHB2LPENR_CRYPLPEN_BIT)
+ #define RCC_AHB2LPENR_DCMILPEN (1U << RCC_AHB2LPENR_DCMILPEN_BIT)
+
+ /* AHB3 */
+
+ #define RCC_AHB3LPENR_FSMCLPEN_BIT 0
+
+ #define RCC_AHB3LPENR_FSMCLPEN (1U << RCC_AHB3LPENR_FSMCLPEN_BIT)
+
+ /* APB1 */
+
+ #define RCC_APB1LPENR_DACLPEN_BIT 29
+ #define RCC_APB1LPENR_PWRLPEN_BIT 28
+ #define RCC_APB1LPENR_CAN2LPEN_BIT 26
+ #define RCC_APB1LPENR_CAN1LPEN_BIT 25
+ #define RCC_APB1LPENR_I2C3LPEN_BIT 23
+ #define RCC_APB1LPENR_I2C2LPEN_BIT 22
+ #define RCC_APB1LPENR_I2C1LPEN_BIT 21
+ #define RCC_APB1LPENR_UART5LPEN_BIT 20
+ #define RCC_APB1LPENR_UART4LPEN_BIT 19
+ #define RCC_APB1LPENR_USART3LPEN_BIT 18
+ #define RCC_APB1LPENR_USART2LPEN_BIT 17
+ #define RCC_APB1LPENR_SPI3LPEN_BIT 15
+ #define RCC_APB1LPENR_SPI2LPEN_BIT 14
+ #define RCC_APB1LPENR_WWDGLPEN_BIT 11
+ #define RCC_APB1LPENR_TIM14LPEN_BIT 8
+ #define RCC_APB1LPENR_TIM13LPEN_BIT 7
+ #define RCC_APB1LPENR_TIM12LPEN_BIT 6
+ #define RCC_APB1LPENR_TIM7LPEN_BIT 5
+ #define RCC_APB1LPENR_TIM6LPEN_BIT 4
+ #define RCC_APB1LPENR_TIM5LPEN_BIT 3
+ #define RCC_APB1LPENR_TIM4LPEN_BIT 2
+ #define RCC_APB1LPENR_TIM3LPEN_BIT 1
+ #define RCC_APB1LPENR_TIM2LPEN_BIT 0
+
+ #define RCC_APB1LPENR_DACLPEN (1U << RCC_APB1LPENR_DACLPEN_BIT)
+ #define RCC_APB1LPENR_PWRLPEN (1U << RCC_APB1LPENR_PWRLPEN_BIT)
+ #define RCC_APB1LPENR_CAN2LPEN (1U << RCC_APB1LPENR_CAN2LPEN_BIT)
+ #define RCC_APB1LPENR_CAN1LPEN (1U << RCC_APB1LPENR_CAN1LPEN_BIT)
+ #define RCC_APB1LPENR_I2C3LPEN (1U << RCC_APB1LPENR_I2C3LPEN_BIT)
+ #define RCC_APB1LPENR_I2C2LPEN (1U << RCC_APB1LPENR_I2C2LPEN_BIT)
+ #define RCC_APB1LPENR_I2C1LPEN (1U << RCC_APB1LPENR_I2C1LPEN_BIT)
+ #define RCC_APB1LPENR_UART5LPEN (1U << RCC_APB1LPENR_UART5LPEN_BIT)
+ #define RCC_APB1LPENR_UART4LPEN (1U << RCC_APB1LPENR_UART4LPEN_BIT)
+ #define RCC_APB1LPENR_USART3LPEN (1U << RCC_APB1LPENR_USART3LPEN_BIT)
+ #define RCC_APB1LPENR_USART2LPEN (1U << RCC_APB1LPENR_USART2LPEN_BIT)
+ #define RCC_APB1LPENR_SPI3LPEN (1U << RCC_APB1LPENR_SPI3LPEN_BIT)
+ #define RCC_APB1LPENR_SPI2LPEN (1U << RCC_APB1LPENR_SPI2LPEN_BIT)
+ #define RCC_APB1LPENR_WWDGLPEN (1U << RCC_APB1LPENR_WWDGLPEN_BIT)
+ #define RCC_APB1LPENR_TIM14LPEN (1U << RCC_APB1LPENR_TIM14LPEN_BIT)
+ #define RCC_APB1LPENR_TIM13LPEN (1U << RCC_APB1LPENR_TIM13LPEN_BIT)
+ #define RCC_APB1LPENR_TIM12LPEN (1U << RCC_APB1LPENR_TIM12LPEN_BIT)
+ #define RCC_APB1LPENR_TIM7LPEN (1U << RCC_APB1LPENR_TIM7LPEN_BIT)
+ #define RCC_APB1LPENR_TIM6LPEN (1U << RCC_APB1LPENR_TIM6LPEN_BIT)
+ #define RCC_APB1LPENR_TIM5LPEN (1U << RCC_APB1LPENR_TIM5LPEN_BIT)
+ #define RCC_APB1LPENR_TIM4LPEN (1U << RCC_APB1LPENR_TIM4LPEN_BIT)
+ #define RCC_APB1LPENR_TIM3LPEN (1U << RCC_APB1LPENR_TIM3LPEN_BIT)
+ #define RCC_APB1LPENR_TIM2LPEN (1U << RCC_APB1LPENR_TIM2LPEN_BIT)
+
+ /* APB2 */
+
+ #define RCC_APB2LPENR_TIM11LPEN_BIT 18
+ #define RCC_APB2LPENR_TIM10LPEN_BIT 17
+ #define RCC_APB2LPENR_TIM9LPEN_BIT 16
+ #define RCC_APB2LPENR_SYSCFGLPEN_BIT 14
+ #define RCC_APB2LPENR_SPI1LPEN_BIT 12
+ #define RCC_APB2LPENR_SDIOLPEN_BIT 11
+ #define RCC_APB2LPENR_ADC3LPEN_BIT 10
+ #define RCC_APB2LPENR_ADC2LPEN_BIT 9
+ #define RCC_APB2LPENR_ADC1LPEN_BIT 8
+ #define RCC_APB2LPENR_USART6LPEN_BIT 5
+ #define RCC_APB2LPENR_USART1LPEN_BIT 4
+ #define RCC_APB2LPENR_TIM8LPEN_BIT 1
+ #define RCC_APB2LPENR_TIM1LPEN_BIT 0
+
+ #define RCC_APB2LPENR_TIM11LPEN (1U << RCC_APB2LPENR_TIM11LPEN_BIT)
+ #define RCC_APB2LPENR_TIM10LPEN (1U << RCC_APB2LPENR_TIM10LPEN_BIT)
+ #define RCC_APB2LPENR_TIM9LPEN (1U << RCC_APB2LPENR_TIM9LPEN_BIT)
+ #define RCC_APB2LPENR_SYSCFGLPEN (1U << RCC_APB2LPENR_SYSCFGLPEN_BIT)
+ #define RCC_APB2LPENR_SPI1LPEN (1U << RCC_APB2LPENR_SPI1LPEN_BIT)
+ #define RCC_APB2LPENR_SDIOLPEN (1U << RCC_APB2LPENR_SDIOLPEN_BIT)
+ #define RCC_APB2LPENR_ADC3LPEN (1U << RCC_APB2LPENR_ADC3LPEN_BIT)
+ #define RCC_APB2LPENR_ADC2LPEN (1U << RCC_APB2LPENR_ADC2LPEN_BIT)
+ #define RCC_APB2LPENR_ADC1LPEN (1U << RCC_APB2LPENR_ADC1LPEN_BIT)
+ #define RCC_APB2LPENR_USART6LPEN (1U << RCC_APB2LPENR_USART6LPEN_BIT)
+ #define RCC_APB2LPENR_USART1LPEN (1U << RCC_APB2LPENR_USART1LPEN_BIT)
+ #define RCC_APB2LPENR_TIM8LPEN (1U << RCC_APB2LPENR_TIM8LPEN_BIT)
+ #define RCC_APB2LPENR_TIM1LPEN (1U << RCC_APB2LPENR_TIM1LPEN_BIT)
+
+Backup domain control register
+++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_BDCR_BDRST_BIT 16
+ #define RCC_BDCR_RTCEN_BIT 15
+ #define RCC_BDCR_LSEBYP_BIT 2
+ #define RCC_BDCR_LSERDY_BIT 1
+ #define RCC_BDCR_LSEON_BIT 0
+
+ #define RCC_BDCR_BDRST (1U << RCC_BDCR_BDRST_BIT)
+ #define RCC_BDCR_RTCEN (1U << RCC_BDCR_RTCEN_BIT)
+ #define RCC_BDCR_RTCSEL (0x3 << 8)
+ #define RCC_BDCR_RTCSEL_NOCLOCK (0x0 << 8)
+ #define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
+ #define RCC_BDCR_RTCSEL_LSI (0x2 << 8)
+ #define RCC_BDCR_RTCSEL_HSE_DIV (0x3 << 8)
+ #define RCC_BDCR_LSEBYP (1U << RCC_BDCR_LSEBYP_BIT)
+ #define RCC_BDCR_LSERDY (1U << RCC_BDCR_LSERDY_BIT)
+ #define RCC_BDCR_LSEON (1U << RCC_BDCR_LSEON_BIT)
+
+Clock control and status register
++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_CSR_LPWRRSTF_BIT 31
+ #define RCC_CSR_WWDGRSTF_BIT 30
+ #define RCC_CSR_IWDGRSTF_BIT 29
+ #define RCC_CSR_SFTRSTF_BIT 28
+ #define RCC_CSR_PORRSTF_BIT 27
+ #define RCC_CSR_PINRSTF_BIT 26
+ #define RCC_CSR_BORRSTF_BIT 25
+ #define RCC_CSR_RMVF_BIT 24
+ #define RCC_CSR_LSIRDY_BIT 1
+ #define RCC_CSR_LSION_BIT 0
+
+ #define RCC_CSR_LPWRRSTF (1U << RCC_CSR_LPWRRSTF_BIT)
+ #define RCC_CSR_WWDGRSTF (1U << RCC_CSR_WWDGRSTF_BIT)
+ #define RCC_CSR_IWDGRSTF (1U << RCC_CSR_IWDGRSTF_BIT)
+ #define RCC_CSR_SFTRSTF (1U << RCC_CSR_SFTRSTF_BIT)
+ #define RCC_CSR_PORRSTF (1U << RCC_CSR_PORRSTF_BIT)
+ #define RCC_CSR_PINRSTF (1U << RCC_CSR_PINRSTF_BIT)
+ #define RCC_CSR_BORRSTF (1U << RCC_CSR_BORRSTF_BIT)
+ #define RCC_CSR_RMVF (1U << RCC_CSR_RMVF_BIT)
+ #define RCC_CSR_LSIRDY (1U << RCC_CSR_LSIRDY_BIT)
+ #define RCC_CSR_LSION (1U << RCC_CSR_LSION_BIT)
+
+Spread spectrum clock generation register
++++++++++++++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_SSCGR_SSCGEN_BIT 31
+ #define RCC_SSCGR_SPREADSEL_BIT 30
+
+ #define RCC_SSCGR_SSCGEN (1U << RCC_SSCGR_SSCGEN_BIT)
+ #define RCC_SSCGR_SPREADSEL (1U << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_SPREADSEL_CENTER (0x0 << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_SPREADSEL_DOWN (0x1 << RCC_SSCGR_SPREADSEL_BIT)
+ #define RCC_SSCGR_INCSTEP (0xFFF << 16)
+ #define RCC_SSCGR_MODPER 0xFFFF
+
+PLLI2S configuration register
++++++++++++++++++++++++++++++
+
+::
+
+ #define RCC_PLLI2SCFGR_PLLI2SR (0x7 << 28)
+ #define RCC_PLLI2SCFGR_PLLI2SN (0x1FF << 6)
+
diff --git a/docs/source/libmaple/api/rcc.rst b/docs/source/libmaple/api/rcc.rst
new file mode 100644
index 0000000..ce58ec8
--- /dev/null
+++ b/docs/source/libmaple/api/rcc.rst
@@ -0,0 +1,360 @@
+.. highlight:: c
+.. _libmaple-rcc:
+
+``<libmaple/rcc.h>``
+====================
+
+Reset and Clock Control (RCC) support.
+
+The RCC is responsible for managing the MCU's various clocks. This
+includes the core clock SYSCLK, which determines the CPU clock
+frequency, as well as the clock lines that drive peripherals.
+
+Because of this, the available RCC functionality varies by target.
+There are a :ref:`variety of abstractions <libmaple-rcc-core-types>`
+in place to make managing this more convenient.
+
+.. contents:: Contents
+ :local:
+ :depth: 2
+
+.. _libmaple-rcc-core-types:
+
+Core Types
+----------
+
+The core abstractions in place are
+:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`,
+:ref:`rcc_clk <libmaple-rcc-rcc_clk>`,
+:ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`,
+:ref:`rcc_clk_domain <libmaple-rcc-rcc_clk_domain>`, and
+:ref:`rcc_prescaler <libmaple-rcc-rcc_prescaler>`.
+
+.. _libmaple-rcc-rcc_clk_id:
+
+Peripheral Identifiers: ``rcc_clk_id``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``rcc_clk_id`` is an enum used to identify peripherals. The RCC
+back-ends use them to look up a peripheral's bus and clock line, but
+they are also generally useful as unique identifiers for each
+peripheral. You can manage peripherals using their ``rcc_clk_id``\ s
+with :ref:`these functions <libmaple-rcc-clk-id-funcs>`.
+
+Peripherals which are common across targets have the same token
+(though not necessarily the same value) for their ``rcc_clk_id``
+across different targets. For example, the ``rcc_clk_id`` for the ADC1
+peripheral is always ``RCC_ADC1`` regardless of the target.
+Additionally, as explained in :ref:`libmaple-overview-devices`, each
+peripheral device type struct contains the ``rcc_clk_id`` for that
+peripheral in a ``clk_id`` field.
+
+The available ``rcc_clk_id``\ s on each supported target series are as
+follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk_id
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk_id
+
+.. _libmaple-rcc-rcc_sysclk_src:
+
+System Clock (SYSCLK) Sources: ``rcc_sysclk_src``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SYSCLK is the core system clock. It determines the CPU clock rate, and
+it's the base clock which is used to drive (most of) the peripherals
+on the STM32. ``rcc_sysclk_src`` is an enum for the possible SYSCLK
+sources. Switch the SYSCLK source with :ref:`rcc_switch_sysclk()
+<libmaple-rcc-rcc_switch_sysclk>`.
+
+.. doxygenenum:: rcc_sysclk_src
+
+As a special case, you can configure the PLL with a call to
+:ref:`rcc_configure_pll() <libmaple-rcc-rcc_configure_pll>`.
+
+.. _libmaple-rcc-rcc_clk:
+
+System and Secondary Clock Sources: ``rcc_clk``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``rcc_clk`` type gives available system and secondary clock
+sources (e.g. HSI, HSE, LSE). As with :ref:`rcc_clk_id
+<libmaple-rcc-rcc_clk_id>`, clock sources which are common across
+targets have the same token, but not necessarily the same value, for
+their ``rcc_clk`` on each target. A variety of :ref:`clock management
+functions <libmaple-rcc-clk-funcs>` are available.
+
+Note that the inclusion of secondary clock sources, like LSI and LSE,
+makes ``rcc_clk`` different from the SYSCLK sources, which are managed
+using :ref:`rcc_sysclk_src <libmaple-rcc-rcc_sysclk_src>`.
+
+The available ``rcc_clk``\ s for each supported target series are as
+follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk
+
+.. _libmaple-rcc-rcc_clk_domain:
+
+Clock Domains: ``rcc_clk_domain``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These specify the available clock domains. For example, each AHB and
+APB is a clock domain.
+
+This type mostly exists to enable asking devices what bus they're on,
+which, given knowledge of your system's clock configuration, can be
+useful when making decisions about prescalers, etc.
+
+Given an :ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`, you can get the
+peripheral's clock domain with :ref:`rcc_dev_clk()
+<libmaple-rcc-rcc_dev_clk>`. Clock domains that are common across
+series have the same token (but not necessarily the same value) for
+their corresponding ``rcc_clk_domain``.
+
+The available ``rcc_clk_domain``\ s for each supported target series
+are as follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_clk_domain
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_clk_domain
+
+.. _libmaple-rcc-rcc_prescaler:
+
+Prescalers: ``rcc_prescaler`` and Friends
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Available prescalers are managed via the ``rcc_prescaler`` type, the
+``rcc_set_prescaler()`` function, and a variety of related prescaler
+divider types. See :ref:`libmaple-rcc-prescalers` for more
+information and usage notes.
+
+Functions
+---------
+
+.. _libmaple-rcc-sysclk-funcs:
+.. _libmaple-rcc-rcc_switch_sysclk:
+
+SYSCLK Management
+~~~~~~~~~~~~~~~~~
+
+Change the SYSCLK source with ``rcc_switch_sysclk()``.
+
+.. doxygenfunction:: rcc_switch_sysclk
+
+.. _libmaple-rcc-rcc_configure_pll:
+
+PLL Configuration
+~~~~~~~~~~~~~~~~~
+
+You can configure the PLL with ``rcc_configure_pll()``. This takes an
+``rcc_pll_cfg`` struct as its argument. Though the definition of
+``rcc_pll_cfg`` is common across series, its contents are entirely
+target-dependent.
+
+.. doxygenstruct:: rcc_pll_cfg
+.. _rcc-rcc_configure_pll:
+.. doxygenfunction:: rcc_configure_pll
+
+The fields in an ``rcc_pll_cfg`` on each target are as follows.
+
+rcc_pll_cfg on STM32F1 Targets
+++++++++++++++++++++++++++++++
+
+The ``pllsrc`` field is chosen from the following.
+
+.. doxygenenum:: stm32f1::rcc_pllsrc
+
+.. FIXME [0.0.13] We've got plans to redo this; make sure you watch
+.. libmaple for changes here.
+
+The ``data`` field must point to a ``struct stm32f1_rcc_pll_data``.
+This just contains an ``rcc_pll_multiplier``.
+
+.. doxygenenum:: stm32f1::rcc_pll_multiplier
+
+.. doxygenstruct:: stm32f1::stm32f1_rcc_pll_data
+
+rcc_pll_cfg on STM32F2 Targets
+++++++++++++++++++++++++++++++
+
+The ``pllsrc`` field is chosen from the following.
+
+.. doxygenenum:: stm32f2::rcc_pllsrc
+
+The ``data`` field must point to a ``struct stm32f2_rcc_pll_data``.
+
+.. doxygenstruct:: stm32f2::stm32f2_rcc_pll_data
+
+.. _libmaple-rcc-clk-funcs:
+
+System and Secondary Clock Management
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These functions are useful for managing clocks via their :ref:`rcc_clk
+<libmaple-rcc-rcc_clk>`.
+
+.. doxygenfunction:: rcc_turn_on_clk
+.. doxygenfunction:: rcc_turn_off_clk
+.. doxygenfunction:: rcc_is_clk_on
+.. doxygenfunction:: rcc_is_clk_ready
+
+.. _libmaple-rcc-clk-id-funcs:
+
+Peripheral Management
+~~~~~~~~~~~~~~~~~~~~~
+
+These functions are useful for managing peripherals via their
+:ref:`rcc_clk_id <libmaple-rcc-rcc_clk_id>`.
+
+.. _libmaple-rcc-rcc_clk_enable:
+.. doxygenfunction:: rcc_clk_enable
+.. doxygenfunction:: rcc_reset_dev
+.. _libmaple-rcc-rcc_dev_clk:
+.. doxygenfunction:: rcc_dev_clk
+
+.. _libmaple-rcc-prescalers:
+
+Prescaler Management
+~~~~~~~~~~~~~~~~~~~~
+
+All clock prescalers managed by RCC can be controlled with a single
+function, ``rcc_set_prescaler()``.
+
+.. doxygenfunction:: rcc_set_prescaler
+
+The arguments to ``rcc_set_prescaler()`` are target-dependent, but
+follow a common pattern:
+
+- The first argument is the prescaler to set, so there's one for each
+ peripheral clock domain, etc. These have names like
+ ``RCC_PRESCALER_FOO``, e.g. ``RCC_PRESCALER_APB1``. Choose the
+ prescaler from the ``rcc_prescaler``\ s on your target (see below).
+
+- The second argument is the actual clock divider to use; it's chosen
+ based on the first argument. The dividers for ``RCC_PRESCALER_FOO``
+ are given by the type ``rcc_foo_divider``, and have values like
+ ``RCC_FOO_xxx_DIV_y``. This means that the foo clock will be the
+ ``xxx`` clock divided by ``y``.
+
+For example, calling ``rcc_set_prescaler(RCC_PRESCALER_APB1,
+RCC_APB1_HCLK_DIV_1)`` would set the APB1 clock to HCLK divided by 1.
+
+Prescalers which are common across targets have the same token, though
+not necessarily the same value, for their ``rcc_prescaler`` (for
+example, ``RCC_PRESCALER_APB1`` is available on both STM32F1 and
+STM32F2 targets). The available prescalers and dividers on each
+supported target series are as follows.
+
+STM32F1 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f1::rcc_prescaler
+.. doxygenenum:: stm32f1::rcc_adc_divider
+.. doxygenenum:: stm32f1::rcc_apb1_divider
+.. doxygenenum:: stm32f1::rcc_apb2_divider
+.. doxygenenum:: stm32f1::rcc_ahb_divider
+
+STM32F2 Targets
++++++++++++++++
+
+.. doxygenenum:: stm32f2::rcc_prescaler
+.. doxygenenum:: stm32f2::rcc_mco2_divider
+.. doxygenenum:: stm32f2::rcc_mco1_divider
+.. doxygenenum:: stm32f2::rcc_rtc_divider
+.. doxygenenum:: stm32f2::rcc_apb2_divider
+.. doxygenenum:: stm32f2::rcc_apb1_divider
+.. doxygenenum:: stm32f2::rcc_ahb_divider
+
+Register Maps
+-------------
+
+These vary by target. The base pointer is always ``RCC_BASE``.
+
+.. doxygendefine:: RCC_BASE
+
+STM32F1 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f1::rcc_reg_map
+
+STM32F2 Targets
+~~~~~~~~~~~~~~~
+
+.. doxygenstruct:: stm32f2::rcc_reg_map
+
+Register Bit Definitions
+------------------------
+
+These are given as source code. Available register bit definitions
+vary by target.
+
+.. We need this include to avoid crashing Emacs's ReST parser. Yuck.
+
+.. include:: rcc-reg-bits.txt
+
+Deprecated Functionality
+------------------------
+
+.. _rcc-rcc_clk_init:
+.. doxygenfunction:: stm32f1::rcc_clk_init
+
+To replace a call to ``rcc_clk_init()`` in order to set SYSCLK to PLL
+driven by an external oscillator, you can use something like this,
+which is portable except for the initialization of ``your_pll_cfg``::
+
+ /* You need to make this point to something valid for your target; see
+ * the documentation for rcc_configure_pll() for more details. */
+ extern rcc_pll_cfg *your_pll_cfg;
+
+ void pll_reconfigure() {
+ /* Turn on HSI using rcc_turn_on_clk() and wait for it to
+ * become ready by busy-waiting on rcc_is_clk_ready().
+ *
+ * Switch to HSI to ensure we're not using the PLL while we
+ * reconfigure it. */
+ rcc_turn_on_clk(RCC_CLK_HSI);
+ while (!rcc_is_clk_ready(RCC_CLK_HSI))
+ ;
+ rcc_switch_sysclk(RCC_CLKSRC_HSI);
+
+ /* Turn off HSE and the PLL, or we can't reconfigure it. */
+ rcc_turn_off_clk(RCC_CLK_PLL);
+ rcc_turn_off_clk(RCC_CLK_HSE);
+
+ /* Reconfigure the PLL. You can also perform any other
+ * prescaler management here. */
+ rcc_configure_pll(your_pll_cfg);
+
+ /* Turn on RCC_CLK_HSE. */
+ rcc_turn_on_clk(RCC_CLK_HSE);
+ while (!rcc_is_clk_ready(RCC_CLK_HSE))
+ ;
+
+ /* Turn on RCC_CLK_PLL. */
+ rcc_turn_on_clk(RCC_CLK_PLL);
+ while (!rcc_is_clk_ready(RCC_CLK_PLL))
+ ;
+
+ /* Finally, switch to the PLL. */
+ rcc_switch_sysclk(RCC_CLKSRC_PLL);
+ }
diff --git a/docs/source/libmaple/api/ring_buffer.rst b/docs/source/libmaple/api/ring_buffer.rst
new file mode 100644
index 0000000..ef082dd
--- /dev/null
+++ b/docs/source/libmaple/api/ring_buffer.rst
@@ -0,0 +1,27 @@
+.. highlight:: c
+.. _libmaple-ring_buffer:
+
+``<libmaple/ring_buffer.h>``
+============================
+
+Simple circular byte buffer. This implementation is not thread-safe.
+In particular, none of these functions is guaranteed to be re-entrant.
+
+Ring Buffer Type
+----------------
+
+.. doxygenstruct:: ring_buffer
+
+Ring Buffer Operations
+----------------------
+
+.. doxygenfunction:: rb_init
+.. doxygenfunction:: rb_full_count
+.. doxygenfunction:: rb_is_full
+.. doxygenfunction:: rb_is_empty
+.. doxygenfunction:: rb_insert
+.. doxygenfunction:: rb_remove
+.. doxygenfunction:: rb_safe_remove
+.. doxygenfunction:: rb_safe_insert
+.. doxygenfunction:: rb_push_insert
+.. doxygenfunction:: rb_reset
diff --git a/docs/source/libmaple/api/scb.rst b/docs/source/libmaple/api/scb.rst
new file mode 100644
index 0000000..96d464f
--- /dev/null
+++ b/docs/source/libmaple/api/scb.rst
@@ -0,0 +1,156 @@
+.. highlight:: c
+.. _libmaple-scb:
+
+``<libmaple/scb.h>``
+====================
+
+.. TODO [0.0.13] check for any F2 modifications
+
+System Control Block (SCB) support. This is currently limited to a
+register map and bit definitions.
+
+.. warning::
+
+ At time of writing, ST PM0056 (which specifies the system control
+ block on STM32F1) appears to be buggy (some registers required or
+ specified as implementation-defined by ARM are not mentioned).
+ This file is the result of combining material from ARM and ST, and
+ is subject to change. See the source code for more details.
+
+ If you notice a problem or have any other input on this, please
+ `contact`_ us!
+
+.. contents:: Contents
+ :local:
+
+Register Maps
+-------------
+
+The SCB has the following register map. Its base pointer is ``SCB_BASE``.
+
+.. doxygenstruct:: scb_reg_map
+.. doxygendefine:: SCB_BASE
+
+Register Bit Definitions
+------------------------
+
+These are given as source code.
+
+::
+
+ /* No SCB_REG_FIELD_BIT macros as the relevant addresses are not in a
+ * bit-band region. */
+
+ /* CPUID base register (SCB_CPUID) */
+
+ #define SCB_CPUID_IMPLEMENTER (0xFF << 24)
+ #define SCB_CPUID_VARIANT (0xF << 20)
+ #define SCB_CPUID_CONSTANT (0xF << 16)
+ #define SCB_CPUID_PARTNO (0xFFF << 4)
+ #define SCB_CPUID_REVISION 0xF
+
+ /* Interrupt control state register (SCB_ICSR) */
+
+ #define SCB_ICSR_NMIPENDSET (1U << 31)
+ #define SCB_ICSR_PENDSVSET (1U << 28)
+ #define SCB_ICSR_PENDSVCLR (1U << 27)
+ #define SCB_ICSR_PENDSTSET (1U << 26)
+ #define SCB_ICSR_PENDSTCLR (1U << 25)
+ #define SCB_ICSR_ISRPENDING (1U << 22)
+ #define SCB_ICSR_VECTPENDING (0x3FF << 12)
+ #define SCB_ICSR_RETOBASE (1U << 11)
+ #define SCB_ICSR_VECTACTIVE 0xFF
+
+ /* Vector table offset register (SCB_VTOR) */
+
+ #define SCB_VTOR_TBLOFF (0x1FFFFF << 9)
+
+ /* Application interrupt and reset control register (SCB_AIRCR) */
+
+ #define SCB_AIRCR_VECTKEYSTAT (0x5FA << 16)
+ #define SCB_AIRCR_VECTKEY (0x5FA << 16)
+ #define SCB_AIRCR_ENDIANNESS (1U << 15)
+ #define SCB_AIRCR_PRIGROUP (0x3 << 8)
+ #define SCB_AIRCR_SYSRESETREQ (1U << 2)
+ #define SCB_AIRCR_VECTCLRACTIVE (1U << 1)
+ #define SCB_AIRCR_VECTRESET (1U << 0)
+
+ /* System control register (SCB_SCR) */
+
+ #define SCB_SCR_SEVONPEND (1U << 4)
+ #define SCB_SCR_SLEEPDEEP (1U << 2)
+ #define SCB_SCR_SLEEPONEXIT (1U << 1)
+
+ /* Configuration and Control Register (SCB_CCR) */
+
+ #define SCB_CCR_STKALIGN (1U << 9)
+ #define SCB_CCR_BFHFNMIGN (1U << 8)
+ #define SCB_CCR_DIV_0_TRP (1U << 4)
+ #define SCB_CCR_UNALIGN_TRP (1U << 3)
+ #define SCB_CCR_USERSETMPEND (1U << 1)
+ #define SCB_CCR_NONBASETHRDENA (1U << 0)
+
+ /* System handler priority registers (SCB_SHPRx) */
+
+ #define SCB_SHPR1_PRI6 (0xFF << 16)
+ #define SCB_SHPR1_PRI5 (0xFF << 8)
+ #define SCB_SHPR1_PRI4 0xFF
+
+ #define SCB_SHPR2_PRI11 (0xFF << 24)
+
+ #define SCB_SHPR3_PRI15 (0xFF << 24)
+ #define SCB_SHPR3_PRI14 (0xFF << 16)
+
+ /* System Handler Control and state register (SCB_SHCSR) */
+
+ #define SCB_SHCSR_USGFAULTENA (1U << 18)
+ #define SCB_SHCSR_BUSFAULTENA (1U << 17)
+ #define SCB_SHCSR_MEMFAULTENA (1U << 16)
+ #define SCB_SHCSR_SVCALLPENDED (1U << 15)
+ #define SCB_SHCSR_BUSFAULTPENDED (1U << 14)
+ #define SCB_SHCSR_MEMFAULTPENDED (1U << 13)
+ #define SCB_SHCSR_USGFAULTPENDED (1U << 12)
+ #define SCB_SHCSR_SYSTICKACT (1U << 11)
+ #define SCB_SHCSR_PENDSVACT (1U << 10)
+ #define SCB_SHCSR_MONITORACT (1U << 8)
+ #define SCB_SHCSR_SVCALLACT (1U << 7)
+ #define SCB_SHCSR_USGFAULTACT (1U << 3)
+ #define SCB_SHCSR_BUSFAULTACT (1U << 1)
+ #define SCB_SHCSR_MEMFAULTACT (1U << 0)
+
+ /* Configurable fault status register (SCB_CFSR) */
+
+ #define SCB_CFSR_DIVBYZERO (1U << 25)
+ #define SCB_CFSR_UNALIGNED (1U << 24)
+ #define SCB_CFSR_NOCP (1U << 19)
+ #define SCB_CFSR_INVPC (1U << 18)
+ #define SCB_CFSR_INVSTATE (1U << 17)
+ #define SCB_CFSR_UNDEFINSTR (1U << 16)
+ #define SCB_CFSR_BFARVALID (1U << 15)
+ #define SCB_CFSR_STKERR (1U << 12)
+ #define SCB_CFSR_UNSTKERR (1U << 11)
+ #define SCB_CFSR_IMPRECISERR (1U << 10)
+ #define SCB_CFSR_PRECISERR (1U << 9)
+ #define SCB_CFSR_IBUSERR (1U << 8)
+ #define SCB_CFSR_MMARVALID (1U << 7)
+ #define SCB_CFSR_MSTKERR (1U << 4)
+ #define SCB_CFSR_MUNSTKERR (1U << 3)
+ #define SCB_CFSR_DACCVIOL (1U << 1)
+ #define SCB_CFSR_IACCVIOL (1U << 0)
+
+ /* Hard Fault Status Register (SCB_HFSR) */
+
+ #define SCB_HFSR_DEBUG_VT (1U << 31)
+ #define SCB_CFSR_FORCED (1U << 30)
+ #define SCB_CFSR_VECTTBL (1U << 1)
+
+ /* Debug Fault Status Register */
+
+ /* Not specified by PM0056, but required by ARM. The bit definitions
+ * here are based on the names given in the ARM v7-M ARM. */
+
+ #define SCB_DFSR_EXTERNAL (1U << 4)
+ #define SCB_DFSR_VCATCH (1U << 3)
+ #define SCB_DFSR_DWTTRAP (1U << 2)
+ #define SCB_DFSR_BKPT (1U << 1)
+ #define SCB_DFSR_HALTED (1U << 0)
diff --git a/docs/source/libmaple/api/spi.rst b/docs/source/libmaple/api/spi.rst
new file mode 100644
index 0000000..e72696b
--- /dev/null
+++ b/docs/source/libmaple/api/spi.rst
@@ -0,0 +1,187 @@
+.. highlight:: c
+.. _libmaple-spi:
+
+``spi.h``
+=========
+
+Serial Peripheral Interface (SPI) support. Currently, there is no I2S
+support beyond register bit definitions.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: spi_reg_map
+.. doxygenstruct:: spi_dev
+.. doxygenenum:: spi_mode
+.. doxygenenum:: spi_baud_rate
+.. doxygenenum:: spi_cfg_flag
+.. doxygenenum:: spi_interrupt
+
+Devices
+-------
+
+.. doxygenvariable:: SPI1
+.. doxygenvariable:: SPI2
+.. doxygenvariable:: SPI3
+
+Functions
+---------
+
+.. doxygenfunction:: spi_init
+.. doxygenfunction:: spi_gpio_cfg
+.. doxygenfunction:: spi_master_enable
+.. doxygenfunction:: spi_slave_enable
+.. doxygenfunction:: spi_tx
+.. doxygenfunction:: spi_foreach
+.. doxygenfunction:: spi_peripheral_enable
+.. doxygenfunction:: spi_peripheral_disable
+.. doxygenfunction:: spi_peripheral_disable_all
+.. doxygenfunction:: spi_tx_dma_enable
+.. doxygenfunction:: spi_tx_dma_disable
+.. doxygenfunction:: spi_rx_dma_enable
+.. doxygenfunction:: spi_rx_dma_disable
+.. doxygenfunction:: spi_is_enabled
+.. doxygenfunction:: spi_irq_enable
+.. doxygenfunction:: spi_irq_disable
+.. doxygenfunction:: spi_dff
+.. doxygenfunction:: spi_is_rx_nonempty
+.. doxygenfunction:: spi_rx_reg
+.. doxygenfunction:: spi_is_tx_empty
+.. doxygenfunction:: spi_tx_reg
+.. doxygenfunction:: spi_is_busy
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: SPI1_BASE
+.. doxygendefine:: SPI2_BASE
+.. doxygendefine:: SPI3_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_CR1_BIDIMODE_BIT
+.. doxygendefine:: SPI_CR1_BIDIOE_BIT
+.. doxygendefine:: SPI_CR1_CRCEN_BIT
+.. doxygendefine:: SPI_CR1_CRCNEXT_BIT
+.. doxygendefine:: SPI_CR1_DFF_BIT
+.. doxygendefine:: SPI_CR1_RXONLY_BIT
+.. doxygendefine:: SPI_CR1_SSM_BIT
+.. doxygendefine:: SPI_CR1_SSI_BIT
+.. doxygendefine:: SPI_CR1_LSBFIRST_BIT
+.. doxygendefine:: SPI_CR1_SPE_BIT
+.. doxygendefine:: SPI_CR1_MSTR_BIT
+.. doxygendefine:: SPI_CR1_CPOL_BIT
+.. doxygendefine:: SPI_CR1_CPHA_BIT
+
+.. doxygendefine:: SPI_CR1_BIDIMODE
+.. doxygendefine:: SPI_CR1_BIDIMODE_2_LINE
+.. doxygendefine:: SPI_CR1_BIDIMODE_1_LINE
+.. doxygendefine:: SPI_CR1_BIDIOE
+.. doxygendefine:: SPI_CR1_CRCEN
+.. doxygendefine:: SPI_CR1_CRCNEXT
+.. doxygendefine:: SPI_CR1_DFF
+.. doxygendefine:: SPI_CR1_DFF_8_BIT
+.. doxygendefine:: SPI_CR1_DFF_16_BIT
+.. doxygendefine:: SPI_CR1_RXONLY
+.. doxygendefine:: SPI_CR1_SSM
+.. doxygendefine:: SPI_CR1_SSI
+.. doxygendefine:: SPI_CR1_LSBFIRST
+.. doxygendefine:: SPI_CR1_SPE
+.. doxygendefine:: SPI_CR1_BR
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_2
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_4
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_8
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_16
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_32
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_64
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_128
+.. doxygendefine:: SPI_CR1_BR_PCLK_DIV_256
+.. doxygendefine:: SPI_CR1_MSTR
+.. doxygendefine:: SPI_CR1_CPOL
+.. doxygendefine:: SPI_CR1_CPOL_LOW
+.. doxygendefine:: SPI_CR1_CPOL_HIGH
+.. doxygendefine:: SPI_CR1_CPHA
+
+Control register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_CR2_TXEIE_BIT
+.. doxygendefine:: SPI_CR2_RXNEIE_BIT
+.. doxygendefine:: SPI_CR2_ERRIE_BIT
+.. doxygendefine:: SPI_CR2_SSOE_BIT
+.. doxygendefine:: SPI_CR2_TXDMAEN_BIT
+.. doxygendefine:: SPI_CR2_RXDMAEN_BIT
+
+.. doxygendefine:: SPI_CR2_TXEIE
+.. doxygendefine:: SPI_CR2_RXNEIE
+.. doxygendefine:: SPI_CR2_ERRIE
+.. doxygendefine:: SPI_CR2_SSOE
+.. doxygendefine:: SPI_CR2_TXDMAEN
+.. doxygendefine:: SPI_CR2_RXDMAEN
+
+Status register
+~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_SR_BSY_BIT
+.. doxygendefine:: SPI_SR_OVR_BIT
+.. doxygendefine:: SPI_SR_MODF_BIT
+.. doxygendefine:: SPI_SR_CRCERR_BIT
+.. doxygendefine:: SPI_SR_UDR_BIT
+.. doxygendefine:: SPI_SR_CHSIDE_BIT
+.. doxygendefine:: SPI_SR_TXE_BIT
+.. doxygendefine:: SPI_SR_RXNE_BIT
+
+.. doxygendefine:: SPI_SR_BSY
+.. doxygendefine:: SPI_SR_OVR
+.. doxygendefine:: SPI_SR_MODF
+.. doxygendefine:: SPI_SR_CRCERR
+.. doxygendefine:: SPI_SR_UDR
+.. doxygendefine:: SPI_SR_CHSIDE
+.. doxygendefine:: SPI_SR_CHSIDE_LEFT
+.. doxygendefine:: SPI_SR_CHSIDE_RIGHT
+.. doxygendefine:: SPI_SR_TXE
+.. doxygendefine:: SPI_SR_RXNE
+
+I2S configuration register
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_BIT
+.. doxygendefine:: SPI_I2SCFGR_I2SE_BIT
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_BIT
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_BIT
+
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_SPI
+.. doxygendefine:: SPI_I2SCFGR_I2SMOD_I2S
+.. doxygendefine:: SPI_I2SCFGR_I2SE
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_TX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_SLAVE_RX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_TX
+.. doxygendefine:: SPI_I2SCFGR_I2SCFG_MASTER_RX
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_SHORT
+.. doxygendefine:: SPI_I2SCFGR_PCMSYNC_LONG
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PHILLIPS
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_MSB
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_LSB
+.. doxygendefine:: SPI_I2SCFGR_I2SSTD_PCM
+.. doxygendefine:: SPI_I2SCFGR_CKPOL
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_LOW
+.. doxygendefine:: SPI_I2SCFGR_CKPOL_HIGH
+.. doxygendefine:: SPI_I2SCFGR_DATLEN
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_16_BIT
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_24_BIT
+.. doxygendefine:: SPI_I2SCFGR_DATLEN_32_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_16_BIT
+.. doxygendefine:: SPI_I2SCFGR_CHLEN_32_BIT
diff --git a/docs/source/libmaple/api/stm32.rst b/docs/source/libmaple/api/stm32.rst
new file mode 100644
index 0000000..335bda4
--- /dev/null
+++ b/docs/source/libmaple/api/stm32.rst
@@ -0,0 +1,121 @@
+.. highlight:: c
+.. _libmaple-stm32:
+
+``<libmaple/stm32.h>``
+======================
+
+STM32 chip header. This header supplies various series-specific and
+chip-specific macros for the current build target. It's useful both
+to abstract away hardware details (e.g. through use of
+:ref:`STM32_NR_INTERRUPTS <libmaple-stm32-STM32_NR_INTERRUPTS>`) and
+to decide what to do when you want something nonportable (e.g. by
+checking :ref:`STM32_MCU_SERIES <libmaple-stm32-STM32_MCU_SERIES>`).
+
+.. contents:: Contents
+ :local:
+
+Determining the Target Series
+-----------------------------
+
+The STM32 series (e.g. STM32F1, STM32F2, etc.) of the current target
+can be inspected with ``STM32_MCU_SERIES``.
+
+.. _libmaple-stm32-STM32_MCU_SERIES:
+.. doxygendefine:: STM32_MCU_SERIES
+
+Allowed values for ``STM32_MCU_SERIES`` are the following. This set is
+expected to grow over time.
+
+.. doxygendefine:: STM32_SERIES_F1
+.. doxygendefine:: STM32_SERIES_F2
+.. doxygendefine:: STM32_SERIES_L1
+.. doxygendefine:: STM32_SERIES_F4
+
+Series-Specific Characteristics
+-------------------------------
+
+The macros in this section are only available on some STM32 series.
+
+STM32F1
+~~~~~~~
+
+.. note:: These macros are only available when the current target is
+ an STM32F1 series MCU (i.e., when :ref:`STM32_MCU_SERIES
+ <libmaple-stm32-STM32_MCU_SERIES>` is ``STM32_SERIES_F1``).
+
+The STM32F1 series is further subdivided into :ref:`lines
+<stm32-series-f1-lines>`. The line of the current target can be
+inspected with ``STM32_F1_LINE``.
+
+.. doxygendefine:: STM32_F1_LINE
+
+There are five STM32F1 lines. The corresponding values
+``STM32_F1_LINE`` can take are the following, though libmaple doesn't
+currently support all of them.
+
+.. doxygendefine:: STM32_F1_LINE_VALUE
+.. doxygendefine:: STM32_F1_LINE_ACCESS
+.. doxygendefine:: STM32_F1_LINE_USB_ACCESS
+.. doxygendefine:: STM32_F1_LINE_PERFORMANCE
+.. doxygendefine:: STM32_F1_LINE_CONNECTIVITY
+
+MCU Feature Tests
+-----------------
+
+The following defines can be used to determine if the target MCU has
+a particular feature.
+
+.. _libmaple-stm32-STM32_HAVE_FSMC:
+.. doxygendefine:: STM32_HAVE_FSMC
+.. doxygendefine:: STM32_HAVE_USB
+
+MCU Characteristics
+-------------------
+
+The following defines give salient characteristics of the target MCU.
+
+.. doxygendefine:: STM32_NR_GPIO_PORTS
+.. _libmaple-stm32-STM32_NR_INTERRUPTS:
+.. doxygendefine:: STM32_NR_INTERRUPTS
+.. doxygendefine:: STM32_SRAM_END
+
+Clock Speeds
+------------
+
+The macros in this section are related to clock rates. As such, they
+are really part of the configuration of the MCU, rather than inherent
+characteristics of the MCU itself. For instance, it's possible to
+change the PCLK1 and PCLK2 clock rates by reconfiguring the :ref:`RCC
+<libmaple-rcc>`. libmaple proper never changes any clock rates, but it
+does have APIs for doing so (such as :ref:`rcc_configure_pll()
+<libmaple-rcc-rcc_configure_pll>`). Because of this, be careful when
+using the macros in this section, as they assume that some values are
+constant which in fact may be changed.
+
+The values these macros actually take are typically the maximum values
+supported by the MCU. Since these are their actual values in practice
+(at least in LeafLabs' current use cases, which have the chips running
+as fast as possible), they're still considered useful.
+
+.. doxygendefine:: STM32_PCLK1
+.. doxygendefine:: STM32_PCLK2
+
+The following macro, ``STM32_DELAY_US_MULT``, is a libmaple
+implementation detail. It was included in this public API page in a
+previous release by mistake, and is not deprecated, but using it in
+your own code is a bad idea.
+
+.. doxygendefine:: STM32_DELAY_US_MULT
+
+Deprecated Macros
+-----------------
+
+.. warning:: The macros in this section are deprecated, and are
+ available for backwards compatibility only. Do not use
+ them in new code.
+
+.. doxygendefine:: PCLK1
+.. doxygendefine:: PCLK2
+.. doxygendefine:: NR_INTERRUPTS
+.. doxygendefine:: NR_GPIO_PORTS
+.. doxygendefine:: DELAY_US_MULT
diff --git a/docs/source/libmaple/api/systick.rst b/docs/source/libmaple/api/systick.rst
new file mode 100644
index 0000000..45b6d63
--- /dev/null
+++ b/docs/source/libmaple/api/systick.rst
@@ -0,0 +1,62 @@
+.. highlight:: c
+
+.. _libmaple-systick:
+
+``systick.h``
+=============
+
+System timer (SysTick) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: systick_reg_map
+
+Devices
+-------
+
+None.
+
+Functions
+---------
+
+.. doxygenfunction:: systick_init
+.. _libmaple-systick-enable:
+.. doxygenfunction:: systick_enable
+.. _libmaple-systick-disable:
+.. doxygenfunction:: systick_disable
+.. doxygenfunction:: systick_uptime
+.. doxygenfunction:: systick_get_count
+.. doxygenfunction:: systick_check_underflow
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: SYSTICK_BASE
+
+Register Bit Definitions
+------------------------
+
+Control and status register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SYSTICK_CSR_COUNTFLAG
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_EXTERNAL
+.. doxygendefine:: SYSTICK_CSR_CLKSOURCE_CORE
+.. doxygendefine:: SYSTICK_CSR_TICKINT
+.. doxygendefine:: SYSTICK_CSR_TICKINT_PEND
+.. doxygendefine:: SYSTICK_CSR_TICKINT_NO_PEND
+.. doxygendefine:: SYSTICK_CSR_ENABLE
+.. doxygendefine:: SYSTICK_CSR_ENABLE_MULTISHOT
+.. doxygendefine:: SYSTICK_CSR_ENABLE_DISABLED
+
+Calibration value register
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: SYSTICK_CVR_NOREF
+.. doxygendefine:: SYSTICK_CVR_SKEW
+.. doxygendefine:: SYSTICK_CVR_TENMS
diff --git a/docs/source/libmaple/api/timer.rst b/docs/source/libmaple/api/timer.rst
new file mode 100644
index 0000000..f315cb0
--- /dev/null
+++ b/docs/source/libmaple/api/timer.rst
@@ -0,0 +1,453 @@
+.. highlight:: c
+.. _libmaple-timer:
+
+``timer.h``
+===========
+
+Timer support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+The timer register map type, unlike that for most other peripherals in
+libmaple, is a union rather than a struct. This is due to the fact
+that there are advanced, general purpose, and basic timers. Thus,
+each kind of timer has a register map type, and a ``union
+timer_reg_map`` ties it all together.
+
+.. doxygenstruct:: timer_adv_reg_map
+.. doxygenstruct:: timer_gen_reg_map
+.. doxygenstruct:: timer_bas_reg_map
+.. doxygenunion:: timer_reg_map
+.. doxygenenum:: timer_type
+.. doxygenstruct:: timer_dev
+.. doxygenenum:: timer_mode
+.. doxygenenum:: timer_channel
+.. doxygenenum:: timer_interrupt_id
+.. doxygenenum:: timer_dma_base_addr
+.. doxygenenum:: timer_oc_mode
+.. doxygenenum:: timer_oc_mode_flags
+
+Devices
+-------
+
+.. doxygenvariable:: TIMER1
+.. doxygenvariable:: TIMER2
+.. doxygenvariable:: TIMER3
+.. doxygenvariable:: TIMER4
+.. doxygenvariable:: TIMER5
+.. doxygenvariable:: TIMER6
+.. doxygenvariable:: TIMER7
+.. doxygenvariable:: TIMER8
+
+Functions
+---------
+
+Enabling and Disabling
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_init
+.. doxygenfunction:: timer_init_all
+.. doxygenfunction:: timer_disable
+.. doxygenfunction:: timer_disable_all
+
+General Configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_set_mode
+.. doxygenfunction:: timer_foreach
+
+Count and Prescaler
+~~~~~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_get_count
+.. doxygenfunction:: timer_set_count
+.. doxygenfunction:: timer_pause
+.. doxygenfunction:: timer_resume
+.. doxygenfunction:: timer_generate_update
+.. doxygenfunction:: timer_get_prescaler
+.. doxygenfunction:: timer_set_prescaler
+.. doxygenfunction:: timer_get_reload
+.. doxygenfunction:: timer_set_reload
+
+Interrupts
+~~~~~~~~~~
+
+.. doxygenfunction:: timer_attach_interrupt
+.. doxygenfunction:: timer_detach_interrupt
+.. doxygenfunction:: timer_enable_irq
+.. doxygenfunction:: timer_disable_irq
+
+Capture/Compare
+~~~~~~~~~~~~~~~
+
+.. doxygenfunction:: timer_get_compare
+.. doxygenfunction:: timer_set_compare
+.. doxygenfunction:: timer_cc_enable
+.. doxygenfunction:: timer_cc_disable
+.. doxygenfunction:: timer_cc_get_pol
+.. doxygenfunction:: timer_cc_set_pol
+.. doxygenfunction:: timer_oc_set_mode
+
+DMA
+~~~
+
+.. doxygenfunction:: timer_dma_enable_trg_req
+.. doxygenfunction:: timer_dma_disable_trg_req
+.. doxygenfunction:: timer_dma_enable_req
+.. doxygenfunction:: timer_dma_get_burst_len
+.. doxygenfunction:: timer_dma_set_burst_len
+.. doxygenfunction:: timer_dma_get_base_addr
+.. doxygenfunction:: timer_dma_set_base_addr
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: TIMER1_BASE
+.. doxygendefine:: TIMER2_BASE
+.. doxygendefine:: TIMER3_BASE
+.. doxygendefine:: TIMER4_BASE
+.. doxygendefine:: TIMER5_BASE
+.. doxygendefine:: TIMER6_BASE
+.. doxygendefine:: TIMER7_BASE
+.. doxygendefine:: TIMER8_BASE
+
+Register Bit Definitions
+------------------------
+
+Control register 1 (CR1)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CR1_ARPE_BIT
+.. doxygendefine:: TIMER_CR1_DIR_BIT
+.. doxygendefine:: TIMER_CR1_OPM_BIT
+.. doxygendefine:: TIMER_CR1_URS_BIT
+.. doxygendefine:: TIMER_CR1_UDIS_BIT
+.. doxygendefine:: TIMER_CR1_CEN_BIT
+
+.. doxygendefine:: TIMER_CR1_CKD
+.. doxygendefine:: TIMER_CR1_CKD_1TCKINT
+.. doxygendefine:: TIMER_CR1_CKD_2TCKINT
+.. doxygendefine:: TIMER_CR1_CKD_4TICKINT
+.. doxygendefine:: TIMER_CR1_ARPE
+.. doxygendefine:: TIMER_CR1_CKD_CMS
+.. doxygendefine:: TIMER_CR1_CKD_CMS_EDGE
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER1
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER2
+.. doxygendefine:: TIMER_CR1_CKD_CMS_CENTER3
+.. doxygendefine:: TIMER_CR1_DIR
+.. doxygendefine:: TIMER_CR1_OPM
+.. doxygendefine:: TIMER_CR1_URS
+.. doxygendefine:: TIMER_CR1_UDIS
+.. doxygendefine:: TIMER_CR1_CEN
+
+Control register 2 (CR2)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CR2_OIS4_BIT
+.. doxygendefine:: TIMER_CR2_OIS3N_BIT
+.. doxygendefine:: TIMER_CR2_OIS3_BIT
+.. doxygendefine:: TIMER_CR2_OIS2N_BIT
+.. doxygendefine:: TIMER_CR2_OIS2_BIT
+.. doxygendefine:: TIMER_CR2_OIS1N_BIT
+.. doxygendefine:: TIMER_CR2_OIS1_BIT
+.. doxygendefine:: TIMER_CR2_TI1S_BIT
+.. doxygendefine:: TIMER_CR2_CCDS_BIT
+.. doxygendefine:: TIMER_CR2_CCUS_BIT
+.. doxygendefine:: TIMER_CR2_CCPC_BIT
+
+.. doxygendefine:: TIMER_CR2_OIS4
+.. doxygendefine:: TIMER_CR2_OIS3N
+.. doxygendefine:: TIMER_CR2_OIS3
+.. doxygendefine:: TIMER_CR2_OIS2N
+.. doxygendefine:: TIMER_CR2_OIS2
+.. doxygendefine:: TIMER_CR2_OIS1N
+.. doxygendefine:: TIMER_CR2_OIS1
+.. doxygendefine:: TIMER_CR2_TI1S
+.. doxygendefine:: TIMER_CR2_MMS
+.. doxygendefine:: TIMER_CR2_MMS_RESET
+.. doxygendefine:: TIMER_CR2_MMS_ENABLE
+.. doxygendefine:: TIMER_CR2_MMS_UPDATE
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_PULSE
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC1REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC2REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC3REF
+.. doxygendefine:: TIMER_CR2_MMS_COMPARE_OC4REF
+.. doxygendefine:: TIMER_CR2_CCDS
+.. doxygendefine:: TIMER_CR2_CCUS
+.. doxygendefine:: TIMER_CR2_CCPC
+
+Slave mode control register (SMCR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_SMCR_ETP_BIT
+.. doxygendefine:: TIMER_SMCR_ECE_BIT
+.. doxygendefine:: TIMER_SMCR_MSM_BIT
+
+.. doxygendefine:: TIMER_SMCR_ETP
+.. doxygendefine:: TIMER_SMCR_ECE
+.. doxygendefine:: TIMER_SMCR_ETPS
+.. doxygendefine:: TIMER_SMCR_ETPS_OFF
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV2
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV4
+.. doxygendefine:: TIMER_SMCR_ETPS_DIV8
+.. doxygendefine:: TIMER_SMCR_ETF
+.. doxygendefine:: TIMER_SMCR_MSM
+.. doxygendefine:: TIMER_SMCR_TS
+.. doxygendefine:: TIMER_SMCR_TS_ITR0
+.. doxygendefine:: TIMER_SMCR_TS_ITR1
+.. doxygendefine:: TIMER_SMCR_TS_ITR2
+.. doxygendefine:: TIMER_SMCR_TS_ITR3
+.. doxygendefine:: TIMER_SMCR_TS_TI1F_ED
+.. doxygendefine:: TIMER_SMCR_TS_TI1FP1
+.. doxygendefine:: TIMER_SMCR_TS_TI2FP2
+.. doxygendefine:: TIMER_SMCR_TS_ETRF
+.. doxygendefine:: TIMER_SMCR_SMS
+.. doxygendefine:: TIMER_SMCR_SMS_DISABLED
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER1
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER2
+.. doxygendefine:: TIMER_SMCR_SMS_ENCODER3
+.. doxygendefine:: TIMER_SMCR_SMS_RESET
+.. doxygendefine:: TIMER_SMCR_SMS_GATED
+.. doxygendefine:: TIMER_SMCR_SMS_TRIGGER
+.. doxygendefine:: TIMER_SMCR_SMS_EXTERNAL
+
+DMA/Interrupt enable register (DIER)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_DIER_TDE_BIT
+.. doxygendefine:: TIMER_DIER_CC4DE_BIT
+.. doxygendefine:: TIMER_DIER_CC3DE_BIT
+.. doxygendefine:: TIMER_DIER_CC2DE_BIT
+.. doxygendefine:: TIMER_DIER_CC1DE_BIT
+.. doxygendefine:: TIMER_DIER_UDE_BIT
+.. doxygendefine:: TIMER_DIER_TIE_BIT
+.. doxygendefine:: TIMER_DIER_CC4IE_BIT
+.. doxygendefine:: TIMER_DIER_CC3IE_BIT
+.. doxygendefine:: TIMER_DIER_CC2IE_BIT
+.. doxygendefine:: TIMER_DIER_CC1IE_BIT
+.. doxygendefine:: TIMER_DIER_UIE_BIT
+
+.. doxygendefine:: TIMER_DIER_TDE
+.. doxygendefine:: TIMER_DIER_CC4DE
+.. doxygendefine:: TIMER_DIER_CC3DE
+.. doxygendefine:: TIMER_DIER_CC2DE
+.. doxygendefine:: TIMER_DIER_CC1DE
+.. doxygendefine:: TIMER_DIER_UDE
+.. doxygendefine:: TIMER_DIER_TIE
+.. doxygendefine:: TIMER_DIER_CC4IE
+.. doxygendefine:: TIMER_DIER_CC3IE
+.. doxygendefine:: TIMER_DIER_CC2IE
+.. doxygendefine:: TIMER_DIER_CC1IE
+.. doxygendefine:: TIMER_DIER_UIE
+
+Status register (SR)
+~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_SR_CC4OF_BIT
+.. doxygendefine:: TIMER_SR_CC3OF_BIT
+.. doxygendefine:: TIMER_SR_CC2OF_BIT
+.. doxygendefine:: TIMER_SR_CC1OF_BIT
+.. doxygendefine:: TIMER_SR_BIF_BIT
+.. doxygendefine:: TIMER_SR_TIF_BIT
+.. doxygendefine:: TIMER_SR_COMIF_BIT
+.. doxygendefine:: TIMER_SR_CC4IF_BIT
+.. doxygendefine:: TIMER_SR_CC3IF_BIT
+.. doxygendefine:: TIMER_SR_CC2IF_BIT
+.. doxygendefine:: TIMER_SR_CC1IF_BIT
+.. doxygendefine:: TIMER_SR_UIF_BIT
+
+.. doxygendefine:: TIMER_SR_CC4OF
+.. doxygendefine:: TIMER_SR_CC3OF
+.. doxygendefine:: TIMER_SR_CC2OF
+.. doxygendefine:: TIMER_SR_CC1OF
+.. doxygendefine:: TIMER_SR_BIF
+.. doxygendefine:: TIMER_SR_TIF
+.. doxygendefine:: TIMER_SR_COMIF
+.. doxygendefine:: TIMER_SR_CC4IF
+.. doxygendefine:: TIMER_SR_CC3IF
+.. doxygendefine:: TIMER_SR_CC2IF
+.. doxygendefine:: TIMER_SR_CC1IF
+.. doxygendefine:: TIMER_SR_UIF
+
+Event generation register (EGR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_EGR_TG_BIT
+.. doxygendefine:: TIMER_EGR_CC4G_BIT
+.. doxygendefine:: TIMER_EGR_CC3G_BIT
+.. doxygendefine:: TIMER_EGR_CC2G_BIT
+.. doxygendefine:: TIMER_EGR_CC1G_BIT
+.. doxygendefine:: TIMER_EGR_UG_BIT
+
+.. doxygendefine:: TIMER_EGR_TG
+.. doxygendefine:: TIMER_EGR_CC4G
+.. doxygendefine:: TIMER_EGR_CC3G
+.. doxygendefine:: TIMER_EGR_CC2G
+.. doxygendefine:: TIMER_EGR_CC1G
+.. doxygendefine:: TIMER_EGR_UG
+
+Capture/compare mode registers, common values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR_CCS_OUTPUT
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR_CCS_INPUT_TRC
+
+Capture/compare mode register 1 (CCMR1)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR1_OC2CE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC2PE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC2FE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1CE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1PE_BIT
+.. doxygendefine:: TIMER_CCMR1_OC1FE_BIT
+
+.. doxygendefine:: TIMER_CCMR1_OC2CE
+.. doxygendefine:: TIMER_CCMR1_OC2M
+.. doxygendefine:: TIMER_CCMR1_IC2F
+.. doxygendefine:: TIMER_CCMR1_OC2PE
+.. doxygendefine:: TIMER_CCMR1_OC2FE
+.. doxygendefine:: TIMER_CCMR1_IC2PSC
+.. doxygendefine:: TIMER_CCMR1_CC2S
+.. doxygendefine:: TIMER_CCMR1_CC2S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC2S_INPUT_TRC
+.. doxygendefine:: TIMER_CCMR1_OC1CE
+.. doxygendefine:: TIMER_CCMR1_OC1M
+.. doxygendefine:: TIMER_CCMR1_IC1F
+.. doxygendefine:: TIMER_CCMR1_OC1PE
+.. doxygendefine:: TIMER_CCMR1_OC1FE
+.. doxygendefine:: TIMER_CCMR1_IC1PSC
+.. doxygendefine:: TIMER_CCMR1_CC1S
+.. doxygendefine:: TIMER_CCMR1_CC1S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC1S_INPUT_TRC
+
+Capture/compare mode register 2 (CCMR2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCMR2_OC4CE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC4PE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC4FE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3CE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3PE_BIT
+.. doxygendefine:: TIMER_CCMR2_OC3FE_BIT
+
+.. doxygendefine:: TIMER_CCMR2_OC4CE
+.. doxygendefine:: TIMER_CCMR2_OC4M
+.. doxygendefine:: TIMER_CCMR2_IC2F
+.. doxygendefine:: TIMER_CCMR2_OC4PE
+.. doxygendefine:: TIMER_CCMR2_OC4FE
+.. doxygendefine:: TIMER_CCMR2_IC2PSC
+.. doxygendefine:: TIMER_CCMR2_CC4S
+.. doxygendefine:: TIMER_CCMR1_CC4S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC4S_INPUT_TRC
+.. doxygendefine:: TIMER_CCMR2_OC3CE
+.. doxygendefine:: TIMER_CCMR2_OC3M
+.. doxygendefine:: TIMER_CCMR2_IC1F
+.. doxygendefine:: TIMER_CCMR2_OC3PE
+.. doxygendefine:: TIMER_CCMR2_OC3FE
+.. doxygendefine:: TIMER_CCMR2_IC1PSC
+.. doxygendefine:: TIMER_CCMR2_CC3S
+.. doxygendefine:: TIMER_CCMR1_CC3S_OUTPUT
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI1
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TI2
+.. doxygendefine:: TIMER_CCMR1_CC3S_INPUT_TRC
+
+Capture/compare enable register (CCER)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_CCER_CC4P_BIT
+.. doxygendefine:: TIMER_CCER_CC4E_BIT
+.. doxygendefine:: TIMER_CCER_CC3P_BIT
+.. doxygendefine:: TIMER_CCER_CC3E_BIT
+.. doxygendefine:: TIMER_CCER_CC2P_BIT
+.. doxygendefine:: TIMER_CCER_CC2E_BIT
+.. doxygendefine:: TIMER_CCER_CC1P_BIT
+.. doxygendefine:: TIMER_CCER_CC1E_BIT
+
+.. doxygendefine:: TIMER_CCER_CC4P
+.. doxygendefine:: TIMER_CCER_CC4E
+.. doxygendefine:: TIMER_CCER_CC3P
+.. doxygendefine:: TIMER_CCER_CC3E
+.. doxygendefine:: TIMER_CCER_CC2P
+.. doxygendefine:: TIMER_CCER_CC2E
+.. doxygendefine:: TIMER_CCER_CC1P
+.. doxygendefine:: TIMER_CCER_CC1E
+
+Break and dead-time register (BDTR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_BDTR_MOE_BIT
+.. doxygendefine:: TIMER_BDTR_AOE_BIT
+.. doxygendefine:: TIMER_BDTR_BKP_BIT
+.. doxygendefine:: TIMER_BDTR_BKE_BIT
+.. doxygendefine:: TIMER_BDTR_OSSR_BIT
+.. doxygendefine:: TIMER_BDTR_OSSI_BIT
+
+.. doxygendefine:: TIMER_BDTR_MOE
+.. doxygendefine:: TIMER_BDTR_AOE
+.. doxygendefine:: TIMER_BDTR_BKP
+.. doxygendefine:: TIMER_BDTR_BKE
+.. doxygendefine:: TIMER_BDTR_OSSR
+.. doxygendefine:: TIMER_BDTR_OSSI
+.. doxygendefine:: TIMER_BDTR_LOCK
+.. doxygendefine:: TIMER_BDTR_LOCK_OFF
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL1
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL2
+.. doxygendefine:: TIMER_BDTR_LOCK_LEVEL3
+.. doxygendefine:: TIMER_BDTR_DTG
+
+DMA control register (DCR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: TIMER_DCR_DBL
+.. doxygendefine:: TIMER_DCR_DBL_1BYTE
+.. doxygendefine:: TIMER_DCR_DBL_2BYTE
+.. doxygendefine:: TIMER_DCR_DBL_3BYTE
+.. doxygendefine:: TIMER_DCR_DBL_4BYTE
+.. doxygendefine:: TIMER_DCR_DBL_5BYTE
+.. doxygendefine:: TIMER_DCR_DBL_6BYTE
+.. doxygendefine:: TIMER_DCR_DBL_7BYTE
+.. doxygendefine:: TIMER_DCR_DBL_8BYTE
+.. doxygendefine:: TIMER_DCR_DBL_9BYTE
+.. doxygendefine:: TIMER_DCR_DBL_10BYTE
+.. doxygendefine:: TIMER_DCR_DBL_11BYTE
+.. doxygendefine:: TIMER_DCR_DBL_12BYTE
+.. doxygendefine:: TIMER_DCR_DBL_13BYTE
+.. doxygendefine:: TIMER_DCR_DBL_14BYTE
+.. doxygendefine:: TIMER_DCR_DBL_15BYTE
+.. doxygendefine:: TIMER_DCR_DBL_16BYTE
+.. doxygendefine:: TIMER_DCR_DBL_17BYTE
+.. doxygendefine:: TIMER_DCR_DBL_18BYTE
+.. doxygendefine:: TIMER_DCR_DBA
+.. doxygendefine:: TIMER_DCR_DBA_CR1
+.. doxygendefine:: TIMER_DCR_DBA_CR2
+.. doxygendefine:: TIMER_DCR_DBA_SMCR
+.. doxygendefine:: TIMER_DCR_DBA_DIER
+.. doxygendefine:: TIMER_DCR_DBA_SR
+.. doxygendefine:: TIMER_DCR_DBA_EGR
+.. doxygendefine:: TIMER_DCR_DBA_CCMR1
+.. doxygendefine:: TIMER_DCR_DBA_CCMR2
+.. doxygendefine:: TIMER_DCR_DBA_CCER
+.. doxygendefine:: TIMER_DCR_DBA_CNT
+.. doxygendefine:: TIMER_DCR_DBA_PSC
+.. doxygendefine:: TIMER_DCR_DBA_ARR
+.. doxygendefine:: TIMER_DCR_DBA_RCR
+.. doxygendefine:: TIMER_DCR_DBA_CCR1
+.. doxygendefine:: TIMER_DCR_DBA_CCR2
+.. doxygendefine:: TIMER_DCR_DBA_CCR3
+.. doxygendefine:: TIMER_DCR_DBA_CCR4
+.. doxygendefine:: TIMER_DCR_DBA_BDTR
+.. doxygendefine:: TIMER_DCR_DBA_DCR
+.. doxygendefine:: TIMER_DCR_DBA_DMAR
diff --git a/docs/source/libmaple/api/usart.rst b/docs/source/libmaple/api/usart.rst
new file mode 100644
index 0000000..68f2c37
--- /dev/null
+++ b/docs/source/libmaple/api/usart.rst
@@ -0,0 +1,197 @@
+.. highlight:: c
+.. _libmaple-usart:
+
+``usart.h``
+===========
+
+Universal Synchronous/Asynchronous Receiver/Transmitter (USART, or
+commonly *serial port*) support.
+
+.. contents:: Contents
+ :local:
+
+Types
+-----
+
+.. doxygenstruct:: usart_reg_map
+.. doxygenstruct:: usart_dev
+
+Devices
+-------
+
+.. doxygenvariable:: USART1
+.. doxygenvariable:: USART2
+.. doxygenvariable:: USART3
+.. doxygenvariable:: UART4
+.. doxygenvariable:: UART5
+
+Functions
+---------
+
+.. doxygenfunction:: usart_init
+.. doxygenfunction:: usart_set_baud_rate
+.. doxygenfunction:: usart_enable
+.. doxygenfunction:: usart_disable
+.. doxygenfunction:: usart_disable_all
+.. doxygenfunction:: usart_foreach
+.. doxygenfunction:: usart_rx
+.. doxygenfunction:: usart_tx
+.. doxygenfunction:: usart_putudec
+.. doxygenfunction:: usart_putc
+.. doxygenfunction:: usart_putstr
+.. doxygenfunction:: usart_getc
+.. doxygenfunction:: usart_data_available
+.. doxygenfunction:: usart_reset_rx
+
+Register Map Base Pointers
+--------------------------
+
+.. doxygendefine:: USART1_BASE
+.. doxygendefine:: USART2_BASE
+.. doxygendefine:: USART3_BASE
+.. doxygendefine:: UART4_BASE
+.. doxygendefine:: UART5_BASE
+
+Register Bit Definitions
+------------------------
+
+Status Register
+~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_SR_CTS_BIT
+.. doxygendefine:: USART_SR_LBD_BIT
+.. doxygendefine:: USART_SR_TXE_BIT
+.. doxygendefine:: USART_SR_TC_BIT
+.. doxygendefine:: USART_SR_RXNE_BIT
+.. doxygendefine:: USART_SR_IDLE_BIT
+.. doxygendefine:: USART_SR_ORE_BIT
+.. doxygendefine:: USART_SR_NE_BIT
+.. doxygendefine:: USART_SR_FE_BIT
+.. doxygendefine:: USART_SR_PE_BIT
+
+.. doxygendefine:: USART_SR_CTS
+.. doxygendefine:: USART_SR_LBD
+.. doxygendefine:: USART_SR_TXE
+.. doxygendefine:: USART_SR_TC
+.. doxygendefine:: USART_SR_RXNE
+.. doxygendefine:: USART_SR_IDLE
+.. doxygendefine:: USART_SR_ORE
+.. doxygendefine:: USART_SR_NE
+.. doxygendefine:: USART_SR_FE
+.. doxygendefine:: USART_SR_PE
+
+Data register
+~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_DR_DR
+
+Baud Rate Register
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_BRR_DIV_MANTISSA
+.. doxygendefine:: USART_BRR_DIV_FRACTION
+
+Control Register 1
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR1_UE_BIT
+.. doxygendefine:: USART_CR1_M_BIT
+.. doxygendefine:: USART_CR1_WAKE_BIT
+.. doxygendefine:: USART_CR1_PCE_BIT
+.. doxygendefine:: USART_CR1_PS_BIT
+.. doxygendefine:: USART_CR1_PEIE_BIT
+.. doxygendefine:: USART_CR1_TXEIE_BIT
+.. doxygendefine:: USART_CR1_TCIE_BIT
+.. doxygendefine:: USART_CR1_RXNEIE_BIT
+.. doxygendefine:: USART_CR1_IDLEIE_BIT
+.. doxygendefine:: USART_CR1_TE_BIT
+.. doxygendefine:: USART_CR1_RE_BIT
+.. doxygendefine:: USART_CR1_RWU_BIT
+.. doxygendefine:: USART_CR1_SBK_BIT
+
+.. doxygendefine:: USART_CR1_UE
+.. doxygendefine:: USART_CR1_M
+.. doxygendefine:: USART_CR1_WAKE
+.. doxygendefine:: USART_CR1_WAKE_IDLE
+.. doxygendefine:: USART_CR1_WAKE_ADDR
+.. doxygendefine:: USART_CR1_PCE
+.. doxygendefine:: USART_CR1_PS
+.. doxygendefine:: USART_CR1_PS_EVEN
+.. doxygendefine:: USART_CR1_PS_ODD
+.. doxygendefine:: USART_CR1_PEIE
+.. doxygendefine:: USART_CR1_TXEIE
+.. doxygendefine:: USART_CR1_TCIE
+.. doxygendefine:: USART_CR1_RXNEIE
+.. doxygendefine:: USART_CR1_IDLEIE
+.. doxygendefine:: USART_CR1_TE
+.. doxygendefine:: USART_CR1_RE
+.. doxygendefine:: USART_CR1_RWU
+.. doxygendefine:: USART_CR1_RWU_ACTIVE
+.. doxygendefine:: USART_CR1_RWU_MUTE
+.. doxygendefine:: USART_CR1_SBK
+
+Control Register 2
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR2_LINEN_BIT
+.. doxygendefine:: USART_CR2_CLKEN_BIT
+.. doxygendefine:: USART_CR2_CPOL_BIT
+.. doxygendefine:: USART_CR2_CPHA_BIT
+.. doxygendefine:: USART_CR2_LBCL_BIT
+.. doxygendefine:: USART_CR2_LBDIE_BIT
+.. doxygendefine:: USART_CR2_LBDL_BIT
+
+.. doxygendefine:: USART_CR2_LINEN
+.. doxygendefine:: USART_CR2_STOP
+.. doxygendefine:: USART_CR2_STOP_BITS_1
+.. doxygendefine:: USART_CR2_STOP_BITS_POINT_5
+.. doxygendefine:: USART_CR2_STOP_BITS_1_POINT_5
+.. doxygendefine:: USART_CR2_STOP_BITS_2
+.. doxygendefine:: USART_CR2_CLKEN
+.. doxygendefine:: USART_CR2_CPOL
+.. doxygendefine:: USART_CR2_CPOL_LOW
+.. doxygendefine:: USART_CR2_CPOL_HIGH
+.. doxygendefine:: USART_CR2_CPHA
+.. doxygendefine:: USART_CR2_CPHA_FIRST
+.. doxygendefine:: USART_CR2_CPHA_SECOND
+.. doxygendefine:: USART_CR2_LBCL
+.. doxygendefine:: USART_CR2_LBDIE
+.. doxygendefine:: USART_CR2_LBDL
+.. doxygendefine:: USART_CR2_LBDL_10_BIT
+.. doxygendefine:: USART_CR2_LBDL_11_BIT
+.. doxygendefine:: USART_CR2_ADD
+
+Control Register 3
+~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_CR3_CTSIE_BIT
+.. doxygendefine:: USART_CR3_CTSE_BIT
+.. doxygendefine:: USART_CR3_RTSE_BIT
+.. doxygendefine:: USART_CR3_DMAT_BIT
+.. doxygendefine:: USART_CR3_DMAR_BIT
+.. doxygendefine:: USART_CR3_SCEN_BIT
+.. doxygendefine:: USART_CR3_NACK_BIT
+.. doxygendefine:: USART_CR3_HDSEL_BIT
+.. doxygendefine:: USART_CR3_IRLP_BIT
+.. doxygendefine:: USART_CR3_IREN_BIT
+.. doxygendefine:: USART_CR3_EIE_BIT
+
+.. doxygendefine:: USART_CR3_CTSIE
+.. doxygendefine:: USART_CR3_CTSE
+.. doxygendefine:: USART_CR3_RTSE
+.. doxygendefine:: USART_CR3_DMAT
+.. doxygendefine:: USART_CR3_DMAR
+.. doxygendefine:: USART_CR3_SCEN
+.. doxygendefine:: USART_CR3_NACK
+.. doxygendefine:: USART_CR3_HDSEL
+.. doxygendefine:: USART_CR3_IRLP
+.. doxygendefine:: USART_CR3_IRLP_NORMAL
+.. doxygendefine:: USART_CR3_IRLP_LOW_POWER
+.. doxygendefine:: USART_CR3_IREN
+.. doxygendefine:: USART_CR3_EIE
+
+Guard Time and Prescaler Register
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygendefine:: USART_GTPR_GT
+.. doxygendefine:: USART_GTPR_PSC
diff --git a/docs/source/libmaple/api/util.rst b/docs/source/libmaple/api/util.rst
new file mode 100644
index 0000000..54377c0
--- /dev/null
+++ b/docs/source/libmaple/api/util.rst
@@ -0,0 +1,54 @@
+.. highlight:: c
+.. _libmaple-util:
+
+``<libmaple/util.h>``
+=====================
+
+.. TODO [0.2.0?] clean this up.
+
+Miscellaneous utility macros and procedures.
+
+.. contents:: Contents
+ :local:
+
+Bit Manipulation
+----------------
+
+The following macros are useful for bit manipulation.
+
+.. doxygendefine:: BIT
+.. doxygendefine:: BIT_MASK_SHIFT
+.. doxygendefine:: GET_BITS
+.. doxygendefine:: IS_POWER_OF_TWO
+
+Failure Routines
+----------------
+
+``throb()`` is called by various routines to throb a built-in
+LED. **Usually, you shouldn't call it yourself**; use something like
+``ASSERT(0)`` (or the libc ``abort()`` function) instead.
+
+.. doxygenfunction:: throb
+
+Asserts and Debug Levels
+------------------------
+
+The level of libmaple's assertion support is determined by
+``DEBUG_LEVEL``, as follows:
+
+.. doxygendefine:: DEBUG_LEVEL
+
+The current assert macros are ``ASSERT()`` and ``ASSERT_FAULT()``.
+``ASSERT()`` is checked when ``DEBUG_LEVEL >= DEBUG_ALL``.
+``ASSERT_FAULT()`` is checked whenever ``DEBUG_LEVEL >= DEBUG_FAULT``.
+
+As explained above, an assert macro is checked when the current
+``DEBUG_LEVEL`` is high enough. If the debug level is too low, the
+macro expands into a no-op that gets compiled away.
+
+If an assertion fails, execution is halted at the point of the failed
+assertion. When libmaple has been configured properly (Wirish
+performs this configuration by default), the built-in LED throbs in a
+smooth pattern to signal the failed assertion (using
+:c:func:`throb()`), and the file and line where the assert failed are
+transmitted to the user as detailed in :ref:`lang-assert`.