-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy paths-stm32.adb
More file actions
132 lines (107 loc) · 5.32 KB
/
s-stm32.adb
File metadata and controls
132 lines (107 loc) · 5.32 KB
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
129
130
131
132
------------------------------------------------------------------------------
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
-- Copyright (C) 2012-2020, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
with Ada.Unchecked_Conversion;
with System.BB.Parameters;
with Interfaces; use Interfaces;
with Interfaces.STM32; use Interfaces.STM32;
with Interfaces.STM32.RCC; use Interfaces.STM32.RCC;
package body System.STM32 is
package Param renames System.BB.Parameters;
HPRE_Presc_Table : constant array (AHB_Prescaler_Enum) of UInt32 :=
(2, 4, 8, 16, 64, 128, 256, 512);
PPRE_Presc_Table : constant array (APB_Prescaler_Enum) of UInt32 :=
(2, 4, 8, 16);
-------------------
-- System_Clocks --
-------------------
function System_Clocks return RCC_System_Clocks
is
Source : constant SYSCLK_Source :=
SYSCLK_Source'Val (RCC_Periph.CFGR.SWS);
Result : RCC_System_Clocks;
begin
case Source is
-- HSI as source
when SYSCLK_SRC_HSI =>
Result.SYSCLK := Param.HSI_Clock;
-- HSE as source
when SYSCLK_SRC_HSE =>
Result.SYSCLK := Param.HSE_Clock;
-- PLL as source
when SYSCLK_SRC_PLL =>
declare
Pllm : constant UInt32 := UInt32 (RCC_Periph.PLLCFGR.PLLM);
Plln : constant UInt32 := UInt32 (RCC_Periph.PLLCFGR.PLLN);
Pllp : constant UInt32 := UInt32 (RCC_Periph.PLLCFGR.PLLP);
Pllvco : UInt32;
begin
case PLL_Source'Val (RCC_Periph.PLLCFGR.PLLSRC) is
when PLL_SRC_HSE =>
Pllvco := (Param.HSE_Clock / Pllm) * Plln;
when PLL_SRC_HSI =>
Pllvco := (Param.HSI_Clock / Pllm) * Plln;
end case;
Result.SYSCLK := Pllvco / ((Pllp + 1) * 2);
end;
end case;
declare
function To_AHBP is new Ada.Unchecked_Conversion
(CFGR_HPRE_Field, AHB_Prescaler);
function To_APBP is new Ada.Unchecked_Conversion
(CFGR_PPRE_Element, APB_Prescaler);
HPRE : constant AHB_Prescaler := To_AHBP (RCC_Periph.CFGR.HPRE);
HPRE_Div : constant UInt32 := (if HPRE.Enabled
then HPRE_Presc_Table (HPRE.Value)
else 1);
PPRE1 : constant APB_Prescaler :=
To_APBP (RCC_Periph.CFGR.PPRE.Arr (1));
PPRE1_Div : constant UInt32 := (if PPRE1.Enabled
then PPRE_Presc_Table (PPRE1.Value)
else 1);
PPRE2 : constant APB_Prescaler :=
To_APBP (RCC_Periph.CFGR.PPRE.Arr (2));
PPRE2_Div : constant UInt32 := (if PPRE2.Enabled
then PPRE_Presc_Table (PPRE2.Value)
else 1);
begin
Result.HCLK := Result.SYSCLK / HPRE_Div;
Result.PCLK1 := Result.HCLK / PPRE1_Div;
Result.PCLK2 := Result.HCLK / PPRE2_Div;
if not PPRE1.Enabled then
Result.TIMCLK1 := Result.PCLK1;
else
Result.TIMCLK1 := Result.PCLK1 * 2;
end if;
if not PPRE2.Enabled then
Result.TIMCLK2 := Result.PCLK2;
else
Result.TIMCLK2 := Result.PCLK2 * 2;
end if;
end;
return Result;
end System_Clocks;
end System.STM32;