libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
clk.c
Go to the documentation of this file.
1
/** @defgroup clk_file Clock peripheral API
2
* @ingroup peripheral_apis
3
* @brief SWM050 Clock API.
4
* LGPL License Terms @ref lgpl_license
5
* @author @htmlonly © @endhtmlonly 2019
6
* Caleb Szalacinski <contact@skiboy.net>
7
*/
8
/*
9
* This file is part of the libopencm3 project.
10
*
11
* Copyright (C) 2019 Caleb Szalacinski <contact@skiboy.net>
12
*
13
* This library is free software: you can redistribute it and/or modify
14
* it under the terms of the GNU Lesser General Public License as published by
15
* the Free Software Foundation, either version 3 of the License, or
16
* (at your option) any later version.
17
*
18
* This library is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU Lesser General Public License for more details.
22
*
23
* You should have received a copy of the GNU Lesser General Public License
24
* along with this library. If not, see <http://www.gnu.org/licenses/>.
25
*/
26
/**@{*/
27
#include <
libopencm3/swm050/clk.h
>
28
#include <
libopencm3/swm050/sysctl.h
>
29
30
/*---------------------------------------------------------------------------*/
31
/** @brief Setup and change the system clock multiplier and divider
32
33
Change system clock speed and wait for the clock to stabilize. The clock only
34
needs time to stabilize on the first invocation of this function. This should be
35
run at startup if you want to have a stable clock before doing anything.
36
37
@param[in] mhz Base clock speed @ref clk_speeds
38
The base clock speed, before the clock divider
39
40
@param[in] div Clock divider
41
Takes values from 0 to 1023 (in reality the possible values are the even
42
numbers from 2 to 1022, as well as the number 1). Anything more than the
43
first 10 bits is stripped off of the value. If the value is 0, it will
44
be treated as a 1. All odd values other than 1 are rounded down to the
45
closest even value, due to the fact that all odd values are treated by
46
the register as a 1, which would likely be unexpected. A value of 0
47
would also normally be treated as a 2, which would also be unexpected
48
behavior.
49
*/
50
void
clk_speed
(
enum
clk_speeds
mhz, uint16_t div)
51
{
52
static
bool
first_run =
true
;
53
54
if
(first_run) {
55
first_run =
false
;
56
clk_speed
(
CLK_18MHZ
, 1);
57
58
for
(uint16_t i = 0; i < 10000; ++i) {
59
__asm__(
"nop"
);
60
}
61
62
/* The speed doesn't need to be changed
63
a second time if the user wants 18Mhz. */
64
if
((mhz ==
CLK_18MHZ
) && (div <= 1)) {
65
return
;
66
}
67
if
((mhz ==
CLK_36MHZ
) && (div == 2)) {
68
return
;
69
}
70
}
71
72
if
(mhz ==
CLK_36MHZ
) {
73
SYSCTL_SYS_DBLF
|=
BIT0
;
74
}
else
{
75
SYSCTL_SYS_DBLF
&= ~BIT0;
76
}
77
78
if
(div <= 1) {
79
SYSCTL_SYS_CFG_0
|=
BIT0
;
80
}
else
{
81
uint32_t masked_reg32 =
SYSCTL_SYS_CFG_0
&
CLK_MASK
;
82
SYSCTL_SYS_CFG_0
= masked_reg32 | (div & ~(
CLK_MASK
| 0x1));
83
}
84
}
85
/**@}*/
clk.h
BIT0
#define BIT0
Definition:
common.h:81
clk_speed
void clk_speed(enum clk_speeds mhz, uint16_t div)
Setup and change the system clock multiplier and divider.
Definition:
clk.c:50
CLK_MASK
#define CLK_MASK
Definition:
clk.h:45
clk_speeds
clk_speeds
Definition:
clk.h:36
CLK_18MHZ
@ CLK_18MHZ
Definition:
clk.h:37
CLK_36MHZ
@ CLK_36MHZ
Definition:
clk.h:38
SYSCTL_SYS_CFG_0
#define SYSCTL_SYS_CFG_0
Clock dividers for TIMERSE and SCLK.
Definition:
sysctl.h:46
SYSCTL_SYS_DBLF
#define SYSCTL_SYS_DBLF
SCLK multiplier (18Mhz and 36Mhz)
Definition:
sysctl.h:50
sysctl.h
lib
swm050
clk.c
Generated on Tue Mar 7 2023 16:13:12 for libopencm3 by
1.9.4