Add software

This commit is contained in:
RocketGod
2022-09-22 09:26:57 -07:00
parent fee0ab05fd
commit 957ea3d712
4511 changed files with 1943182 additions and 0 deletions

View File

@ -0,0 +1,46 @@
##
## 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
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 spi.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
VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include

View File

@ -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);
}
/**@}*/
/*---------------------------------------------------------------------------*/
/**@}*/

View File

@ -0,0 +1,61 @@
/** @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;
}

View File

@ -0,0 +1,33 @@
/** @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>
#include <libopencm3/stm32/common/crc_common_all.h>

View File

@ -0,0 +1,33 @@
/** @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>
#include <libopencm3/stm32/common/dac_common_all.h>

View File

@ -0,0 +1,33 @@
/** @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>
#include <libopencm3/stm32/common/dma_common_l1f013.h>

View File

@ -0,0 +1,93 @@
/*
* 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>
void flash_prefetch_buffer_enable(void)
{
FLASH_ACR |= FLASH_ACR_PRFTBE;
}
void flash_prefetch_buffer_disable(void)
{
FLASH_ACR &= ~FLASH_ACR_PRFTBE;
}
void flash_set_ws(uint32_t ws)
{
FLASH_ACR = (FLASH_ACR & ~FLASH_ACR_LATENCY) | ws;
}
void flash_wait_busy(void)
{
while ((FLASH_SR & FLASH_SR_BSY) != 0);
}
void flash_program_u32(uint32_t address, uint32_t data)
{
flash_wait_busy();
FLASH_CR |= FLASH_CR_PG;
MMIO16(address) = (uint16_t)data;
flash_wait_busy();
MMIO16(address + 2) = data >> 16;
flash_wait_busy();
FLASH_CR &= ~FLASH_CR_PG;
}
void flash_program_u16(uint32_t address, uint16_t data)
{
flash_wait_busy();
FLASH_CR |= FLASH_CR_PG;
MMIO16(address) = data;
flash_wait_busy();
FLASH_CR &= ~FLASH_CR_PG;
}
void flash_erase_page(uint32_t page_address)
{
flash_wait_busy();
FLASH_CR |= FLASH_CR_PER;
FLASH_AR = page_address;
FLASH_CR |= FLASH_CR_STRT;
flash_wait_busy();
FLASH_CR &= ~FLASH_CR_PER;
}
void flash_erase_all_pages(void)
{
flash_wait_busy();
FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */
FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */
flash_wait_busy();
FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */
}

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,33 @@
/** @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>
#include <libopencm3/stm32/common/iwdg_common_all.h>

View File

@ -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));

View File

@ -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>
/**@}*/

View File

@ -0,0 +1,637 @@
/** @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 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 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 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 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 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 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 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 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 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 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 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;
}
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 = 32000000;
rcc_core_frequency = 32000000;
}
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 = 24MHz */
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL16);
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
/**@}*/

View File

@ -0,0 +1,32 @@
/** @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>
#include <libopencm3/stm32/common/rtc_common_l1f024.h>

View File

@ -0,0 +1,54 @@
/** @defgroup spi_file SPI
*
* @ingroup STM32F0xx
*
* @brief <b>libopencm3 STM32F0xx Serial Peripheral Interface</b>
*
* @version 1.0.0
*
* @date 11 July 2013
*
* LGPL License Terms @ref lgpl_license
*/
/*
* 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/>.
*/
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/rcc.h>
void spi_set_data_size(uint32_t spi, uint16_t data_s)
{
SPI_CR2(spi) = (SPI_CR2(spi) & ~SPI_CR2_DS_MASK) |
(data_s & SPI_CR2_DS_MASK);
}
void spi_fifo_reception_threshold_8bit(uint32_t spi)
{
SPI_CR2(spi) |= SPI_CR2_FRXTH;
}
void spi_fifo_reception_threshold_16bit(uint32_t spi)
{
SPI_CR2(spi) &= ~SPI_CR2_FRXTH;
}
void spi_i2s_mode_spi_mode(uint32_t spi)
{
SPI_I2SCFGR(spi) &= ~SPI_I2SCFGR_I2SMOD;
}

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
/**@}*/