Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RIOT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cm-projects
RIOT
Commits
5f0b8e5b
Commit
5f0b8e5b
authored
7 years ago
by
Francisco Acosta
Committed by
GitHub
7 years ago
Browse files
Options
Downloads
Plain Diff
Merge pull request #6978 from gebart/pr/kinetis-mcg
kinetis: MCG improvements
parents
863bda7b
8efb714e
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
cpu/kinetis_common/include/mcg.h
+26
-1
26 additions, 1 deletion
cpu/kinetis_common/include/mcg.h
cpu/kinetis_common/periph/mcg.c
+64
-124
64 additions, 124 deletions
cpu/kinetis_common/periph/mcg.c
with
90 additions
and
125 deletions
cpu/kinetis_common/include/mcg.h
+
26
−
1
View file @
5f0b8e5b
...
@@ -10,7 +10,8 @@
...
@@ -10,7 +10,8 @@
* @defgroup cpu_kinetis_common_mcg Kinetis MCG
* @defgroup cpu_kinetis_common_mcg Kinetis MCG
* @ingroup cpu_kinetis_common
* @ingroup cpu_kinetis_common
* @brief Implementation of the Kinetis Multipurpose Clock Generator
* @brief Implementation of the Kinetis Multipurpose Clock Generator
* (MCG) driver.
* (MCG) driver
*
* Please add mcg.h in cpu conf.h
* Please add mcg.h in cpu conf.h
* and MCG configuration to periph_conf.h
* and MCG configuration to periph_conf.h
*
*
...
@@ -37,6 +38,30 @@
...
@@ -37,6 +38,30 @@
* - BLPE -> FEE
* - BLPE -> FEE
* - BLPI -> FEE
* - BLPI -> FEE
*
*
* \dot
* digraph states {
* layout=dot
* nodesep=0.5
* {rank=same Reset [shape=none] FEI FEE}
* {rank=same FBI FBE}
* {rank=same BLPI BLPE}
* Reset -> FEI
* FEI -> FEE [dir="both"]
* FEI -> FBE [dir="both"]
* FEI -> FBI [dir="both"]
* FEE -> FBI [dir="both"]
* FEE -> FBE [dir="both"]
* FBI -> FBE [dir="both"]
* FBI -> BLPI [dir="both"]
* FBE -> BLPE [dir="both"]
* PBE
* PEE
* FBE -> PBE [dir="both"]
* BLPE -> PBE [dir="both"]
* PBE -> PEE [dir="both"]
* }
* \enddot
*
* ### MCG Configuration Examples (for periph_conf.h) ###
* ### MCG Configuration Examples (for periph_conf.h) ###
*
*
* Example for FEI Mode (MCGOUTCLK = 20MHz ... 25MHz):
* Example for FEI Mode (MCGOUTCLK = 20MHz ... 25MHz):
...
...
This diff is collapsed.
Click to expand it.
cpu/kinetis_common/periph/mcg.c
+
64
−
124
View file @
5f0b8e5b
/*
/*
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
* Copyright (C) 2017 Eistec AB
*
*
* This file is subject to the terms and conditions of the GNU Lesser General
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* Public License v2.1. See the file LICENSE in the top level directory for more
...
@@ -14,7 +15,8 @@
...
@@ -14,7 +15,8 @@
* @brief Implementation of the Kinetis Multipurpose Clock Generator
* @brief Implementation of the Kinetis Multipurpose Clock Generator
*
*
* @author Johann Fischer <j.fischer@phytec.de>
* @author Johann Fischer <j.fischer@phytec.de>
* @}
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*
*/
*/
#include
<stdint.h>
#include
<stdint.h>
...
@@ -23,8 +25,24 @@
...
@@ -23,8 +25,24 @@
#if KINETIS_CPU_USE_MCG
#if KINETIS_CPU_USE_MCG
/* MCG neighbor modes matrix */
#if defined(MCG_C6_PLLS_MASK)
static
uint8_t
mcg_pm
[
8
]
=
{
0x02
,
0x15
,
0x12
,
0x20
,
0xe6
,
0xd8
,
0xb0
,
0xf0
};
#define KINETIS_HAVE_PLL 1
#else
#define KINETIS_HAVE_PLL 0
#endif
/* Pathfinding for the clocking modes, this table lists the next mode in the
* chain when moving from mode <first> to mode <second> */
static
const
uint8_t
mcg_mode_routing
[
8
][
8
]
=
{
{
0
,
1
,
1
,
1
,
1
,
1
,
1
,
1
},
/* from PEE */
{
0
,
1
,
2
,
4
,
4
,
4
,
4
,
4
},
/* from PBE */
{
1
,
1
,
2
,
4
,
4
,
4
,
4
,
4
},
/* from BLPE */
{
5
,
5
,
5
,
3
,
5
,
5
,
5
,
5
},
/* from BLPI */
{
1
,
1
,
2
,
5
,
4
,
5
,
6
,
7
},
/* from FBE */
{
4
,
4
,
4
,
3
,
4
,
5
,
6
,
7
},
/* from FBI */
{
4
,
4
,
4
,
5
,
4
,
5
,
6
,
7
},
/* from FEE */
{
4
,
4
,
4
,
5
,
4
,
5
,
6
,
7
},
/* from FEI */
};
static
uint8_t
current_mode
=
KINETIS_MCG_FEI
;
static
uint8_t
current_mode
=
KINETIS_MCG_FEI
;
...
@@ -97,6 +115,7 @@ static uint8_t current_mode = KINETIS_MCG_FEI;
...
@@ -97,6 +115,7 @@ static uint8_t current_mode = KINETIS_MCG_FEI;
#error "KINETIS_MCG_ERC_RANGE not defined in periph_conf.h"
#error "KINETIS_MCG_ERC_RANGE not defined in periph_conf.h"
#endif
#endif
#if KINETIS_HAVE_PLL
#ifndef KINETIS_MCG_PLL_PRDIV
#ifndef KINETIS_MCG_PLL_PRDIV
#error "KINETIS_MCG_PLL_PRDIV not defined in periph_conf.h"
#error "KINETIS_MCG_PLL_PRDIV not defined in periph_conf.h"
#endif
#endif
...
@@ -118,6 +137,9 @@ static inline void kinetis_mcg_disable_pll(void)
...
@@ -118,6 +137,9 @@ static inline void kinetis_mcg_disable_pll(void)
MCG
->
C5
=
(
uint8_t
)
0
;
MCG
->
C5
=
(
uint8_t
)
0
;
MCG
->
C6
=
(
uint8_t
)
0
;
MCG
->
C6
=
(
uint8_t
)
0
;
}
}
#else
static
inline
void
kinetis_mcg_disable_pll
(
void
)
{}
#endif
/* KINETIS_HAVE_PLL */
/**
/**
* @brief Set Frequency Locked Loop (FLL) factor.
* @brief Set Frequency Locked Loop (FLL) factor.
...
@@ -161,7 +183,7 @@ static void kinetis_mcg_enable_osc(void)
...
@@ -161,7 +183,7 @@ static void kinetis_mcg_enable_osc(void)
MCG
->
C2
|=
(
uint8_t
)(
MCG_C2_EREFS0_MASK
);
MCG
->
C2
|=
(
uint8_t
)(
MCG_C2_EREFS0_MASK
);
/* wait fo OSC initialization */
/* wait fo OSC initialization */
while
((
MCG
->
S
&
MCG_S_OSCINIT0_MASK
)
==
0
)
;
while
((
MCG
->
S
&
MCG_S_OSCINIT0_MASK
)
==
0
)
{}
}
}
}
}
...
@@ -182,10 +204,10 @@ static void kinetis_mcg_set_fei(void)
...
@@ -182,10 +204,10 @@ static void kinetis_mcg_set_fei(void)
MCG
->
C2
=
(
uint8_t
)
0
;
MCG
->
C2
=
(
uint8_t
)
0
;
/* source of the FLL reference clock shall be internal reference clock */
/* source of the FLL reference clock shall be internal reference clock */
while
((
MCG
->
S
&
MCG_S_IREFST_MASK
)
==
0
)
;
while
((
MCG
->
S
&
MCG_S_IREFST_MASK
)
==
0
)
{}
/* Wait until output of the FLL is selected */
/* Wait until output of the FLL is selected */
while
(
MCG
->
S
&
(
MCG_S_CLKST_MASK
))
;
while
(
MCG
->
S
&
(
MCG_S_CLKST_MASK
))
{}
kinetis_mcg_disable_pll
();
kinetis_mcg_disable_pll
();
current_mode
=
KINETIS_MCG_FEI
;
current_mode
=
KINETIS_MCG_FEI
;
...
@@ -207,7 +229,7 @@ static void kinetis_mcg_set_fee(void)
...
@@ -207,7 +229,7 @@ static void kinetis_mcg_set_fee(void)
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
0
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
0
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
/* Wait until output of FLL is selected */
/* Wait until output of FLL is selected */
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
0
))
;
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
0
))
{}
kinetis_mcg_disable_pll
();
kinetis_mcg_disable_pll
();
current_mode
=
KINETIS_MCG_FEE
;
current_mode
=
KINETIS_MCG_FEE
;
...
@@ -237,10 +259,10 @@ static void kinetis_mcg_set_fbi(void)
...
@@ -237,10 +259,10 @@ static void kinetis_mcg_set_fbi(void)
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
1
)
|
MCG_C1_IREFS_MASK
);
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
1
)
|
MCG_C1_IREFS_MASK
);
/* Wait until output of IRC is selected */
/* Wait until output of IRC is selected */
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
1
))
;
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
1
))
{}
/* source of the FLL reference clock shall be internal reference clock */
/* source of the FLL reference clock shall be internal reference clock */
while
((
MCG
->
S
&
MCG_S_IREFST_MASK
)
==
0
)
;
while
((
MCG
->
S
&
MCG_S_IREFST_MASK
)
==
0
)
{}
kinetis_mcg_disable_pll
();
kinetis_mcg_disable_pll
();
current_mode
=
KINETIS_MCG_FBI
;
current_mode
=
KINETIS_MCG_FBI
;
...
@@ -266,7 +288,7 @@ static void kinetis_mcg_set_fbe(void)
...
@@ -266,7 +288,7 @@ static void kinetis_mcg_set_fbe(void)
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
2
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
2
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
/* Wait until ERC is selected */
/* Wait until ERC is selected */
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
2
))
;
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
2
))
{}
kinetis_mcg_disable_pll
();
kinetis_mcg_disable_pll
();
current_mode
=
KINETIS_MCG_FBE
;
current_mode
=
KINETIS_MCG_FBE
;
...
@@ -299,6 +321,7 @@ static void kinetis_mcg_set_blpe(void)
...
@@ -299,6 +321,7 @@ static void kinetis_mcg_set_blpe(void)
current_mode
=
KINETIS_MCG_BLPE
;
current_mode
=
KINETIS_MCG_BLPE
;
}
}
#if KINETIS_HAVE_PLL
/**
/**
* @brief Initialize the PLL Bypassed External Mode.
* @brief Initialize the PLL Bypassed External Mode.
*
*
...
@@ -315,7 +338,7 @@ static void kinetis_mcg_set_pbe(void)
...
@@ -315,7 +338,7 @@ static void kinetis_mcg_set_pbe(void)
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
2
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
MCG
->
C1
=
(
uint8_t
)(
MCG_C1_CLKS
(
2
)
|
MCG_C1_FRDIV
(
KINETIS_MCG_ERC_FRDIV
));
/* Wait until ERC is selected */
/* Wait until ERC is selected */
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
2
))
;
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
2
))
{}
/* PLL is not disabled in bypass mode */
/* PLL is not disabled in bypass mode */
MCG
->
C2
&=
~
(
uint8_t
)(
MCG_C2_LP_MASK
);
MCG
->
C2
&=
~
(
uint8_t
)(
MCG_C2_LP_MASK
);
...
@@ -330,10 +353,10 @@ static void kinetis_mcg_set_pbe(void)
...
@@ -330,10 +353,10 @@ static void kinetis_mcg_set_pbe(void)
MCG
->
C6
|=
(
uint8_t
)(
MCG_C6_PLLS_MASK
);
MCG
->
C6
|=
(
uint8_t
)(
MCG_C6_PLLS_MASK
);
/* Wait until the source of the PLLS clock is PLL */
/* Wait until the source of the PLLS clock is PLL */
while
((
MCG
->
S
&
MCG_S_PLLST_MASK
)
==
0
)
;
while
((
MCG
->
S
&
MCG_S_PLLST_MASK
)
==
0
)
{}
/* Wait until PLL locked */
/* Wait until PLL locked */
while
((
MCG
->
S
&
MCG_S_LOCK0_MASK
)
==
0
)
;
while
((
MCG
->
S
&
MCG_S_LOCK0_MASK
)
==
0
)
{}
current_mode
=
KINETIS_MCG_PBE
;
current_mode
=
KINETIS_MCG_PBE
;
}
}
...
@@ -350,135 +373,52 @@ static void kinetis_mcg_set_pee(void)
...
@@ -350,135 +373,52 @@ static void kinetis_mcg_set_pee(void)
MCG
->
C1
&=
~
(
uint8_t
)(
MCG_C1_CLKS_MASK
);
MCG
->
C1
&=
~
(
uint8_t
)(
MCG_C1_CLKS_MASK
);
/* Wait until output of the PLL is selected */
/* Wait until output of the PLL is selected */
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
3
))
;
while
((
MCG
->
S
&
MCG_S_CLKST_MASK
)
!=
MCG_S_CLKST
(
3
))
{}
current_mode
=
KINETIS_MCG_PEE
;
current_mode
=
KINETIS_MCG_PEE
;
}
}
#endif
/* KINETIS_HAVE_PLL */
int
kinetis_mcg_set_mode
(
kinetis_mcg_mode_t
mode
)
int
kinetis_mcg_set_mode
(
kinetis_mcg_mode_t
mode
)
{
{
if
(
mode
>
KINETIS_MCG_FEI
)
{
if
(
mode
>
KINETIS_MCG_FEI
)
{
return
-
1
;
return
-
1
;
}
}
while
(
current_mode
!=
mode
)
{
if
(
mcg_pm
[
current_mode
]
&
(
1
<<
mode
))
{
switch
(
mcg_mode_routing
[
current_mode
][
mode
])
{
if
(
mode
==
KINETIS_MCG_FEI
)
{
#if KINETIS_HAVE_PLL
kinetis_mcg_set_fei
();
case
KINETIS_MCG_PEE
:
}
if
(
mode
==
KINETIS_MCG_FBI
)
{
kinetis_mcg_set_fbi
();
}
if
(
mode
==
KINETIS_MCG_FEE
)
{
kinetis_mcg_set_fee
();
}
if
(
mode
==
KINETIS_MCG_FBE
)
{
kinetis_mcg_set_fbe
();
}
if
(
mode
==
KINETIS_MCG_BLPI
)
{
kinetis_mcg_set_blpi
();
}
if
(
mode
==
KINETIS_MCG_BLPE
)
{
kinetis_mcg_set_blpe
();
}
if
(
mode
==
KINETIS_MCG_PBE
)
{
kinetis_mcg_set_pbe
();
}
if
(
mode
==
KINETIS_MCG_PEE
)
{
kinetis_mcg_set_pee
();
}
return
0
;
}
switch
(
mode
)
{
case
KINETIS_MCG_PEE
:
/* cppcheck-suppress duplicateExpression */
if
(
!
(
KINETIS_MCG_USE_ERC
||
KINETIS_MCG_USE_PLL
))
{
return
-
1
;
}
if
(
current_mode
==
KINETIS_MCG_FEI
)
{
/* set FBE -> PBE -> PEE */
kinetis_mcg_set_fbe
();
kinetis_mcg_set_pbe
();
kinetis_mcg_set_pee
();
kinetis_mcg_set_pee
();
return
0
;
break
;
}
case
KINETIS_MCG_PBE
:
if
(
current_mode
==
KINETIS_MCG_BLPE
)
{
/* set PBE -> PEE */
kinetis_mcg_set_pbe
();
kinetis_mcg_set_pbe
();
kinetis_mcg_set_pee
();
break
;
return
0
;
#endif
/* KINETIS_HAVE_PLL */
}
case
KINETIS_MCG_BLPE
:
break
;
case
KINETIS_MCG_BLPE
:
if
(
!
KINETIS_MCG_USE_ERC
)
{
return
-
1
;
}
if
(
current_mode
==
KINETIS_MCG_PEE
)
{
/* set PBE -> BLPE */
kinetis_mcg_set_pbe
();
kinetis_mcg_set_blpe
();
return
0
;
}
if
(
current_mode
==
KINETIS_MCG_FEE
)
{
/* set FBE -> BLPE */
kinetis_mcg_set_fbe
();
kinetis_mcg_set_blpe
();
kinetis_mcg_set_blpe
();
return
0
;
break
;
}
case
KINETIS_MCG_BLPI
:
break
;
case
KINETIS_MCG_BLPI
:
if
(
current_mode
==
KINETIS_MCG_FEE
)
{
/* set FBI -> BLPI */
kinetis_mcg_set_fbi
();
kinetis_mcg_set_blpi
();
kinetis_mcg_set_blpi
();
return
0
;
break
;
}
case
KINETIS_MCG_FBE
:
break
;
case
KINETIS_MCG_FEE
:
if
(
!
KINETIS_MCG_USE_ERC
)
{
return
-
1
;
}
if
(
current_mode
==
KINETIS_MCG_BLPE
)
{
/* set FBE -> FEE */
kinetis_mcg_set_fbe
();
kinetis_mcg_set_fbe
();
kinetis_mcg_set_fee
();
break
;
return
0
;
case
KINETIS_MCG_FBI
:
}
if
(
current_mode
==
KINETIS_MCG_BLPI
)
{
/* set FBI -> FEE */
kinetis_mcg_set_fbi
();
kinetis_mcg_set_fbi
();
break
;
case
KINETIS_MCG_FEE
:
kinetis_mcg_set_fee
();
kinetis_mcg_set_fee
();
re
turn
0
;
b
re
ak
;
}
case
KINETIS_MCG_FEI
:
kinetis_mcg_set_fei
();
break
;
break
;
default:
default:
return
-
1
;
break
;
}
}
}
return
-
1
;
return
0
;
}
}
#endif
/* KINETIS_CPU_USE_MCG */
#endif
/* KINETIS_CPU_USE_MCG */
/** @} */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment