1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#ifndef CORE_CLOCK_H__
#define CORE_CLOCK_H__
#include <stdint.h>
#include "arch/stm32l4xxx/peripherals/rcc.h"
#define PERIPH_BASE ((uint32_t)0x40000000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000)
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x00003C00)
#define PWR_BASE (PERIPH_BASE + 0x7000)
#define PWR_CSR_VOSF ((uint16_t)0x0010) /*!< Voltage Scaling select flag */
#ifndef __IO
#define __IO volatile
#endif
typedef struct {
__IO uint32_t cr;
__IO uint32_t csr;
} pwr_t;
// typedef struct {
// __IO uint32_t acr;
// __IO uint32_t pecr;
// __IO uint32_t pdkeyr;
// __IO uint32_t pekeyr;
// __IO uint32_t prgkeyr;
// __IO uint32_t optkeyr;
// __IO uint32_t sr;
// __IO uint32_t obr;
// __IO uint32_t wrpr;
// } flash_t;
// #define FLASH (*(flash_t*) (FLASH_R_BASE))
#define PWR (*(pwr_t*)(PWR_BASE))
/* Valid values for the PLLR/PLLQ bits of the PLLCFG register. */
typedef enum {
PLL_DIVISOR_2 = 1,
PLL_DIVISOR_4 = 3,
PLL_DIVISOR_6 = 5,
PLL_DIVISOR_8 = 7,
PLL_DIVISOR_OFF = 0,
} pll_divisor_t;
/* Valid values for the PLLP bits off the PLLCFG register. */
typedef enum {
PLLP_DIVISOR_7 = 1,
PLLP_DIVISOR_17 = 3,
PLLP_DIVISOR_OFF = 0,
} pllp_divisor_t;
/* Valid values for the PLLM bits of the PLLCFG register. */
typedef enum {
PLLM_DIVISOR_1 = 0,
PLLM_DIVISOR_2 = 1,
PLLM_DIVISOR_3 = 2,
PLLM_DIVISOR_4 = 3,
PLLM_DIVISOR_5 = 4,
PLLM_DIVISOR_6 = 5,
PLLM_DIVISOR_7 = 6,
PLLM_DIVISOR_8 = 7,
} pllm_divisor_t;
/* Possible sources for the input clock. */
typedef enum {
PLL_SRC_NONE = 0,
PLL_SRC_MSI = 1,
PLL_SRC_HSI = 2,
PLL_SRC_HSE = 3,
} pll_src_t;
/* Valid sources for the system clock. */
typedef enum {
SYSTEM_CLOCK_SRC_MSI = 0,
SYSTEM_CLOCK_SRC_HSI = 1,
SYSTEM_CLOCK_SRC_HSE = 2,
SYSTEM_CLOCK_SRC_PLL = 3,
} system_clock_src_t;
#define E_BADPLLN (-2)
#define E_BADPLLP_DIV (-1)
#define E_TIMEOUT (-3)
#define E_NOT_OFF (-4)
#define E_BAD_ARG (-5)
#define enable_hsi(rcc, enabled) do { \
if (enabled) { \
(rcc)->c_r |= BIT(8); \
} else { \
(rcc)->c_r &= ~BIT(8); \
} \
} while(0)
/*
* Sets the system clock to a full 80Mhz.
*/
int set_system_clock_MHz(uint8_t mhz);
/*
* Set the PLL on.
*/
int pll_on();
/*
* Set the PLL off.
*/
int pll_off();
/*
* Sets the source of the system clock.
*/
int set_system_clock_src(system_clock_src_t src);
/*
* Configure the PLL.
*/
int configure_pll(
uint8_t pllp_div_factor, pll_divisor_t pllr, /* System clock divisor. */
pll_divisor_t pllq, /* Divison factor for PLL48M1CLK. */
pllp_divisor_t pllp, /* Divison factor for PLLSAI2CLK. */
uint8_t plln, /* PLL numerator. */
pllm_divisor_t pllm, /* PLL denominator. */
pll_src_t pllsrc /* PLL source */);
uint8_t get_clock_mhz();
#endif /* CORE_CLOCK_H__ */
|