libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
rcc_common_all.c
Go to the documentation of this file.
1/** @addtogroup rcc_file RCC peripheral API
2 * @ingroup peripheral_apis
3 */
4/*
5 * This file is part of the libopencm3 project.
6 *
7 * Copyright (C) 2013 Frantisek Burian <bufran@seznam.cz>
8 * .. file is merged from many other copyrighted files of stm32 family
9 *
10 * This library is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library. If not, see <http://www.gnu.org/licenses/>.
22 */
23/**@{*/
24
26
27/*---------------------------------------------------------------------------*/
28/** @brief RCC Enable Peripheral Clocks.
29 *
30 * Enable the clock on particular peripherals. There are three registers
31 * involved, each one controlling the enabling of clocks associated with the
32 * AHB, APB1 and APB2 respectively. Several peripherals could be enabled
33 * simultaneously <em>only if they are controlled by the same register</em>.
34 * @sa rcc_periph_clock_enable for a less error prone version, if you only
35 * need to enable a single peripheral.
36 *
37 * @param[in] *reg Unsigned int32. Pointer to a Clock Enable Register
38 * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
39 *
40 * @param[in] en Unsigned int32. Logical OR of all enables to be set
41 * @li If register is RCC_AHBENR, from @ref rcc_ahbenr_en
42 * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en
43 * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en
44 */
45
46void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en)
47{
48 *reg |= en;
49}
50
51/*---------------------------------------------------------------------------*/
52/** @brief RCC Disable Peripheral Clocks.
53 *
54 * Disable the clock on particular peripherals. There are three registers
55 * involved, each one controlling the enabling of clocks associated with
56 * the AHB, APB1 and APB2 respectively. Several peripherals could be disabled
57 * simultaneously <em>only if they are controlled by the same register</em>.
58 * @sa rcc_periph_clock_disable for a less error prone version, if you only
59 * need to disable a single peripheral.
60 *
61 * @param[in] *reg Unsigned int32. Pointer to a Clock Enable Register
62 * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
63 * @param[in] en Unsigned int32. Logical OR of all enables to be used for
64 * disabling.
65 * @li If register is RCC_AHBENR, from @ref rcc_ahbenr_en
66 * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en
67 * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en
68 */
69void rcc_peripheral_disable_clock(volatile uint32_t *reg, uint32_t en)
70{
71 *reg &= ~en;
72}
73
74/*---------------------------------------------------------------------------*/
75/** @brief RCC Reset Peripherals.
76 *
77 * Reset particular peripherals. There are three registers involved, each one
78 * controlling reset of peripherals associated with the AHB, APB1 and APB2
79 * respectively. Several peripherals could be reset simultaneously <em>only if
80 * they are controlled by the same register</em>.
81 * @sa rcc_periph_reset_hold for a less error prone version, if you only
82 * need to reset a single peripheral.
83 * @sa rcc_periph_reset_pulse if you are only going to toggle reset anyway.
84 *
85 * @param[in] *reg Unsigned int32. Pointer to a Reset Register
86 * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
87 * @param[in] reset Unsigned int32. Logical OR of all resets.
88 * @li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst
89 * @li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst
90 * @li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst
91 */
92void rcc_peripheral_reset(volatile uint32_t *reg, uint32_t reset)
93{
94 *reg |= reset;
95}
96
97/*---------------------------------------------------------------------------*/
98/** @brief RCC Remove Reset on Peripherals.
99 *
100 * Remove the reset on particular peripherals. There are three registers
101 * involved, each one controlling reset of peripherals associated with the AHB,
102 * APB1 and APB2 respectively. Several peripherals could have the reset removed
103 * simultaneously <em>only if they are controlled by the same register</em>.
104 * @sa rcc_periph_reset_release for a less error prone version, if you only
105 * need to unreset a single peripheral.
106 * @sa rcc_periph_reset_pulse if you are only going to toggle reset anyway.
107 *
108 * @param[in] *reg Unsigned int32. Pointer to a Reset Register
109 * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR)
110 * @param[in] clear_reset Unsigned int32. Logical OR of all resets to be
111 * removed:
112 * @li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst
113 * @li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst
114 * @li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst
115 */
116void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset)
117{
118 *reg &= ~clear_reset;
119}
120
121#define _RCC_REG(i) MMIO32(RCC_BASE + ((i) >> 5))
122#define _RCC_BIT(i) (1 << ((i) & 0x1f))
123
124/*---------------------------------------------------------------------------*/
125/** @brief Enable Peripheral Clock in running mode.
126 *
127 * Enable the clock on particular peripheral.
128 *
129 * @param[in] clken rcc_periph_clken Peripheral RCC
130 *
131 * For available constants, see #rcc_periph_clken (RCC_UART1 for example)
132 */
133
135{
136 _RCC_REG(clken) |= _RCC_BIT(clken);
137}
138
139/*---------------------------------------------------------------------------*/
140/** @brief Disable Peripheral Clock in running mode.
141 * Disable the clock on particular peripheral.
142 *
143 * @param[in] clken rcc_periph_clken Peripheral RCC
144 *
145 * For available constants, see #rcc_periph_clken (RCC_UART1 for example)
146 */
147
149{
150 _RCC_REG(clken) &= ~_RCC_BIT(clken);
151}
152
153/*---------------------------------------------------------------------------*/
154/** @brief Reset Peripheral, pulsed
155 *
156 * Reset particular peripheral, and restore to working state.
157 *
158 * @param[in] rst rcc_periph_rst Peripheral reset
159 *
160 * For available constants, see #rcc_periph_rst (RST_UART1 for example)
161 */
162
164{
165 _RCC_REG(rst) |= _RCC_BIT(rst);
166 _RCC_REG(rst) &= ~_RCC_BIT(rst);
167}
168
169/*---------------------------------------------------------------------------*/
170/** @brief Reset Peripheral, hold
171 *
172 * Reset particular peripheral, and hold in reset state.
173 *
174 * @param[in] rst rcc_periph_rst Peripheral reset
175 *
176 * For available constants, see #rcc_periph_rst (RST_UART1 for example)
177 */
178
180{
181 _RCC_REG(rst) |= _RCC_BIT(rst);
182}
183
184/*---------------------------------------------------------------------------*/
185/** @brief Reset Peripheral, release
186 *
187 * Restore peripheral from reset state to working state.
188 *
189 * @param[in] rst rcc_periph_rst Peripheral reset
190 *
191 * For available constants, see #rcc_periph_rst (RST_UART1 for example)
192 */
193
195{
196 _RCC_REG(rst) &= ~_RCC_BIT(rst);
197}
198
199/** @brief Select the source of Microcontroller Clock Output
200 *
201 * Exact sources available depend on your target. On devices with multiple
202 * MCO pins, this function controls MCO1
203 *
204 * @param[in] mcosrc the unshifted source bits
205 */
206
207void rcc_set_mco(uint32_t mcosrc)
208{
210 (mcosrc << RCC_CFGR_MCO_SHIFT);
211}
212
213/**
214 * RCC Enable Bypass.
215 * Enable an external clock to bypass the internal clock (high speed and low
216 * speed clocks only). The external clock must be enabled (see @ref rcc_osc_on)
217 * and the internal clock must be disabled (see @ref rcc_osc_off) for this to
218 * have effect.
219 * @note The LSE clock is in the backup domain and cannot be bypassed until the
220 * backup domain write protection has been removed (see @ref
221 * pwr_disable_backup_domain_write_protect).
222 * @param[in] osc Oscillator ID. Only HSE and LSE have effect.
223 */
225{
226 switch (osc) {
227 case RCC_HSE:
229 break;
230 case RCC_LSE:
231#ifdef RCC_CSR_LSEBYP
232 RCC_CSR |= RCC_CSR_LSEBYP;
233#else
235#endif
236 break;
237 default:
238 /* Do nothing, only HSE/LSE allowed here. */
239 break;
240 }
241}
242
243/**
244 * RCC Disable Bypass.
245 * Re-enable the internal clock (high speed and low speed clocks only). The
246 * internal clock must be disabled (see @ref rcc_osc_off) for this to have
247 * effect.
248 * @note The LSE clock is in the backup domain and cannot have bypass removed
249 * until the backup domain write protection has been removed (see @ref
250 * pwr_disable_backup_domain_write_protect) or the backup domain has been reset
251 * (see @ref rcc_backupdomain_reset).
252 * @param[in] osc Oscillator ID. Only HSE and LSE have effect.
253 */
255{
256 switch (osc) {
257 case RCC_HSE:
258 RCC_CR &= ~RCC_CR_HSEBYP;
259 break;
260 case RCC_LSE:
261#ifdef RCC_CSR_LSEBYP
262 RCC_CSR &= ~RCC_CSR_LSEBYP;
263#else
264 RCC_BDCR &= ~RCC_BDCR_LSEBYP;
265#endif
266 break;
267 default:
268 /* Do nothing, only HSE/LSE allowed here. */
269 break;
270 }
271}
272
273/* This is a helper to calculate dividers that go 2/4/8/16/64/128/256/512.
274 * These dividers also use the top bit as an "enable". This is typically
275 * used for AHB and other system clock prescaler. */
276uint16_t rcc_get_div_from_hpre(uint8_t div_val) {
277 if (div_val < 0x8) {
278 return 1;
279 } else if (div_val <= 0x0b /* DIV16 */) {
280 return (1U << (div_val - 7));
281 } else {
282 return (1U << (div_val - 6));
283 }
284}
285/**@}*/
286
287#undef _RCC_REG
288#undef _RCC_BIT
#define RCC_CFGR_MCO_SHIFT
Definition: f0/rcc.h:97
#define RCC_CR
Definition: f0/rcc.h:48
rcc_periph_rst
Definition: f0/rcc.h:506
#define RCC_BDCR_LSEBYP
Definition: f0/rcc.h:330
rcc_periph_clken
Definition: f0/rcc.h:448
rcc_osc
Definition: f0/rcc.h:442
#define RCC_CSR
Definition: f0/rcc.h:57
#define RCC_CFGR
Definition: f0/rcc.h:49
#define RCC_CR_HSEBYP
Definition: f0/rcc.h:72
#define RCC_BDCR
Definition: f0/rcc.h:56
#define RCC_CFGR_MCO_MASK
Definition: f0/rcc.h:98
@ RCC_LSE
Definition: f0/rcc.h:443
@ RCC_HSE
Definition: f0/rcc.h:443
void rcc_periph_reset_release(enum rcc_periph_rst rst)
Reset Peripheral, release.
#define _RCC_REG(i)
void rcc_peripheral_reset(volatile uint32_t *reg, uint32_t reset)
RCC Reset Peripherals.
void rcc_osc_bypass_enable(enum rcc_osc osc)
RCC Enable Bypass.
void rcc_osc_bypass_disable(enum rcc_osc osc)
RCC Disable Bypass.
void rcc_periph_reset_hold(enum rcc_periph_rst rst)
Reset Peripheral, hold.
void rcc_periph_clock_disable(enum rcc_periph_clken clken)
Disable Peripheral Clock in running mode.
void rcc_periph_clock_enable(enum rcc_periph_clken clken)
Enable Peripheral Clock in running mode.
#define _RCC_BIT(i)
void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en)
RCC Enable Peripheral Clocks.
void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset)
RCC Remove Reset on Peripherals.
void rcc_set_mco(uint32_t mcosrc)
Select the source of Microcontroller Clock Output.
void rcc_periph_reset_pulse(enum rcc_periph_rst rst)
Reset Peripheral, pulsed.
void rcc_peripheral_disable_clock(volatile uint32_t *reg, uint32_t en)
RCC Disable Peripheral Clocks.
uint16_t rcc_get_div_from_hpre(uint8_t div_val)
This will return the divisor 1/2/4/8/16/64/128/256/512 which is set as a 4-bit value,...