summaryrefslogtreecommitdiffstats
path: root/libopencm3/lib/stm32/f0
diff options
context:
space:
mode:
Diffstat (limited to 'libopencm3/lib/stm32/f0')
-rw-r--r--libopencm3/lib/stm32/f0/Makefile49
-rw-r--r--libopencm3/lib/stm32/f0/adc.c835
-rw-r--r--libopencm3/lib/stm32/f0/comparator.c64
-rw-r--r--libopencm3/lib/stm32/f0/crc.c31
-rw-r--r--libopencm3/lib/stm32/f0/crs.c32
-rw-r--r--libopencm3/lib/stm32/f0/dac.c31
-rw-r--r--libopencm3/lib/stm32/f0/dma.c31
-rw-r--r--libopencm3/lib/stm32/f0/flash.c157
-rw-r--r--libopencm3/lib/stm32/f0/gpio.c31
-rw-r--r--libopencm3/lib/stm32/f0/i2c.c32
-rw-r--r--libopencm3/lib/stm32/f0/iwdg.c31
-rw-r--r--libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld106
-rw-r--r--libopencm3/lib/stm32/f0/pwr.c38
-rw-r--r--libopencm3/lib/stm32/f0/rcc.c665
-rw-r--r--libopencm3/lib/stm32/f0/rtc.c31
-rw-r--r--libopencm3/lib/stm32/f0/spi.c31
-rw-r--r--libopencm3/lib/stm32/f0/syscfg.c31
-rw-r--r--libopencm3/lib/stm32/f0/timer.c34
-rw-r--r--libopencm3/lib/stm32/f0/usart.c429
19 files changed, 2689 insertions, 0 deletions
diff --git a/libopencm3/lib/stm32/f0/Makefile b/libopencm3/lib/stm32/f0/Makefile
new file mode 100644
index 0000000..156171c
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/Makefile
@@ -0,0 +1,49 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+LIBNAME = libopencm3_stm32f0
+SRCLIBDIR ?= ../..
+
+PREFIX ?= arm-none-eabi
+#PREFIX ?= arm-elf
+CC = $(PREFIX)-gcc
+AR = $(PREFIX)-ar
+CFLAGS = -Os -g \
+ -Wall -Wextra -Wimplicit-function-declaration \
+ -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
+ -Wundef -Wshadow \
+ -I../../../include -fno-common \
+ -mcpu=cortex-m0 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
+ -ffunction-sections -fdata-sections -MD -DSTM32F0
+
+ARFLAGS = rcs
+
+OBJS = flash.o rcc.o usart.o dma.o rtc.o comparator.o crc.o \
+ dac.o i2c.o iwdg.o pwr.o gpio.o timer.o adc.o
+
+OBJS += gpio_common_all.o gpio_common_f0234.o crc_common_all.o \
+ pwr_common_all.o iwdg_common_all.o rtc_common_l1f024.o \
+ dma_common_l1f013.o exti_common_all.o spi_common_all.o \
+ spi_common_f03.o flash_common_f01.o dac_common_all.o \
+ timer_common_all.o
+
+VPATH += ../../usb:../:../../cm3:../common
+
+include ../../Makefile.include
+
diff --git a/libopencm3/lib/stm32/f0/adc.c b/libopencm3/lib/stm32/f0/adc.c
new file mode 100644
index 0000000..7dbf84a
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/adc.c
@@ -0,0 +1,835 @@
+/** @defgroup adc_file ADC
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Analog to Digital Converters</b>
+ *
+ * based on F3 file
+ *
+ * @date 14 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/cm3/assert.h>
+#include <libopencm3/stm32/adc.h>
+
+/**@{*/
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_opmode ADC Operation mode API
+ * @ingroup adc_file
+ *
+ * @brief ADC Result API
+ *
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Continuous Conversion Mode
+ *
+ * In this mode the ADC starts a new conversion of a single channel or a channel
+ * group immediately following completion of the previous channel group
+ * conversion.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_set_continuous_conversion_mode(uint32_t adc)
+{
+ ADC_CFGR1(adc) |= ADC_CFGR1_CONT;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Single Conversion Mode
+ *
+ * In this mode the ADC performs a conversion of one channel or a channel group
+ * and stops.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_set_single_conversion_mode(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_CONT;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Discontinuous Mode for Regular Conversions
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_discontinuous_mode(uint32_t adc)
+{
+ ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable Discontinuous Mode for Regular Conversions
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_discontinuous_mode(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** ADC Set operation mode
+ *
+ * There are some operation modes, common for entire stm32 branch. In the text
+ * the braces are describing result to single trigger event. The trigger event
+ * is described by character T in the description. The ADC is configured to
+ * convert list of inputs [0, 1, 2, 3]. In Grouped modes, there is used group
+ * size of 2 conversions in the examples
+ *
+ * @li @c ADC_MODE_SEQUENTIAL: T(0) T(1) T(2) T(3)[EOSEQ] T(0) T(1) T(2) ...
+ *
+ * In this mode, after the trigger event a single channel is converted and the
+ * next channel in the list is prepared to convert on next trigger edge.
+ *
+ * @note This mode can be emulated by ADC_MODE_GROUPED with group size
+ * of 1. @par
+ *
+ * @li @c ADC_MODE_SCAN: T(0123)[EOSEQ] T(0123)[EOSEQ] T(0123)[EOSEQ]
+ *
+ * In this mode, after the trigger event, all channels will be converted once,
+ * storing results sequentially.
+ *
+ * @note The DMA must be configured properly for more than single channel to
+ * convert. @par
+ *
+ * @li @c ADC_MODE_SCAN_INFINITE: T(0123[EOSEQ]0123[EOSEQ]0123[EOSEQ]...)
+ *
+ * In this mode, after the trigger event, all channels from the list are
+ * converted. At the end of list, the conversion continues from the beginning.
+ *
+ * @note The DMA must be configured properly to operate in this mode.@par
+ *
+ * @li @c ADC_MODE_GROUPED: T(12) T(34)[EOSEQ] T(12) T(34)[EOSEQ] T(12)
+ *
+ * In this mode, after the trigger event, a specified group size of channels
+ * are converted. If the end of channel list occurs, the EOSEQ is generated
+ * and on the next trigger it wraps to the beginning.
+ *
+ * @note The DMA must be configured properly to operate on more than single
+ * channel conversion groups.@par
+ *
+ * @warning not all families supports all modes of operation of ADC.
+ *
+ * @par
+ *
+ */
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set conversion operation mode
+ *
+ * @note on SEQUENTIAL mode, the trigger event is neccesary to start conversion.
+ * @par
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] adc ::adc_opmode. ADC operation mode (@ref adc_opmode)
+ */
+
+void adc_set_operation_mode(uint32_t adc, enum adc_opmode opmode)
+{
+ switch (opmode) {
+ case ADC_MODE_SEQUENTIAL:
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_CONT;
+ ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN;
+ break;
+
+ case ADC_MODE_SCAN:
+ ADC_CFGR1(adc) &= ~(ADC_CFGR1_CONT | ADC_CFGR1_DISCEN);
+ break;
+
+ case ADC_MODE_SCAN_INFINITE:
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN;
+ ADC_CFGR1(adc) |= ADC_CFGR1_CONT;
+ break;
+ }
+}
+
+/**@}*/
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_result ADC Result API
+ * @ingroup adc_file
+ *
+ * @brief ADC Result API
+ *
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Software Triggered Conversion on Regular Channels
+ *
+ * This starts conversion on a set of defined regular channels. It is cleared
+ * by hardware once conversion starts.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_start_conversion_regular(uint32_t adc)
+{
+ /* Start conversion on regular channels. */
+ ADC_CR(adc) |= ADC_CR_ADSTART;
+
+ /* Wait until the ADC starts the conversion. */
+ while (ADC_CR(adc) & ADC_CR_ADSTART);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Read the End-of-Conversion Flag
+ *
+ * This flag is set after all channels of a regular or injected group have been
+ * converted.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @returns bool. End of conversion flag.
+ */
+
+bool adc_eoc(uint32_t adc)
+{
+ return ((ADC_ISR(adc) & ADC_ISR_EOC) != 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Read from the Regular Conversion Result Register
+ *
+ * The result read back is 12 bits, right or left aligned within the first
+ * 16 bits. For ADC1 only, the higher 16 bits will hold the result from ADC2 if
+ * an appropriate dual mode has been set @see adc_set_dual_mode.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @returns Unsigned int32 conversion result.
+ */
+
+uint32_t adc_read_regular(uint32_t adc)
+{
+ return ADC_DR(adc);
+}
+
+/**@}*/
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_trigger ADC Trigger API
+ * @ingroup adc_file
+ *
+ * @brief ADC Trigger API
+ *
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable an External Trigger for Regular Channels
+ *
+ * This enables an external trigger for set of defined regular channels, and
+ * sets the polarity of the trigger event: rising or falling edge or both. Note
+ * that if the trigger polarity is zero, triggering is disabled.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] trigger Unsigned int32. Trigger identifier
+ * @ref adc_trigger_regular
+ * @param[in] polarity Unsigned int32. Trigger polarity @ref
+ * adc_trigger_polarity_regular
+ */
+
+void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger,
+ uint32_t polarity)
+{
+ ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTSEL) | trigger;
+ ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTEN) | polarity;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable an External Trigger for Regular Channels
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_external_trigger_regular(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_EXTEN;
+}
+
+/**@}*/
+
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_interrupts ADC Interrupt configuration API
+ * @ingroup adc_file
+ *
+ * @brief ADC Interrupt configuration API
+ *
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_watchdog_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) |= ADC_IER_AWDIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable Regular End-Of-Conversion Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_watchdog_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) &= ~ADC_IER_AWDIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Read the Analog Watchdog Flag
+ *
+ * This flag is set when the converted voltage crosses the high or low
+ * thresholds.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @returns bool true, if the signal is out of defined analog range.
+ */
+
+bool adc_get_watchdog_flag(uint32_t adc)
+{
+ return ADC_ISR(adc) & ADC_ISR_AWD;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Clear Analog Watchdog Flag
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_clear_watchdog_flag(uint32_t adc)
+{
+ ADC_ISR(adc) = ADC_ISR_AWD;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable the Overrun Interrupt
+ *
+ * The overrun interrupt is generated when data is not read from a result
+ * register before the next conversion is written. If DMA is enabled, all
+ * transfers are terminated and any conversion sequence is aborted.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_overrun_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) |= ADC_IER_OVRIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable the Overrun Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_overrun_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) &= ~ADC_IER_OVRIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Read the Overrun Flag
+ *
+ * The overrun flag is set when data is not read from a result register before
+ * the next conversion is written. If DMA is enabled, all transfers are
+ * terminated and any conversion sequence is aborted.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+bool adc_get_overrun_flag(uint32_t adc)
+{
+ return ADC_ISR(adc) & ADC_ISR_OVR;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Clear Overrun Flags
+ *
+ * The overrun flag is cleared. Note that if an overrun occurs, DMA is
+ * terminated.
+ * The flag must be cleared and the DMA stream and ADC reinitialised to resume
+ * conversions (see the reference manual).
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_clear_overrun_flag(uint32_t adc)
+{
+ ADC_ISR(adc) = ADC_ISR_OVR;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Regular End-Of-Conversion Sequence Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_eoc_sequence_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) |= ADC_IER_EOSEQIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable Regular End-Of-Conversion Sequence Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_eoc_sequence_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) &= ~ADC_IER_EOSEQIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Read the Regular End-Of-Conversion Sequence Flag
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+bool adc_get_eoc_sequence_flag(uint32_t adc)
+{
+ return ADC_ISR(adc) & ADC_ISR_EOSEQ;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Regular End-Of-Conversion Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_eoc_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) |= ADC_IER_EOCIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable Regular End-Of-Conversion Interrupt
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_eoc_interrupt(uint32_t adc)
+{
+ ADC_IER(adc) &= ~ADC_IER_EOCIE;
+}
+
+/**@}*/
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_config ADC Basic configuration API
+ * @ingroup adc_file
+ *
+ * @brief ADC Basic configuration API
+ *
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Power Off
+ *
+ * Turn off the ADC to reduce power consumption to a few microamps.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_power_off(uint32_t adc)
+{
+ ADC_CR(adc) &= ~ADC_CR_ADEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Power On
+ *
+ * If the ADC is in power-down mode then it is powered up. The application
+ * needs to wait a time of about 3 microseconds for stabilization before using
+ * the ADC. If the ADC is already on this function call will have no effect.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_power_on(uint32_t adc)
+{
+ ADC_CR(adc) |= ADC_CR_ADEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set Clock Prescale
+ *
+ * The ADC clock taken from the many sources.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] prescale Unsigned int32. Prescale value (@ref adc_api_clksource)
+ */
+
+void adc_set_clk_source(uint32_t adc, uint32_t source)
+{
+ ADC_CFGR2(adc) = ((ADC_CFGR2(adc) & ~ADC_CFGR2_CKMODE) | source);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set a Regular Channel Conversion Sequence
+ *
+ * Define a sequence of channels to be converted as a regular group with a
+ * length from 1 to 18 channels. If this is called during conversion, the
+ * current conversion is reset and conversion begins again with the newly
+ * defined group.
+ *
+ * @warning This core doesn't support the random order of ADC conversions.
+ * The channel list must be ordered by channel number.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] length Unsigned int8. Number of channels in the group.
+ * @param[in] channel Unsigned int8[]. Set of channels to convert, integers
+ * 0..18.
+ */
+
+void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[])
+{
+ uint32_t reg32 = 0;
+ uint8_t i = 0;
+ bool stepup = false, stepdn = false;
+
+ if (length == 0) {
+ ADC_CHSELR(adc) = 0;
+ return;
+ }
+
+ reg32 |= (1 << channel[0]);
+
+ for (i = 1; i < length; i++) {
+ reg32 |= (1 << channel[i]);
+ stepup |= channel[i-1] < channel[i];
+ stepdn |= channel[i-1] > channel[i];
+ }
+
+ /* Check, if the channel list is in order */
+ if (stepup && stepdn) {
+ cm3_assert_not_reached();
+ }
+
+ /* Update the scan direction flag */
+ if (stepdn) {
+ ADC_CFGR1(adc) |= ADC_CFGR1_SCANDIR;
+ } else {
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_SCANDIR;
+ }
+
+ ADC_CHSELR(adc) = reg32;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set the Sample Time for All Channels
+ *
+ * The sampling time can be selected in ADC clock cycles from 1.5 to 239.5,
+ * same for all channels.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] time Unsigned int8. Sampling time selection (@ref adc_api_smptime)
+ */
+
+void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time)
+{
+ ADC_SMPR(adc) = time & ADC_SMPR_SMP;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set Resolution
+ *
+ * ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a
+ * corresponding reduction in conversion time.
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] resolution Unsigned int16. Resolution value (@ref adc_api_res)
+ */
+
+void adc_set_resolution(uint32_t adc, uint16_t resolution)
+{
+ ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_RES) | resolution;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set the Data as Left Aligned
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_set_left_aligned(uint32_t adc)
+{
+ ADC_CFGR1(adc) |= ADC_CFGR1_ALIGN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set the Data as Right Aligned
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_set_right_aligned(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_ALIGN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable DMA Transfers
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_dma(uint32_t adc)
+{
+ ADC_CFGR1(adc) |= ADC_CFGR1_DMAEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable DMA Transfers
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_disable_dma(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_DMAEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable The Temperature Sensor
+ *
+ * This enables the sensor on channel 16
+ */
+
+void adc_enable_temperature_sensor(void)
+{
+ ADC_CCR |= ADC_CCR_TSEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable The Temperature Sensor
+ *
+ * Disabling this will reduce power consumption from the temperature sensor
+ * measurement.
+ */
+
+void adc_disable_temperature_sensor(void)
+{
+ ADC_CCR &= ~ADC_CCR_TSEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable The VRef Sensor
+ *
+ * This enables the reference voltage measurements on channel 17.
+ */
+
+void adc_enable_vref_sensor(void)
+{
+ ADC_CCR |= ADC_CCR_VREFEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable The VRef Sensor
+ *
+ * Disabling this will reduce power consumption from the reference voltage
+ * measurement.
+ */
+
+void adc_disable_vref_sensor(void)
+{
+ ADC_CCR &= ~ADC_CCR_VREFEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable The VBat Sensor
+ *
+ * This enables the battery voltage measurements on channel 17.
+ */
+
+void adc_enable_vbat_sensor(void)
+{
+ ADC_CCR |= ADC_CCR_VBATEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable The VBat Sensor
+ *
+ * Disabling this will reduce power consumption from the battery voltage
+ * measurement.
+ */
+
+void adc_disable_vbat_sensor(void)
+{
+ ADC_CCR &= ~ADC_CCR_VBATEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Start the calibration procedure
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_calibrate_start(uint32_t adc)
+{
+ ADC_CR(adc) = ADC_CR_ADCAL;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Wait to finish the ADC calibration procedure
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_calibrate_wait_finish(uint32_t adc)
+{
+ while (ADC_CR(adc) & ADC_CR_ADCAL);
+}
+
+/**@}*/
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/**
+ * @defgroup adc_api_wdg ADC Analog watchdog API
+ * @ingroup adc_file
+ *
+ * @brief ADC analog watchdog API definitions.
+ *
+ * The analog watchdog allows the monitoring of an analog signal between two
+ * threshold levels. The thresholds must be preset. Analog watchdog is disabled
+ * by default.
+ *
+ * @warning Comparison is done before data alignment takes place, so the
+ * thresholds are left-aligned.
+ *
+ * Example 1: Enable watchdog checking on all channels
+ *
+ * @code
+ * // in configuration
+ * adc_enable_analog_watchdog_on_all_channels(ADC1);
+ * adc_set_watchdog_high_threshold(ADC1, 0xE00);
+ * adc_set_watchdog_low_threshold(ADC1, 0x200);
+ *
+ * // in the main application thread
+ * if (adc_get_watchdog_flag(ADC1)) {
+ * // the converted signal is out of AWD ranges
+ * adc_clear_watchdog_flag(ADC1);
+ * }
+ * @endcode
+ *
+ * Example 2: Enable watchdog checking on channel 5
+ *
+ * @code
+ * // in configuration
+ * adc_enable_analog_watchdog_on_selected_channel(ADC1,5);
+ * adc_set_watchdog_high_threshold(ADC1, 0xE00);
+ * adc_set_watchdog_low_threshold(ADC1, 0x200);
+ *
+ * // in the main application thread
+ * if (adc_get_watchdog_flag(ADC1)) {
+ * // the converted signal is out of AWD ranges
+ * adc_clear_watchdog_flag(ADC1);
+ * }
+ * @endcode
+ *@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for All Channels
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+
+void adc_enable_analog_watchdog_on_all_channels(uint32_t adc)
+{
+ ADC_CFGR1(adc) |= ADC_CFGR1_AWDEN;
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_AWDSGL;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for a Selected Channel
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] chan Unsigned int8. ADC channel number @ref adc_api_channel
+ */
+
+void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, uint8_t chan)
+{
+ ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_AWDCH) |
+ ADC_CFGR1_AWDCH_VAL(chan);
+
+ ADC_CFGR1(adc) |= ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Disable Analog Watchdog
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ */
+void adc_disable_analog_watchdog(uint32_t adc)
+{
+ ADC_CFGR1(adc) &= ~ADC_CFGR1_AWDEN;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set Analog Watchdog Upper Threshold
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] threshold Unsigned int8. Upper threshold value
+ */
+
+void adc_set_watchdog_high_threshold(uint32_t adc, uint8_t threshold)
+{
+ ADC_TR(adc) = (ADC_TR(adc) & ~ADC_TR_HT) | ADC_TR_HT_VAL(threshold);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief ADC Set Analog Watchdog Lower Threshold
+ *
+ * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
+ * @param[in] threshold Unsigned int8. Lower threshold value
+ */
+
+void adc_set_watchdog_low_threshold(uint32_t adc, uint8_t threshold)
+{
+ ADC_TR(adc) = (ADC_TR(adc) & ~ADC_TR_LT) | ADC_TR_LT_VAL(threshold);
+}
+
+/**@}*/
+
+/*---------------------------------------------------------------------------*/
+
+/**@}*/
diff --git a/libopencm3/lib/stm32/f0/comparator.c b/libopencm3/lib/stm32/f0/comparator.c
new file mode 100644
index 0000000..51bd0f2
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/comparator.c
@@ -0,0 +1,64 @@
+/** @defgroup comp_file COMP
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx COMP</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 10 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**@{*/
+
+#include <libopencm3/stm32/comparator.h>
+
+void comp_enable(uint8_t id)
+{
+ COMP_CSR(id) |= COMP_CSR_EN;
+}
+
+void comp_disable(uint8_t id)
+{
+ COMP_CSR(id) &= ~COMP_CSR_EN;
+}
+
+void comp_select_input(uint8_t id, uint32_t input)
+{
+ COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_INSEL) | input;
+}
+
+void comp_select_output(uint8_t id, uint32_t output)
+{
+ COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_OUTSEL) | output;
+}
+
+void comp_select_hyst(uint8_t id, uint32_t hyst)
+{
+ COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_HYST) | hyst;
+}
+
+void comp_select_speed(uint8_t id, uint32_t speed)
+{
+ COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_SPEED) | speed;
+}
+/**@}*/
+
diff --git a/libopencm3/lib/stm32/f0/crc.c b/libopencm3/lib/stm32/f0/crc.c
new file mode 100644
index 0000000..2519b22
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/crc.c
@@ -0,0 +1,31 @@
+/** @defgroup crc_file CRC
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx CRC</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/crc.h>
diff --git a/libopencm3/lib/stm32/f0/crs.c b/libopencm3/lib/stm32/f0/crs.c
new file mode 100644
index 0000000..db45168
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/crs.c
@@ -0,0 +1,32 @@
+/** @defgroup crs_file CRS
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Clock Recovery Subsystem</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 5 Feb 2014
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/crs.h>
+
diff --git a/libopencm3/lib/stm32/f0/dac.c b/libopencm3/lib/stm32/f0/dac.c
new file mode 100644
index 0000000..55cdd62
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/dac.c
@@ -0,0 +1,31 @@
+/** @defgroup dac_file DAC
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx DAC</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/dac.h>
diff --git a/libopencm3/lib/stm32/f0/dma.c b/libopencm3/lib/stm32/f0/dma.c
new file mode 100644
index 0000000..8f158a8
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/dma.c
@@ -0,0 +1,31 @@
+/** @defgroup dma_file DMA
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx DMA</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 10 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/dma.h>
diff --git a/libopencm3/lib/stm32/f0/flash.c b/libopencm3/lib/stm32/f0/flash.c
new file mode 100644
index 0000000..618405b
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/flash.c
@@ -0,0 +1,157 @@
+/** @defgroup flash_file FLASH
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F05x FLASH</b>
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly &copy; @endhtmlonly 2013
+ * Frantisek Burian <BuFran@seznam.cz>
+ *
+ * @date 14 January 2014
+ *
+ * For the STM32F05x, accessing FLASH memory is described in
+ * section 3 of the STM32F05x Reference Manual.
+ *
+ * FLASH memory may be used for data storage as well as code, and may be
+ * programmatically modified. Note that for firmware upload the STM32F1xx
+ * provides a built-in bootloader in system memory that can be entered from a
+ * running program.
+ *
+ * FLASH must first be unlocked before programming. In this module a write to
+ * FLASH is a blocking operation until the end-of-operation flag is asserted.
+ *
+ * @note: don't forget to lock it again when all operations are complete.
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/stm32/flash.h>
+
+/*---------------------------------------------------------------------------*/
+/** @brief Clear All Status Flags
+
+Program error, end of operation, write protect error, busy.
+*/
+
+void flash_clear_status_flags(void)
+{
+ flash_clear_pgerr_flag();
+ flash_clear_eop_flag();
+ flash_clear_wrprterr_flag();
+ flash_clear_bsy_flag();
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Read All Status Flags
+
+The programming error, end of operation, write protect error and busy flags
+are returned in the order of appearance in the status register.
+
+@returns uint32_t. bit 0: busy, bit 2: programming error, bit 4: write protect
+error, bit 5: end of operation.
+*/
+
+uint32_t flash_get_status_flags(void)
+{
+ return (FLASH_SR & (FLASH_SR_PGERR |
+ FLASH_SR_EOP |
+ FLASH_SR_WRPRTERR |
+ FLASH_SR_BSY));
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Program a Half Word to FLASH
+
+This performs all operations necessary to program a 16 bit word to FLASH memory.
+The program error flag should be checked separately for the event that memory
+was not properly erased.
+
+Status bit polling is used to detect end of operation.
+
+@param[in] uint32_t address. Full address of flash half word to be programmed.
+@param[in] uint16_t data.
+*/
+
+void flash_program_half_word(uint32_t address, uint16_t data)
+{
+ flash_wait_for_last_operation();
+
+ FLASH_CR |= FLASH_CR_PG;
+
+ MMIO16(address) = data;
+
+ flash_wait_for_last_operation();
+
+ FLASH_CR &= ~FLASH_CR_PG;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Erase a Page of FLASH
+
+This performs all operations necessary to erase a page in FLASH memory.
+The page should be checked to ensure that it was properly erased. A page must
+first be fully erased before attempting to program it.
+
+Note that the page sizes differ between devices. See the reference manual or
+the FLASH programming manual for details.
+
+@param[in] uint32_t page_address. Full address of flash page to be erased.
+*/
+
+void flash_erase_page(uint32_t page_address)
+{
+ flash_wait_for_last_operation();
+
+ FLASH_CR |= FLASH_CR_PER;
+ FLASH_AR = page_address;
+ FLASH_CR |= FLASH_CR_STRT;
+
+ flash_wait_for_last_operation();
+
+ FLASH_CR &= ~FLASH_CR_PER;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Erase All FLASH
+
+This performs all operations necessary to erase all user pages in the FLASH
+memory. The information block is unaffected.
+*/
+
+void flash_erase_all_pages(void)
+{
+ flash_wait_for_last_operation();
+
+ FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */
+ FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */
+
+ flash_wait_for_last_operation();
+ FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */
+
+}
+
+/**@}*/
+
diff --git a/libopencm3/lib/stm32/f0/gpio.c b/libopencm3/lib/stm32/f0/gpio.c
new file mode 100644
index 0000000..f60b428
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/gpio.c
@@ -0,0 +1,31 @@
+/** @defgroup gpio_file GPIO
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx General Purpose I/O</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 18 August 2012
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/gpio.h>
diff --git a/libopencm3/lib/stm32/f0/i2c.c b/libopencm3/lib/stm32/f0/i2c.c
new file mode 100644
index 0000000..a39c4be
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/i2c.c
@@ -0,0 +1,32 @@
+/** @defgroup i2c_file I2C
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx I2C</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/i2c.h>
+
diff --git a/libopencm3/lib/stm32/f0/iwdg.c b/libopencm3/lib/stm32/f0/iwdg.c
new file mode 100644
index 0000000..b34a652
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/iwdg.c
@@ -0,0 +1,31 @@
+/** @defgroup iwdg_file IWDG
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Independent Watchdog Timer</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/iwdg.h>
diff --git a/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld b/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld
new file mode 100644
index 0000000..3fc2ccb
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for STM32 targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ .text : {
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >rom
+
+ /* C++ Static constructors/destructors, also used for __attribute__
+ * ((constructor)) and the likes */
+ .preinit_array : {
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+ } >rom
+ .init_array : {
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ } >rom
+ .fini_array : {
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+ } >rom
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ .bss : {
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ . = ALIGN(4);
+ end = .;
+}
+
+PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
+
diff --git a/libopencm3/lib/stm32/f0/pwr.c b/libopencm3/lib/stm32/f0/pwr.c
new file mode 100644
index 0000000..8a3ffd2
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/pwr.c
@@ -0,0 +1,38 @@
+/** @defgroup pwr_file PWR
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Power Control</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ * This library supports the power control system for the
+ * STM32F0 series of ARM Cortex Microcontrollers by ST Microelectronics.
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/stm32/pwr.h>
+
+/**@}*/
+
diff --git a/libopencm3/lib/stm32/f0/rcc.c b/libopencm3/lib/stm32/f0/rcc.c
new file mode 100644
index 0000000..1f37133
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/rcc.c
@@ -0,0 +1,665 @@
+/** @defgroup STM32F0xx-rcc-file RCC
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Reset and Clock Control</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 29 Jun 2013
+ *
+ * This library supports the Reset and Clock Control System in the STM32F0xx
+ * series of ARM Cortex Microcontrollers by ST Microelectronics.
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com>
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/cm3/assert.h>
+#include <libopencm3/stm32/rcc.h>
+#include <libopencm3/stm32/flash.h>
+
+uint32_t rcc_core_frequency = 8000000; /* 8MHz after reset */
+uint32_t rcc_ppre_frequency = 8000000; /* 8MHz after reset */
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Clear the Oscillator Ready Interrupt Flag
+ *
+ * Clear the interrupt flag that was set when a clock oscillator became ready
+ * to use.
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_osc_ready_int_clear(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ RCC_CIR |= RCC_CIR_HSI48RDYC;
+ break;
+ case HSI14:
+ RCC_CIR |= RCC_CIR_HSI14RDYC;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYC;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYC;
+ break;
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYC;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYC;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYC;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Enable the Oscillator Ready Interrupt
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_osc_ready_int_enable(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ RCC_CIR |= RCC_CIR_HSI48RDYIE;
+ break;
+ case HSI14:
+ RCC_CIR |= RCC_CIR_HSI14RDYIE;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYIE;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYIE;
+ break;
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYIE;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYIE;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYIE;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Disable the Oscillator Ready Interrupt
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_osc_ready_int_disable(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ RCC_CIR &= ~RCC_CIR_HSI48RDYC;
+ break;
+ case HSI14:
+ RCC_CIR &= ~RCC_CIR_HSI14RDYC;
+ break;
+ case HSI:
+ RCC_CIR &= ~RCC_CIR_HSIRDYC;
+ break;
+ case HSE:
+ RCC_CIR &= ~RCC_CIR_HSERDYC;
+ break;
+ case PLL:
+ RCC_CIR &= ~RCC_CIR_PLLRDYC;
+ break;
+ case LSE:
+ RCC_CIR &= ~RCC_CIR_LSERDYC;
+ break;
+ case LSI:
+ RCC_CIR &= ~RCC_CIR_LSIRDYC;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Read the Oscillator Ready Interrupt Flag
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ * @returns int. Boolean value for flag set.
+ */
+
+int rcc_osc_ready_int_flag(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ return (RCC_CIR & RCC_CIR_HSI48RDYF) != 0;
+ break;
+ case HSI14:
+ return (RCC_CIR & RCC_CIR_HSI14RDYF) != 0;
+ break;
+ case HSI:
+ return (RCC_CIR & RCC_CIR_HSIRDYF) != 0;
+ break;
+ case HSE:
+ return (RCC_CIR & RCC_CIR_HSERDYF) != 0;
+ break;
+ case PLL:
+ return (RCC_CIR & RCC_CIR_PLLRDYF) != 0;
+ break;
+ case LSE:
+ return (RCC_CIR & RCC_CIR_LSERDYF) != 0;
+ break;
+ case LSI:
+ return (RCC_CIR & RCC_CIR_LSIRDYF) != 0;
+ break;
+ }
+
+ cm3_assert_not_reached();
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Clear the Clock Security System Interrupt Flag
+*/
+
+void rcc_css_int_clear(void)
+{
+ RCC_CIR |= RCC_CIR_CSSC;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Read the Clock Security System Interrupt Flag
+ *
+ * @returns int. Boolean value for flag set.
+ */
+
+int rcc_css_int_flag(void)
+{
+ return ((RCC_CIR & RCC_CIR_CSSF) != 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Wait for Oscillator Ready.
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_wait_for_osc_ready(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ while ((RCC_CIR & RCC_CIR_HSI48RDYF) != 0);
+ break;
+ case HSI14:
+ while ((RCC_CIR & RCC_CIR_HSI14RDYF) != 0);
+ break;
+ case HSI:
+ while ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
+ break;
+ case HSE:
+ while ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
+ break;
+ case PLL:
+ while ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
+ break;
+ case LSE:
+ while ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
+ break;
+ case LSI:
+ while ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Turn on an Oscillator.
+ *
+ * Enable an oscillator and power on. Each oscillator requires an amount of
+ * time to settle to a usable state. Refer to datasheets for time delay
+ * information. A status flag is available to indicate when the oscillator
+ * becomes ready (see @ref rcc_osc_ready_int_flag and @ref
+ * rcc_wait_for_osc_ready).
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_osc_on(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ RCC_CR2 |= RCC_CR2_HSI48ON;
+ break;
+ case HSI14:
+ RCC_CR2 |= RCC_CR2_HSI14ON;
+ break;
+ case HSI:
+ RCC_CR |= RCC_CR_HSION;
+ break;
+ case HSE:
+ RCC_CR |= RCC_CR_HSEON;
+ break;
+ case LSE:
+ RCC_BDCR |= RCC_BDCR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR |= RCC_CSR_LSION;
+ break;
+ case PLL:
+ RCC_CR |= RCC_CR_PLLON;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Turn off an Oscillator.
+ *
+ * Disable an oscillator and power off.
+ *
+ * @note An oscillator cannot be turned off if it is selected as the system
+ * clock.
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID
+ */
+
+void rcc_osc_off(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSI48:
+ RCC_CR2 &= ~RCC_CR2_HSI48ON;
+ break;
+ case HSI14:
+ RCC_CR2 &= ~RCC_CR2_HSI14ON;
+ break;
+ case HSI:
+ RCC_CR &= ~RCC_CR_HSION;
+ break;
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEON;
+ break;
+ case LSE:
+ RCC_BDCR &= ~RCC_BDCR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR &= ~RCC_CSR_LSION;
+ break;
+ case PLL:
+ /* don't do anything */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Enable the Clock Security System.
+ */
+
+void rcc_css_enable(void)
+{
+ RCC_CR |= RCC_CR_CSSON;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Disable the Clock Security System.
+ */
+
+void rcc_css_disable(void)
+{
+ RCC_CR &= ~RCC_CR_CSSON;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Enable Bypass.
+ *
+ * Enable an external clock to bypass the internal clock (high speed and low
+ * speed clocks only). The external clock must be enabled (see @ref rcc_osc_on)
+ * and the internal clock must be disabled (see @ref rcc_osc_off) for this to
+ * have effect.
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect.
+ */
+
+void rcc_osc_bypass_enable(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR |= RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_BDCR |= RCC_BDCR_LSEBYP;
+ break;
+ case HSI48:
+ case HSI14:
+ case HSI:
+ case LSI:
+ case PLL:
+ /* Do nothing */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Disable Bypass.
+ *
+ * Re-enable the internal clock (high speed and low speed clocks only). The
+ * internal clock must be disabled (see @ref rcc_osc_off) for this to have
+ * effect.
+ *
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect.
+ */
+
+void rcc_osc_bypass_disable(enum rcc_osc osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_BDCR &= ~RCC_BDCR_LSEBYP;
+ break;
+ case HSI48:
+ case HSI14:
+ case PLL:
+ case HSI:
+ case LSI:
+ /* Do nothing */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Set the Source for the System Clock.
+ *
+ * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE, LSE and PLL have
+ * effect.
+ */
+
+void rcc_set_sysclk_source(enum rcc_osc clk)
+{
+ switch (clk) {
+ case HSI:
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI;
+ break;
+ case HSE:
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSE;
+ break;
+ case PLL:
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
+ break;
+ case HSI48:
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI48;
+ break;
+ case LSI:
+ case LSE:
+ case HSI14:
+ /* do nothing */
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Set the PLL Multiplication Factor.
+ *
+ * @note This only has effect when the PLL is disabled.
+ *
+ * @param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
+ */
+
+void rcc_set_pll_multiplication_factor(uint32_t mul)
+{
+ RCC_CFGR = (RCC_CFGR & RCC_CFGR_PLLMUL) | mul;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Set the APB Prescale Factor.
+ *
+ * @note The APB1 clock frequency must not exceed 36MHz.
+ *
+ * @param[in] ppre1 Unsigned int32. APB prescale factor @ref rcc_cfgr_apb1pre
+ */
+
+void rcc_set_ppre(uint32_t ppre)
+{
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE) | ppre;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Set the AHB Prescale Factor.
+ *
+ * @param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre
+ */
+
+void rcc_set_hpre(uint32_t hpre)
+{
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_HPRE) | hpre;
+}
+
+
+void rcc_set_prediv(uint32_t prediv)
+{
+ RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV) | prediv;
+}
+
+
+void rcc_set_mco(uint32_t mcosrc)
+{
+ RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_MCO) | mcosrc;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief RCC Get the System Clock Source.
+ *
+ * @returns ::osc_t System clock source:
+ */
+
+enum rcc_osc rcc_system_clock_source(void)
+{
+ /* Return the clock source which is used as system clock. */
+ switch (RCC_CFGR & RCC_CFGR_SWS) {
+ case RCC_CFGR_SWS_HSI:
+ return HSI;
+ case RCC_CFGR_SWS_HSE:
+ return HSE;
+ case RCC_CFGR_SWS_PLL:
+ return PLL;
+ case RCC_CFGR_SWS_HSI48:
+ return HSI48;
+ }
+
+ cm3_assert_not_reached();
+}
+
+void rcc_clock_setup_in_hsi_out_8mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ);
+
+ rcc_ppre_frequency = 8000000;
+ rcc_core_frequency = 8000000;
+}
+
+void rcc_clock_setup_in_hsi_out_16mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ);
+
+ /* 8MHz * 4 / 2 = 16MHz */
+ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL4);
+
+ RCC_CFGR &= ~RCC_CFGR_PLLSRC;
+
+ rcc_osc_on(PLL);
+ rcc_wait_for_osc_ready(PLL);
+ rcc_set_sysclk_source(PLL);
+
+ rcc_ppre_frequency = 16000000;
+ rcc_core_frequency = 16000000;
+}
+
+
+void rcc_clock_setup_in_hsi_out_24mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ);
+
+ /* 8MHz * 6 / 2 = 24MHz */
+ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL6);
+
+ RCC_CFGR &= ~RCC_CFGR_PLLSRC;
+
+ rcc_osc_on(PLL);
+ rcc_wait_for_osc_ready(PLL);
+ rcc_set_sysclk_source(PLL);
+
+ rcc_ppre_frequency = 24000000;
+ rcc_core_frequency = 24000000;
+}
+
+void rcc_clock_setup_in_hsi_out_32mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ);
+
+ /* 8MHz * 8 / 2 = 32MHz */
+ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL8);
+
+ RCC_CFGR &= ~RCC_CFGR_PLLSRC;
+
+ rcc_osc_on(PLL);
+ rcc_wait_for_osc_ready(PLL);
+ rcc_set_sysclk_source(PLL);
+
+ rcc_ppre_frequency = 32000000;
+ rcc_core_frequency = 32000000;
+}
+
+void rcc_clock_setup_in_hsi_out_40mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ);
+
+ /* 8MHz * 10 / 2 = 40MHz */
+ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL10);
+
+ RCC_CFGR &= ~RCC_CFGR_PLLSRC;
+
+ rcc_osc_on(PLL);
+ rcc_wait_for_osc_ready(PLL);
+ rcc_set_sysclk_source(PLL);
+
+ rcc_ppre_frequency = 40000000;
+ rcc_core_frequency = 40000000;
+}
+
+void rcc_clock_setup_in_hsi_out_48mhz(void)
+{
+ rcc_osc_on(HSI);
+ rcc_wait_for_osc_ready(HSI);
+ rcc_set_sysclk_source(HSI);
+
+ rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
+ rcc_set_ppre(RCC_CFGR_PPRE_NODIV);
+
+ flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ);
+
+ /* 8MHz * 12 / 2 = 48MHz */
+ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL12);
+
+ RCC_CFGR &= ~RCC_CFGR_PLLSRC;
+
+ rcc_osc_on(PLL);
+ rcc_wait_for_osc_ready(PLL);
+ rcc_set_sysclk_source(PLL);
+
+ rcc_ppre_frequency = 48000000;
+ rcc_core_frequency = 48000000;
+}
+
+
+#define _RCC_REG(i) MMIO32(RCC_BASE + ((i) >> 5))
+#define _RCC_BIT(i) (1 << ((i) & 0x1f))
+
+void rcc_periph_clock_enable(enum rcc_periph_clken periph)
+{
+ _RCC_REG(periph) |= _RCC_BIT(periph);
+}
+
+void rcc_periph_clock_disable(enum rcc_periph_clken periph)
+{
+ _RCC_REG(periph) &= ~_RCC_BIT(periph);
+}
+
+void rcc_periph_reset_pulse(enum rcc_periph_rst periph)
+{
+ _RCC_REG(periph) |= _RCC_BIT(periph);
+ _RCC_REG(periph) &= ~_RCC_BIT(periph);
+}
+
+void rcc_periph_reset_hold(enum rcc_periph_rst periph)
+{
+ _RCC_REG(periph) |= _RCC_BIT(periph);
+}
+
+void rcc_periph_reset_release(enum rcc_periph_rst periph)
+{
+ _RCC_REG(periph) &= ~_RCC_BIT(periph);
+}
+
+#undef _RCC_REG
+#undef _RCC_BIT
+
+/**@}*/
+
diff --git a/libopencm3/lib/stm32/f0/rtc.c b/libopencm3/lib/stm32/f0/rtc.c
new file mode 100644
index 0000000..6d55cc7
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/rtc.c
@@ -0,0 +1,31 @@
+/** @defgroup rtc_file RTC
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx RTC</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 10 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/rtc.h>
diff --git a/libopencm3/lib/stm32/f0/spi.c b/libopencm3/lib/stm32/f0/spi.c
new file mode 100644
index 0000000..c341001
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/spi.c
@@ -0,0 +1,31 @@
+/** @defgroup spi_file SPI
+
+@ingroup STM32F0xx
+
+@brief <b>libopencm3 STM32F0xx SPI</b>
+
+@version 1.0.0
+
+@date 20 February 2014
+
+LGPL License Terms @ref lgpl_license
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/spi.h>
diff --git a/libopencm3/lib/stm32/f0/syscfg.c b/libopencm3/lib/stm32/f0/syscfg.c
new file mode 100644
index 0000000..5067d96
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/syscfg.c
@@ -0,0 +1,31 @@
+/** @defgroup syscfg_file SYSCFG
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx SYSCFG</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 10 July 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/syscfg.h>
diff --git a/libopencm3/lib/stm32/f0/timer.c b/libopencm3/lib/stm32/f0/timer.c
new file mode 100644
index 0000000..8800683
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/timer.c
@@ -0,0 +1,34 @@
+/** @defgroup timer_file Timers
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx Timers</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 11 July 2013
+ *
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
+ * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/timer.h>
+
diff --git a/libopencm3/lib/stm32/f0/usart.c b/libopencm3/lib/stm32/f0/usart.c
new file mode 100644
index 0000000..3788926
--- /dev/null
+++ b/libopencm3/lib/stm32/f0/usart.c
@@ -0,0 +1,429 @@
+/** @defgroup usart_file USART
+ *
+ * @ingroup STM32F0xx
+ *
+ * @brief <b>libopencm3 STM32F0xx USART</b>
+ *
+ * @version 1.0.0
+ *
+ * @date 7 Jul 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/usart.h>
+#include <libopencm3/stm32/rcc.h>
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Baudrate.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] baud unsigned 32 bit. Baud rate specified in Hz.
+ */
+
+void usart_set_baudrate(uint32_t usart, uint32_t baud)
+{
+ uint32_t clock = rcc_ppre_frequency;
+
+ if (usart == USART1) {
+ clock = rcc_ppre_frequency;
+ /* TODO selective PCLK, SYSCLK, HSI or LSE */
+ }
+
+ /* TODO check oversampling 16 */
+ USART_BRR(usart) = ((2 * clock) + baud) / (2 * baud);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Word Length.
+ *
+ * The word length is set to 8 or 9 bits. Note that the last bit will be a
+ * parity bit if parity is enabled, in which case the data length will be 7
+ * or 8 bits respectively.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] bits unsigned 32 bit. Word length in bits 8 or 9.
+ */
+
+void usart_set_databits(uint32_t usart, uint32_t bits)
+{
+ if (bits == 8) {
+ USART_CR1(usart) &= ~USART_CR1_M; /* 8 data bits */
+ } else {
+ USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Stop Bit(s).
+ *
+ * The stop bits are specified as 0.5, 1, 1.5 or 2.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] stopbits unsigned 32 bit. Stop bits @ref usart_cr2_stopbits.
+ */
+
+void usart_set_stopbits(uint32_t usart, uint32_t stopbits)
+{
+ USART_CR2(usart) = (USART_CR2(usart) & ~USART_CR2_STOP) | stopbits;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Parity.
+ *
+ * The parity bit can be selected as none, even or odd.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] parity unsigned 32 bit. Parity @ref usart_cr1_parity.
+ */
+
+void usart_set_parity(uint32_t usart, uint32_t parity)
+{
+ USART_CR1(usart) = (USART_CR1(usart) & ~USART_PARITY) | parity;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Rx/Tx Mode.
+ *
+ * The mode can be selected as Rx only, Tx only or Rx+Tx.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] mode unsigned 32 bit. Mode @ref usart_cr1_mode.
+ */
+
+void usart_set_mode(uint32_t usart, uint32_t mode)
+{
+ USART_CR1(usart) = (USART_CR1(usart) & ~USART_MODE) | mode;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Set Hardware Flow Control.
+ *
+ * The flow control bit can be selected as none, RTS, CTS or RTS+CTS.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] flowcontrol unsigned 32 bit. Flowcontrol @ref
+ * usart_cr3_flowcontrol.
+ */
+
+void usart_set_flow_control(uint32_t usart, uint32_t flowctrl)
+{
+ USART_CR3(usart) = (USART_CR3(usart) & ~USART_FLOWCONTROL) | flowctrl;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Enable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_enable(uint32_t usart)
+{
+ USART_CR1(usart) |= USART_CR1_UE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Disable.
+ *
+ * At the end of the current frame, the USART is disabled to reduce power.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable(uint32_t usart)
+{
+ USART_CR1(usart) &= ~USART_CR1_UE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Send a Data Word.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] data unsigned 16 bit.
+ */
+
+void usart_send(uint32_t usart, uint8_t data)
+{
+ USART_TDR(usart) = data;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Read a Received Data Word.
+ *
+ * If parity is enabled the MSB (bit 7 or 8 depending on the word length) is
+ * the parity bit.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @returns unsigned 16 bit data word.
+ */
+
+uint8_t usart_recv(uint32_t usart)
+{
+ /* Receive data. */
+ return USART_RDR(usart);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Wait for Transmit Data Buffer Empty
+ *
+ * Blocks until the transmit data buffer becomes empty and is ready to accept
+ * the next data word.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_wait_send_ready(uint32_t usart)
+{
+ /* Wait until the data has been transferred into the shift register. */
+ while ((USART_ISR(usart) & USART_ISR_TXE) == 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Wait for Received Data Available
+ *
+ * Blocks until the receive data buffer holds a valid received data word.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_wait_recv_ready(uint32_t usart)
+{
+ /* Wait until the data is ready to be received. */
+ while ((USART_ISR(usart) & USART_ISR_RXNE) == 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Send Data Word with Blocking
+ *
+ * Blocks until the transmit data buffer becomes empty then writes the next
+ * data word for transmission.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] data unsigned 16 bit.
+ */
+
+void usart_send_blocking(uint32_t usart, uint8_t data)
+{
+ usart_wait_send_ready(usart);
+ usart_send(usart, data);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Read a Received Data Word with Blocking.
+ *
+ * Wait until a data word has been received then return the word.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @returns unsigned 16 bit data word.
+ */
+
+uint8_t usart_recv_blocking(uint32_t usart)
+{
+ usart_wait_recv_ready(usart);
+
+ return usart_recv(usart);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Receiver DMA Enable.
+ *
+ * DMA is available on:
+ * @li USART1 Rx DMA1 channel 3 or 5.
+ * @li USART2 Rx DMA1 channel 5.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_enable_rx_dma(uint32_t usart)
+{
+ USART_CR3(usart) |= USART_CR3_DMAR;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Receiver DMA Disable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable_rx_dma(uint32_t usart)
+{
+ USART_CR3(usart) &= ~USART_CR3_DMAR;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Transmitter DMA Enable.
+ *
+ * DMA is available on:
+ * @li USART1 Tx DMA1 channel 2 or 4.
+ * @li USART2 Tx DMA1 channel 4.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_enable_tx_dma(uint32_t usart)
+{
+ USART_CR3(usart) |= USART_CR3_DMAT;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Transmitter DMA Disable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable_tx_dma(uint32_t usart)
+{
+ USART_CR3(usart) &= ~USART_CR3_DMAT;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Receiver Interrupt Enable.
+
+@param[in] usart unsigned 32 bit. USART block register address base @ref
+usart_reg_base
+*/
+
+void usart_enable_rx_interrupt(uint32_t usart)
+{
+ USART_CR1(usart) |= USART_CR1_RXNEIE;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Receiver Interrupt Disable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable_rx_interrupt(uint32_t usart)
+{
+ USART_CR1(usart) &= ~USART_CR1_RXNEIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Transmitter Interrupt Enable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_enable_tx_interrupt(uint32_t usart)
+{
+ USART_CR1(usart) |= USART_CR1_TXEIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Transmitter Interrupt Disable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable_tx_interrupt(uint32_t usart)
+{
+ USART_CR1(usart) &= ~USART_CR1_TXEIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Error Interrupt Enable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_enable_error_interrupt(uint32_t usart)
+{
+ USART_CR3(usart) |= USART_CR3_EIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Error Interrupt Disable.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ */
+
+void usart_disable_error_interrupt(uint32_t usart)
+{
+ USART_CR3(usart) &= ~USART_CR3_EIE;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Read a Status Flag.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags.
+ * @returns boolean: flag set.
+ */
+
+bool usart_get_flag(uint32_t usart, uint32_t flag)
+{
+ return ((USART_ISR(usart) & flag) != 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief USART Return Interrupt Source.
+ *
+ * Returns true if the specified interrupt flag (IDLE, RXNE, TC, TXE or OE) was
+ * set and the interrupt was enabled. If the specified flag is not an interrupt
+ * flag, the function returns false.
+ *
+ * @param[in] usart unsigned 32 bit. USART block register address base @ref
+ * usart_reg_base
+ * @param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags.
+ * @returns boolean: flag and interrupt enable both set.
+ */
+
+bool usart_get_interrupt_source(uint32_t usart, uint32_t flag)
+{
+ uint32_t flag_set = (USART_ISR(usart) & flag);
+ /* IDLE, RXNE, TC, TXE interrupts */
+ if ((flag >= USART_ISR_IDLE) && (flag <= USART_ISR_TXE)) {
+ return ((flag_set & USART_CR1(usart)) != 0);
+ /* Overrun error */
+ } else if (flag == USART_ISR_ORE) {
+ return flag_set && (USART_CR3(usart) & USART_CR3_CTSIE);
+ }
+
+ return false;
+}
+
+/**@}*/
+