Merging pull request #23 Changed markup to get more control over documentation.

Merge remote-tracking branch 'ksarkies/doc'
This commit is contained in:
Piotr Esden-Tempski
2012-08-25 15:16:50 -07:00
19 changed files with 1588 additions and 290 deletions

View File

@@ -1,3 +1,24 @@
/** @defgroup STM32F1xx-dma-file DMA
@ingroup STM32F1xx
@brief <b>libopencm3 STM32F1xx DMA Controller</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
@date 18 August 2012
This library supports the DMA
Control System in the STM32F1xx series of ARM Cortex Microcontrollers
by ST Microelectronics. It can provide for two DMA controllers,
one with 7 channels and one with 5. Channels are hardware dedicated
and each is shared with a number of different sources (only one can be
used at a time, under the responsibility of the programmer).
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -17,8 +38,19 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
#include <libopencm3/stm32/f1/dma.h>
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Reset
The channel is disabled and configuration registers are cleared.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_channel_reset(u32 dma, u8 channel)
{
/* Disable channel. */
@@ -35,18 +67,51 @@ void dma_channel_reset(u32 dma, u8 channel)
DMA_IFCR(dma) |= DMA_IFCR_CIF(channel);
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Memory to Memory Transfers
Memory to memory transfers do not require a trigger to activate each transfer.
Transfers begin immediately the channel has been enabled, and proceed without
intervention.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_mem2mem_mode(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_MEM2MEM;
DMA_CCR(dma, channel) &= ~DMA_CCR_CIRC;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set Priority
Channel Priority has four levels: low to very high. This has precedence over the
hardware priority.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] prio unsigned int32. Priority level @ref dma_ch_pri.
*/
void dma_set_priority(u32 dma, u8 channel, u32 prio)
{
DMA_CCR(dma, channel) &= ~(DMA_CCR_PL_MASK);
DMA_CCR(dma, channel) |= prio;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set Memory Word Width
Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for
alignment information if the source and destination widths do not match.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] mem_size unsigned int32. Memory word width @ref dma_ch_memwidth.
*/
void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size)
{
@@ -54,89 +119,249 @@ void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size)
DMA_CCR(dma, channel) |= mem_size;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set Peripheral Word Width
Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for
alignment information if the source and destination widths do not match, or
if the peripheral does not support byte or half-word writes.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] peripheral_size unsigned int32. Peripheral word width @ref dma_ch_perwidth.
*/
void dma_set_peripheral_size(u32 dma, u8 channel, u32 peripheral_size)
{
DMA_CCR(dma, channel) &= ~(DMA_CCR_PSIZE_MASK);
DMA_CCR(dma, channel) |= peripheral_size;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Memory Increment after Transfer
Following each transfer the current memory address is incremented by
1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The
value held by the base memory address register is unchanged.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_memory_increment_mode(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_MINC;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Disable Memory Increment after Transfer
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_peripheral_increment_mode(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_PINC;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Memory Circular Mode
After the number of bytes/words to be transferred has been completed, the
original transfer block size, memory and peripheral base addresses are
reloaded and the process repeats.
@note This cannot be used with memory to memory mode, which is explictly
disabled here.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_circular_mode(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_CIRC;
DMA_CCR(dma, channel) &= ~DMA_CCR_MEM2MEM;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Transfers from a Peripheral
The data direction is set to read from a peripheral.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_set_read_from_peripheral(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) &= ~DMA_CCR_DIR;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Transfers from Memory
The data direction is set to read from memory.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_set_read_from_memory(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_DIR;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Interrupt on Transfer Error
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_transfer_error_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_TEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Disable Interrupt on Transfer Error
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_disable_transfer_error_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) &= ~DMA_CCR_TEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Interrupt on Transfer Half Complete
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_half_transfer_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_HTIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Disable Interrupt on Transfer Half Complete
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_disable_half_transfer_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) &= ~DMA_CCR_HTIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Interrupt on Transfer Complete
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_transfer_complete_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_TCIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Disable Interrupt on Transfer Complete
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_disable_transfer_complete_interrupt(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) &= ~DMA_CCR_TCIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_enable_channel(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_EN;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Disable
@note The DMA channel registers retain their values when the channel is disabled.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
void dma_disable_channel(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) &= ~DMA_CCR_EN;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set the Peripheral Address
Set the address of the peripheral register to or from which data is to be transferred.
Refer to the documentation for the specific peripheral.
@note The DMA channel must be disabled before setting this address. This function
has no effect if the channel is enabled.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] address unsigned int32. Peripheral Address.
*/
void dma_set_peripheral_address(u32 dma, u8 channel, u32 address)
{
DMA_CPAR(dma, channel) = (u32) address;
if (!(DMA_CCR(dma, channel) & DMA_CCR_EN))
DMA_CPAR(dma, channel) = (u32) address;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set the Base Memory Address
@note The DMA channel must be disabled before setting this address. This function
has no effect if the channel is enabled.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] address unsigned int32. Memory Initial Address.
*/
void dma_set_memory_address(u32 dma, u8 channel, u32 address)
{
DMA_CMAR(dma, channel) = (u32) address;
if (!(DMA_CCR(dma, channel) & DMA_CCR_EN))
DMA_CMAR(dma, channel) = (u32) address;
}
/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Set the Transfer Block Size
@note The DMA channel must be disabled before setting this count value. The count
is not changed if the channel is enabled.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
@param[in] number unsigned int16. Number of data words to transfer (65535 maximum).
*/
void dma_set_number_of_data(u32 dma, u8 channel, u16 number)
{
DMA_CNDTR(dma, channel) = number;
}
/**@}*/

View File

@@ -1,3 +1,61 @@
/** @defgroup STM32F1xx_gpio_file GPIO
@ingroup STM32F1xx
@brief <b>libopencm3 STM32F1xx General Purpose I/O</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
@date 18 August 2012
This library supports the General Purpose I/O System in the STM32F1xx series
of ARM Cortex Microcontrollers by ST Microelectronics.
Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO
functionality with a number of alternate functions and must be configured to the
alternate function mode if these are to be accessed. A feature is available to
remap alternative functions to a limited set of alternative pins in the event
of a clash of requirements.
The data registers associated with each port for input and output are 32 bit with
the upper 16 bits unused. The output buffer must be written as a 32 bit word, but
individual bits may be set or reset separately in atomic operations to avoid race
conditions during interrupts. Bits may also be individually locked to prevent
accidental configuration changes. Once locked the configuration cannot be changed
until after the next reset.
Each port bit can be configured as analog or digital input, the latter can be
floating or pulled up or down. As outputs they can be configured as either
push-pull or open drain, digital I/O or alternate function, and with maximum
output speeds of 2MHz, 10MHz, or 50MHz.
On reset all ports are configured as digital floating input.
@section gpio_api_ex Basic GPIO Handling API.
Example 1: Push-pull digital output actions on ports C2 and C9
@code
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2 | GPIO9);
gpio_set(GPIOC, GPIO2 | GPIO9);
gpio_clear(GPIOC, GPIO2);
gpio_toggle(GPIOC, GPIO2 | GPIO9);
gpio_port_write(GPIOC, 0x204);
@endcode
Example 1: Digital input on port C12
@code
gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT, GPIO12);
reg16 = gpio_port_read(GPIOC);
@endcode
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -33,9 +91,23 @@
* TODO:
* - GPIO remapping support
*/
/**@{*/
#include <libopencm3/stm32/f1/gpio.h>
/*-----------------------------------------------------------------------------*/
/** @brief Set GPIO Pin Mode
Sets the mode (input/output) and configuration (analog/digitial and
open drain/push pull), for a set of GPIO pins on a given GPIO port.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] mode Unsigned int8. Pin mode @ref gpio_mode
@param[in] cnf Unsigned int8. Pin configuration @ref gpio_cnf
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be set, use logical OR '|' to separate them.
*/
void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios)
{
u16 i, offset = 0;
@@ -73,69 +145,99 @@ void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios)
GPIO_CRH(gpioport) = crh;
}
/**
* Set one or more pins of the given GPIO port to 1.
*
* @param gpioport The GPIO port to use (GPIOA - GPIOG).
* @param gpios The GPIO pin(s) to set to 1 (GPIO0 - GPIO15, or GPIO_ALL).
* If multiple pins shall be set, use '|' to separate them.
*/
/*-----------------------------------------------------------------------------*/
/** @brief Set a Group of Pins Atomic
Set one or more pins of the given GPIO port to 1 in an atomic operation.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use logical OR '|' to separate them.
*/
void gpio_set(u32 gpioport, u16 gpios)
{
GPIO_BSRR(gpioport) = gpios;
}
/**
* Clear one or more pins of the given GPIO port to 0.
*
* @param gpioport The GPIO port to use (GPIOA - GPIOG).
* @param gpios The GPIO pin(s) to set to 0 (GPIO0 - GPIO15, or GPIO_ALL).
* If multiple pins shall be cleared, use '|' to separate them.
*/
/*-----------------------------------------------------------------------------*/
/** @brief Clear a Group of Pins Atomic
Clear one or more pins of the given GPIO port to 0 in an atomic operation.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use logical OR '|' to separate them.
*/
void gpio_clear(u32 gpioport, u16 gpios)
{
GPIO_BRR(gpioport) = gpios;
}
/*-----------------------------------------------------------------------------*/
/** @brief Read a Group of Pins.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be read, use logical OR '|' to separate them.
@return Unsigned int16 value of the pin values. The bit position of the pin value
returned corresponds to the pin number.
*/
u16 gpio_get(u32 gpioport, u16 gpios)
{
return gpio_port_read(gpioport) & gpios;
}
/**
* Toggle one or more pins of the given GPIO port.
*
* @param gpioport The GPIO port to use (GPIOA - GPIOG).
* @param gpios The GPIO pin(s) to toggle (GPIO0 - GPIO15, or GPIO_ALL).
* If multiple pins shall be toggled, use '|' to separate them.
*/
/*-----------------------------------------------------------------------------*/
/** @brief Toggle a Group of Pins
Toggle one or more pins of the given GPIO port. This is not an atomic operation.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use logical OR '|' to separate them.
*/
void gpio_toggle(u32 gpioport, u16 gpios)
{
GPIO_ODR(gpioport) ^= gpios;
}
/**
* Read the current value of the given GPIO port.
*
* @param gpioport The GPIO port to read (GPIOA - GPIOG).
* @return The value of the current GPIO port.
*/
/*-----------------------------------------------------------------------------*/
/** @brief Read from a Port
Read the current value of the given GPIO port. Only the lower 16 bits contain
valid pin data.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@return Unsigned int16. The value held in the specified GPIO port.
*/
u16 gpio_port_read(u32 gpioport)
{
return (u16)GPIO_IDR(gpioport);
}
/**
* Write to the given GPIO port.
*
* @param gpioport The GPIO port to write to (GPIOA - GPIOG).
* @param data The data to write to the specified GPIO port.
*/
/*-----------------------------------------------------------------------------*/
/** @brief Write to a Port
Write a value to the given GPIO port.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] data Unsigned int16. The value to be written to the GPIO port.
*/
void gpio_port_write(u32 gpioport, u16 data)
{
GPIO_ODR(gpioport) = data;
}
/*-----------------------------------------------------------------------------*/
/** @brief Lock the Configuration of a Group of Pins
The configuration of one or more pins of the given GPIO port is locked. There is
no mechanism to unlock these via software. Unlocking occurs at the next reset.
@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
If multiple pins are to be locked, use logical OR '|' to separate them.
*/
void gpio_port_config_lock(u32 gpioport, u16 gpios)
{
u32 reg32;
@@ -152,3 +254,64 @@ void gpio_port_config_lock(u32 gpioport, u16 gpios)
/* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
}
/*-----------------------------------------------------------------------------*/
/** @brief Map the EVENTOUT signal
Enable the EVENTOUT signal and select the port and pin to be used.
@param[in] evoutport Unsigned int8. Port for EVENTOUT signal @ref afio_evcr_port
@param[in] evoutpin Unsigned int8. Pin for EVENTOUT signal @ref afio_evcr_pin
*/
void gpio_set_eventout(u8 evoutport, u8 evoutpin)
{
AFIO_EVCR = AFIO_EVCR_EVOE | evoutport | evoutpin;
}
/*-----------------------------------------------------------------------------*/
/** @brief Map Alternate Function Port Bits (Main Set)
A number of alternate function ports can be remapped to defined alternative
port bits to avoid clashes in cases where multiple alternate functions are present.
Refer to the datasheets for the particular mapping desired. This provides the main
set of remap functionality. See @ref gpio_secondary_remap for a number of lesser used
remaps.
The AFIO remapping feature is used only with the STM32F10x series.
@note The Serial Wire JTAG disable controls allow certain GPIO ports to become available
in place of some of the SWJ signals. Full SWJ capability is obtained by setting this to
zero. The value of this must be specified for every call to this function as its current
value cannot be ascertained from the hardware.
@param[in] swjdisable Unsigned int8. Disable parts of the SWJ capability @ref afio_swj_disable.
@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap,
@ref afio_remap_can1, @ref afio_remap_tim3, @ref afio_remap_tim2, @ref afio_remap_tim1,
@ref afio_remap_usart3. For connectivity line devices only @ref afio_remap_cld are
also available.
*/
void gpio_primary_remap(u8 swjdisable, u32 maps)
{
AFIO_MAPR = swjdisable | (maps & 0x1FFFFF);
}
/*-----------------------------------------------------------------------------*/
/** @brief Map Alternate Function Port Bits (Secondary Set)
A number of alternate function ports can be remapped to defined alternative
port bits to avoid clashes in cases where multiple alternate functions are present.
Refer to the datasheets for the particular mapping desired. This provides the second
smaller and less used set of remap functionality. See @ref gpio_primary_remap for
the main set of remaps.
The AFIO remapping feature is used only with the STM32F10x series.
@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap2
*/
void gpio_secondary_remap(u32 maps)
{
AFIO_MAPR2 = maps;
}
/**@}*/

217
lib/stm32/f1/pwr.c Normal file
View File

@@ -0,0 +1,217 @@
/** @defgroup STM32F1xx-pwr-file PWR
@ingroup STM32F1xx
@brief <b>libopencm3 STM32F1xx Power Control</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
@date 18 August 2012
This library supports the power control system for the
STM32F1 series of ARM Cortex Microcontrollers by ST Microelectronics.
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/stm32/pwr.h>
/*---------------------------------------------------------------------------*/
/** @brief Disable Backup Domain Write Protection.
This allows backup domain registers to be changed. These registers are write
protected after a reset.
*/
void pwr_disable_backup_domain_write_protect(void)
{
PWR_CR |= PWR_CR_DBP;
}
/*---------------------------------------------------------------------------*/
/** @brief Re-enable Backup Domain Write Protection.
This protects backup domain registers from inadvertent change.
*/
void pwr_enable_backup_domain_write_protect(void)
{
PWR_CR &= ~PWR_CR_DBP;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Power Voltage Detector.
This provides voltage level threshold detection. The result of detection is
provided in the power voltage detector output flag (see @ref pwr_voltage_high)
or by setting the EXTI16 interrupt (see datasheet for configuration details).
@param[in] pvd_level u32. Taken from @ref pwr_pls.
*/
void pwr_enable_power_voltage_detect(u32 pvd_level)
{
PWR_CR &= ~PWR_CR_PLS_MASK;
PWR_CR |= (PWR_CR_PVDE | pvd_level);
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Power Voltage Detector.
*/
void pwr_disable_power_voltage_detect(void)
{
PWR_CR &= ~PWR_CR_PVDE;
}
/*---------------------------------------------------------------------------*/
/** @brief Clear the Standby Flag.
This is set when the processor returns from a standby mode.
*/
void pwr_clear_standby_flag(void)
{
PWR_CR |= PWR_CR_CSBF;
}
/*---------------------------------------------------------------------------*/
/** @brief Clear the Wakeup Flag.
This is set when the processor receives a wakeup signal.
*/
void pwr_clear_wakeup_flag(void)
{
PWR_CR |= PWR_CR_CWUF;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Standby Mode in Deep Sleep.
*/
void pwr_set_standby_mode(void)
{
PWR_CR |= PWR_CR_PDDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Stop Mode in Deep Sleep.
*/
void pwr_set_stop_mode(void)
{
PWR_CR &= ~PWR_CR_PDDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Voltage Regulator On in Stop Mode.
*/
void pwr_voltage_regulator_on_in_stop(void)
{
PWR_CR &= ~PWR_CR_LPDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Voltage Regulator Low Power in Stop Mode.
*/
void pwr_voltage_regulator_low_power_in_stop(void)
{
PWR_CR |= PWR_CR_LPDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Wakeup Pin.
The wakeup pin is used for waking the processor from standby mode.
*/
void pwr_enable_wakeup_pin(void)
{
PWR_CSR |= PWR_CR_EWUP;
}
/*---------------------------------------------------------------------------*/
/** @brief Release Wakeup Pin.
The wakeup pin is used for general purpose I/O.
*/
void pwr_disable_wakeup_pin(void)
{
PWR_CSR &= ~PWR_CR_EWUP;
}
/*---------------------------------------------------------------------------*/
/** @brief Get Voltage Detector Output.
The voltage detector threshold must be set when the power voltage detector is
enabled, see @ref pwr_enable_power_voltage_detect.
@returns boolean: TRUE if the power voltage is above the preset voltage
threshold.
*/
bool pwr_voltage_high(void)
{
return (PWR_CSR & PWR_CR_PVDO);
}
/*---------------------------------------------------------------------------*/
/** @brief Get Standby Flag.
The standby flag is set when the processor returns from a standby state. It is
cleared by software (see @ref pwr_clear_standby_flag).
@returns boolean: TRUE if the processor was in standby state.
*/
bool pwr_get_standby_flag(void)
{
return (PWR_CSR & PWR_CR_SBF);
}
/*---------------------------------------------------------------------------*/
/** @brief Get Wakeup Flag.
The wakeup flag is set when a wakeup event has been received. It is
cleared by software (see @ref pwr_clear_wakeup_flag).
@returns boolean: TRUE if a wakeup event was received.
*/
bool pwr_get_wakeup_flag(void)
{
return (PWR_CSR & PWR_CR_WUF);
}
/**@}*/

View File

@@ -1,4 +1,4 @@
/** @file
/** @defgroup STM32F1xx-rcc-file RCC
@ingroup STM32F1xx
@@ -10,25 +10,26 @@
@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
@date 18 May 2012
@date 18 August 2012
This library supports the Reset and Clock
Control System in the STM32F1xx series of ARM Cortex Microcontrollers
by ST Microelectronics.
This library supports the Reset and Clock Control System in the STM32F1xx
series of ARM Cortex Microcontrollers by ST Microelectronics.
@note Full support for connection line devices is not yet provided.
Clock settings and resets for many peripherals are given here rather than in the
peripheral library.
corresponding peripheral library.
The library also provides a number of common configurations for the processor
system clock. Not all possible configurations are given here.
@bugs None known
system clock. Not all possible configurations are included.
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
@@ -45,6 +46,7 @@ LGPL License Terms @ref lgpl_license
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
@@ -54,12 +56,12 @@ u32 rcc_ppre1_frequency = 8000000;
/** Default ppre2 peripheral clock frequency after reset. */
u32 rcc_ppre2_frequency = 8000000;
//-----------------------------------------------------------------------------
/** @brief RCC Clear the Oscillator Ready Interrupt
/*-----------------------------------------------------------------------------*/
/** @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] enum ::osc_t. Oscillator ID
@param[in] osc enum ::osc_t. Oscillator ID
*/
void rcc_osc_ready_int_clear(osc_t osc)
@@ -83,6 +85,12 @@ void rcc_osc_ready_int_clear(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Enable the Oscillator Ready Interrupt
@param[in] osc enum ::osc_t. Oscillator ID
*/
void rcc_osc_ready_int_enable(osc_t osc)
{
switch (osc) {
@@ -104,6 +112,12 @@ void rcc_osc_ready_int_enable(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Disable the Oscillator Ready Interrupt
@param[in] osc enum ::osc_t. Oscillator ID
*/
void rcc_osc_ready_int_disable(osc_t osc)
{
switch (osc) {
@@ -125,6 +139,13 @@ void rcc_osc_ready_int_disable(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @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(osc_t osc)
{
switch (osc) {
@@ -149,16 +170,33 @@ int rcc_osc_ready_int_flag(osc_t osc)
return -1;
}
/*-----------------------------------------------------------------------------*/
/** @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(osc_t osc)
{
switch (osc) {
@@ -180,6 +218,20 @@ void rcc_wait_for_osc_ready(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @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).
@note The LSE clock is in the backup domain and cannot be enabled until the
backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect).
@param[in] osc enum ::osc_t. Oscillator ID
*/
void rcc_osc_on(osc_t osc)
{
switch (osc) {
@@ -201,6 +253,20 @@ void rcc_osc_on(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @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.
@note The LSE clock is in the backup domain and cannot be disabled until the
backup domain write protection has been removed (see
@ref pwr_disable_backup_domain_write_protect) or the backup domain has been
(see reset @ref rcc_backupdomain_reset).
@param[in] osc enum ::osc_t. Oscillator ID
*/
void rcc_osc_off(osc_t osc)
{
switch (osc) {
@@ -222,16 +288,39 @@ void rcc_osc_off(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @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.
@note The LSE clock is in the backup domain and cannot be bypassed until the
backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect).
@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect.
*/
void rcc_osc_bypass_enable(osc_t osc)
{
switch (osc) {
@@ -249,6 +338,19 @@ void rcc_osc_bypass_enable(osc_t osc)
}
}
/*-----------------------------------------------------------------------------*/
/** @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.
@note The LSE clock is in the backup domain and cannot have bypass removed until the
backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect)
or the backup domain has been reset (see @ref rcc_backupdomain_reset).
@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect.
*/
void rcc_osc_bypass_disable(osc_t osc)
{
switch (osc) {
@@ -266,18 +368,20 @@ void rcc_osc_bypass_disable(osc_t osc)
}
}
//-----------------------------------------------------------------------------
/** @brief RCC Enable a peripheral clock.
/*-----------------------------------------------------------------------------*/
/** @brief RCC Enable Peripheral Clocks.
Enable the clock on a particular peripheral. Several peripherals could be
enabled simultaneously if they are controlled by the same register.
Enable the clock on particular peripherals. There are three registers
involved, each one controlling the enabling of clocks associated with the AHB,
APB1 and APB2 respectively. Several peripherals could be
enabled simultaneously <em>only if they are controlled by the same register</em>.
@param[in] Unsigned int32 *reg. Pointer to a Clock Enable Register
(either RCC_AHBENR, RCC_APB1RENR or RCC_APB2RENR)
@param[in] Unsigned int32 en. OR of all enables to be set
@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register
(either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
@param[in] en Unsigned int32. Logical OR of all enables to be set
@li If register is RCC_AHBER, from @ref rcc_ahbenr_en
@li If register is RCC_APB1RENR, from @ref rcc_apb1enr_en
@li If register is RCC_APB2RENR, from @ref rcc_apb2enr_en
@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en
@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en
*/
void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en)
@@ -285,21 +389,75 @@ void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en)
*reg |= en;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Disable Peripheral Clocks.
Enable the clock on particular peripherals. There are three registers
involved, each one controlling the enabling of clocks associated with the AHB,
APB1 and APB2 respectively. Several peripherals could be
disabled simultaneously <em>only if they are controlled by the same register</em>.
@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register
(either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
@param[in] en Unsigned int32. Logical OR of all enables to be used for disabling.
@li If register is RCC_AHBER, from @ref rcc_ahbenr_en
@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en
@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en
*/
void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en)
{
*reg &= ~en;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Reset Peripherals.
Reset particular peripherals. There are three registers
involved, each one controlling reset of peripherals associated with the AHB,
APB1 and APB2 respectively. Several peripherals could be reset simultaneously
<em>only if they are controlled by the same register</em>.
@param[in] *reg Unsigned int32. Pointer to a Reset Register
(either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
@param[in] reset Unsigned int32. Logical OR of all resets.
@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst
@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst
@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst
*/
void rcc_peripheral_reset(volatile u32 *reg, u32 reset)
{
*reg |= reset;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Remove Reset on Peripherals.
Remove the reset on particular peripherals. There are three registers
involved, each one controlling reset of peripherals associated with the AHB,
APB1 and APB2 respectively. Several peripherals could have the reset removed
simultaneously <em>only if they are controlled by the same register</em>.
@param[in] *reg Unsigned int32. Pointer to a Reset Register
(either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
@param[in] clear_reset Unsigned int32. Logical OR of all resets to be removed:
@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst
@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst
@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst
*/
void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset)
{
*reg &= ~clear_reset;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the Source for the System Clock.
@param[in] clk Unsigned int32. System Clock Selection @ref rcc_cfgr_scs
*/
void rcc_set_sysclk_source(u32 clk)
{
u32 reg32;
@@ -309,6 +467,14 @@ void rcc_set_sysclk_source(u32 clk)
RCC_CFGR = (reg32 | clk);
}
/*-----------------------------------------------------------------------------*/
/** @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(u32 mul)
{
u32 reg32;
@@ -318,6 +484,14 @@ void rcc_set_pll_multiplication_factor(u32 mul)
RCC_CFGR = (reg32 | (mul << 18));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL Clock Source.
@note This only has effect when the PLL is disabled.
@param[in] pllsrc Unsigned int32. PLL clock source @ref rcc_cfgr_pcs
*/
void rcc_set_pll_source(u32 pllsrc)
{
u32 reg32;
@@ -327,6 +501,14 @@ void rcc_set_pll_source(u32 pllsrc)
RCC_CFGR = (reg32 | (pllsrc << 16));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the HSE Frequency Divider used as PLL Clock Source.
@note This only has effect when the PLL is disabled.
@param[in] pllxtpre Unsigned int32. HSE division factor @ref rcc_cfgr_hsepre
*/
void rcc_set_pllxtpre(u32 pllxtpre)
{
u32 reg32;
@@ -336,6 +518,14 @@ void rcc_set_pllxtpre(u32 pllxtpre)
RCC_CFGR = (reg32 | (pllxtpre << 17));
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Setup the A/D Clock
The ADC's have a common clock prescale setting.
@param[in] adcpre u32. Prescale divider taken from @ref rcc_cfgr_adcpre
*/
void rcc_set_adcpre(u32 adcpre)
{
u32 reg32;
@@ -345,6 +535,12 @@ void rcc_set_adcpre(u32 adcpre)
RCC_CFGR = (reg32 | (adcpre << 14));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the APB2 Prescale Factor.
@param[in] ppre2 Unsigned int32. APB2 prescale factor @ref rcc_cfgr_apb2pre
*/
void rcc_set_ppre2(u32 ppre2)
{
u32 reg32;
@@ -354,6 +550,14 @@ void rcc_set_ppre2(u32 ppre2)
RCC_CFGR = (reg32 | (ppre2 << 11));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the APB1 Prescale Factor.
@note The APB1 clock frequency must not exceed 36MHz.
@param[in] ppre1 Unsigned int32. APB1 prescale factor @ref rcc_cfgr_apb1pre
*/
void rcc_set_ppre1(u32 ppre1)
{
u32 reg32;
@@ -363,6 +567,12 @@ void rcc_set_ppre1(u32 ppre1)
RCC_CFGR = (reg32 | (ppre1 << 8));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the AHB Prescale Factor.
@param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre
*/
void rcc_set_hpre(u32 hpre)
{
u32 reg32;
@@ -372,6 +582,17 @@ void rcc_set_hpre(u32 hpre)
RCC_CFGR = (reg32 | (hpre << 4));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the USB Prescale Factor.
The prescale factor can be set to 1 (no prescale) for use when the PLL clock is
48MHz, or 1.5 to generate the 48MHz USB clock from a 64MHz PLL clock.
@note This bit cannot be reset while the USB clock is enabled.
@param[in] usbpre Unsigned int32. USB prescale factor @ref rcc_cfgr_usbpre
*/
void rcc_set_usbpre(u32 usbpre)
{
u32 reg32;
@@ -381,16 +602,31 @@ void rcc_set_usbpre(u32 usbpre)
RCC_CFGR = (reg32 | (usbpre << 22));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Get the System Clock Source.
@returns Unsigned int32. System clock source:
@li 00 indicates HSE
@li 01 indicates LSE
@li 02 indicates PLL
*/
u32 rcc_system_clock_source(void)
{
/* Return the clock source which is used as system clock. */
return ((RCC_CFGR & 0x000c) >> 2);
}
/*-----------------------------------------------------------------------------*/
/*
* These functions are setting up the whole clock system for the most common
* input clock and output clock configurations.
*/
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 64MHz from HSI
*/
void rcc_clock_setup_in_hsi_out_64mhz(void)
{
/* Enable internal high-speed oscillator. */
@@ -438,6 +674,11 @@ void rcc_clock_setup_in_hsi_out_64mhz(void)
rcc_ppre2_frequency = 64000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 48MHz from HSI
*/
void rcc_clock_setup_in_hsi_out_48mhz(void)
{
/* Enable internal high-speed oscillator. */
@@ -486,6 +727,11 @@ void rcc_clock_setup_in_hsi_out_48mhz(void)
rcc_ppre2_frequency = 48000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 24MHz from HSI
*/
void rcc_clock_setup_in_hsi_out_24mhz(void) {
/* Enable internal high-speed oscillator. */
rcc_osc_on(HSI);
@@ -532,6 +778,10 @@ void rcc_clock_setup_in_hsi_out_24mhz(void) {
rcc_ppre2_frequency = 24000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 24MHz from HSE at 8MHz
*/
void rcc_clock_setup_in_hse_8mhz_out_24mhz(void)
{
@@ -591,6 +841,11 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void)
rcc_ppre2_frequency = 24000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 72MHz from HSE at 8MHz
*/
void rcc_clock_setup_in_hse_8mhz_out_72mhz(void)
{
/* Enable internal high-speed oscillator. */
@@ -649,6 +904,11 @@ void rcc_clock_setup_in_hse_8mhz_out_72mhz(void)
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 24MHz from HSE at 12MHz
*/
void rcc_clock_setup_in_hse_12mhz_out_72mhz(void)
{
/* Enable internal high-speed oscillator. */
@@ -707,6 +967,11 @@ void rcc_clock_setup_in_hse_12mhz_out_72mhz(void)
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 24MHz from HSE at 16MHz
*/
void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
{
/* Enable internal high-speed oscillator. */
@@ -765,6 +1030,12 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Reset the backup domain
The backup domain register is reset to disable all controls.
*/
void rcc_backupdomain_reset(void)
{
/* Set the backup domain software reset. */
@@ -773,3 +1044,5 @@ void rcc_backupdomain_reset(void)
/* Clear the backup domain software reset. */
RCC_BDCR &= ~RCC_BDCR_BDRST;
}
/**@}*/

View File

@@ -1,4 +1,4 @@
/** @file
/** @defgroup STM32F1xx-timer-file Timers
@ingroup STM32F1xx
@@ -8,7 +8,7 @@
@author @htmlonly &copy; @endhtmlonly 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
@date 8 July 2012
@date 18 August 2012
This library supports the General Purpose and Advanced Control Timers for
the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics.
@@ -93,6 +93,8 @@ push-pull outputs where the PWM output will appear.
* TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP);
*/
/**@{*/
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/f1/rcc.h>
@@ -561,8 +563,8 @@ void timer_set_dma_on_update_event(u32 timer_peripheral)
/** @brief Enable Timer Capture/Compare Control Update with Trigger.
If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
preloaded, they are updated by software setting the COM bit (@ref ) or when a
rising edge occurs on the trigger input TRGI.
preloaded, they are updated by software generating the COMG event (@ref
timer_generate_event) or when a rising edge occurs on the trigger input TRGI.
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@@ -580,7 +582,8 @@ void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral)
/** @brief Disable Timer Capture/Compare Control Update with Trigger.
If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
preloaded, they are updated by software setting the COM bit (@ref ).
preloaded, they are updated by software generating the COMG event (@ref
timer_generate_event).
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@@ -1391,7 +1394,7 @@ the Break and Deadtime Register.
@note This setting is only valid for the advanced timers.
@note It is necessary to call this function to enable the output on an advanced
timer <b>even if break or deadtime features are not being used<\b>.
timer <b>even if break or deadtime features are not being used</b>.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
@@ -1681,24 +1684,24 @@ Set the input filter parameters for an input channel, specifying:
@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
*/
void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt)
void timer_ic_set_filter(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_filter flt)
{
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1F_MASK;
TIM_CCMR1(timer) |= flt << 4;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1F_MASK;
TIM_CCMR1(timer_peripheral) |= flt << 4;
break;
case TIM_IC2:
TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2F_MASK;
TIM_CCMR1(timer) |= flt << 12;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2F_MASK;
TIM_CCMR1(timer_peripheral) |= flt << 12;
break;
case TIM_IC3:
TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3F_MASK;
TIM_CCMR2(timer) |= flt << 4;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3F_MASK;
TIM_CCMR2(timer_peripheral) |= flt << 4;
break;
case TIM_IC4:
TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4F_MASK;
TIM_CCMR2(timer) |= flt << 12;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4F_MASK;
TIM_CCMR2(timer_peripheral) |= flt << 12;
break;
}
}
@@ -1713,24 +1716,24 @@ Set the number of events between each capture.
@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
*/
void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc)
void timer_ic_set_prescaler(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_psc psc)
{
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1PSC_MASK;
TIM_CCMR1(timer) |= psc << 2;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1PSC_MASK;
TIM_CCMR1(timer_peripheral) |= psc << 2;
break;
case TIM_IC2:
TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2PSC_MASK;
TIM_CCMR1(timer) |= psc << 10;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2PSC_MASK;
TIM_CCMR1(timer_peripheral) |= psc << 10;
break;
case TIM_IC3:
TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3PSC_MASK;
TIM_CCMR2(timer) |= psc << 4;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3PSC_MASK;
TIM_CCMR2(timer_peripheral) |= psc << 4;
break;
case TIM_IC4:
TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4PSC_MASK;
TIM_CCMR2(timer) |= psc << 10;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4PSC_MASK;
TIM_CCMR2(timer_peripheral) |= psc << 10;
break;
}
}
@@ -1756,7 +1759,7 @@ internal trigger input selected through TS bit
@param[in] in ::tim_ic_input. Input Capture channel direction and source input.
*/
void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in)
void timer_ic_set_input(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_input in)
{
in &= 3;
@@ -1768,20 +1771,20 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in)
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer) &= ~TIM_CCMR1_CC1S_MASK;
TIM_CCMR1(timer) |= in;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK;
TIM_CCMR1(timer_peripheral) |= in;
break;
case TIM_IC2:
TIM_CCMR1(timer) &= ~TIM_CCMR1_CC2S_MASK;
TIM_CCMR1(timer) |= in << 8;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK;
TIM_CCMR1(timer_peripheral) |= in << 8;
break;
case TIM_IC3:
TIM_CCMR2(timer) &= ~TIM_CCMR2_CC3S_MASK;
TIM_CCMR2(timer) |= in;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK;
TIM_CCMR2(timer_peripheral) |= in;
break;
case TIM_IC4:
TIM_CCMR2(timer) &= ~TIM_CCMR2_CC4S_MASK;
TIM_CCMR2(timer) |= in << 8;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK;
TIM_CCMR2(timer_peripheral) |= in << 8;
break;
}
}
@@ -1794,12 +1797,12 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in)
@param[in] pol ::tim_ic_pol. Input Capture polarity.
*/
void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol)
void timer_ic_set_polarity(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_pol pol)
{
if (pol)
TIM_CCER(timer) |= (0x2 << (ic * 4));
TIM_CCER(timer_peripheral) |= (0x2 << (ic * 4));
else
TIM_CCER(timer) &= ~(0x2 << (ic * 4));
TIM_CCER(timer_peripheral) &= ~(0x2 << (ic * 4));
}
/*---------------------------------------------------------------------------*/
@@ -1809,9 +1812,9 @@ void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol)
@param[in] ic ::tim_ic_id. Input Capture channel designator.
*/
void timer_ic_enable(u32 timer, enum tim_ic_id ic)
void timer_ic_enable(u32 timer_peripheral, enum tim_ic_id ic)
{
TIM_CCER(timer) |= (0x1 << (ic * 4));
TIM_CCER(timer_peripheral) |= (0x1 << (ic * 4));
}
/*---------------------------------------------------------------------------*/
@@ -1821,9 +1824,9 @@ void timer_ic_enable(u32 timer, enum tim_ic_id ic)
@param[in] ic ::tim_ic_id. Input Capture channel designator.
*/
void timer_ic_disable(u32 timer, enum tim_ic_id ic)
void timer_ic_disable(u32 timer_peripheral, enum tim_ic_id ic)
{
TIM_CCER(timer) &= ~(0x1 << (ic * 4));
TIM_CCER(timer_peripheral) &= ~(0x1 << (ic * 4));
}
/*---------------------------------------------------------------------------*/
@@ -1838,10 +1841,10 @@ Set the input filter parameters for the external trigger, specifying:
@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
*/
void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt)
void timer_slave_set_filter(u32 timer_peripheral, enum tim_ic_filter flt)
{
TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK;
TIM_SMCR(timer) |= flt << 8;
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETF_MASK;
TIM_SMCR(timer_peripheral) |= flt << 8;
}
/*---------------------------------------------------------------------------*/
@@ -1853,10 +1856,10 @@ Set the external trigger frequency division ratio.
@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
*/
void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc)
void timer_slave_set_prescaler(u32 timer_peripheral, enum tim_ic_psc psc)
{
TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK;
TIM_SMCR(timer) |= psc << 12;
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETPS_MASK;
TIM_SMCR(timer_peripheral) |= psc << 12;
}
/*---------------------------------------------------------------------------*/
@@ -1866,12 +1869,12 @@ void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc)
@param[in] pol ::tim_ic_pol. Input Capture polarity.
*/
void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol)
void timer_slave_set_polarity(u32 timer_peripheral, enum tim_ic_pol pol)
{
if (pol)
TIM_SMCR(timer) |= TIM_SMCR_ETP;
TIM_SMCR(timer_peripheral) |= TIM_SMCR_ETP;
else
TIM_SMCR(timer) &= ~TIM_SMCR_ETP;
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETP;
}
/*---------------------------------------------------------------------------*/
@@ -1881,10 +1884,10 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol)
@param[in] mode Unsigned int8. Slave mode @ref tim_sms
*/
void timer_slave_set_mode(u32 timer, u8 mode)
void timer_slave_set_mode(u32 timer_peripheral, u8 mode)
{
TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK;
TIM_SMCR(timer) |= mode;
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_SMS_MASK;
TIM_SMCR(timer_peripheral) |= mode;
}
/*---------------------------------------------------------------------------*/
@@ -1894,28 +1897,13 @@ void timer_slave_set_mode(u32 timer, u8 mode)
@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts
*/
void timer_slave_set_trigger(u32 timer, u8 trigger)
void timer_slave_set_trigger(u32 timer_peripheral, u8 trigger)
{
TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK;
TIM_SMCR(timer) |= trigger;
}
/*---------------------------------------------------------------------------*/
/** @brief Force Timer Event
A number of events can be forced by software action. All events are cleared by
hardware on completion.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] event Unsigned int8. Event identifier @ref tim_event_gen.
More than one event can be forced at the same time by logical OR of the event
identifiers.
*/
void timer_force_event(u32 timer, u8 event)
{
TIM_EGR(timer) = event;
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_TS_MASK;
TIM_SMCR(timer_peripheral) |= trigger;
}
/* TODO Timer DMA burst */
/**@}*/