kinetis: Simplify MCG state traversal algorithm
The new implementation uses a precalculated map of which mode to switch to next if going from mode A to mode B. This simplifies the implementation for moving between modes which are not direct neighbors. See mcg.h documentation for a diagram of the state machine for the clocking modes. Also found in the CPU reference manual of all Kinetis CPUs, MCG chapter, MCG mode state diagram.
This commit is contained in:
parent
f9ed160fe2
commit
a8450f2952
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 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 @@
|
|||||||
* @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,18 @@
|
|||||||
|
|
||||||
#if KINETIS_CPU_USE_MCG
|
#if KINETIS_CPU_USE_MCG
|
||||||
|
|
||||||
/* MCG neighbor modes matrix */
|
/* Pathfinding for the clocking modes, this table lists the next mode in the
|
||||||
static uint8_t mcg_pm[8] = {0x02, 0x15, 0x12, 0x20, 0xe6, 0xd8, 0xb0, 0xf0};
|
* 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;
|
||||||
|
|
||||||
@ -361,124 +373,39 @@ 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) {
|
|
||||||
kinetis_mcg_set_fei();
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_mode == KINETIS_MCG_BLPE) {
|
|
||||||
/* set PBE -> PEE */
|
|
||||||
kinetis_mcg_set_pbe();
|
|
||||||
kinetis_mcg_set_pee();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case KINETIS_MCG_PBE:
|
||||||
|
kinetis_mcg_set_pbe();
|
||||||
|
break;
|
||||||
case KINETIS_MCG_BLPE:
|
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();
|
kinetis_mcg_set_blpe();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_mode == KINETIS_MCG_FEE) {
|
|
||||||
/* set FBE -> BLPE */
|
|
||||||
kinetis_mcg_set_fbe();
|
|
||||||
kinetis_mcg_set_blpe();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KINETIS_MCG_BLPI:
|
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;
|
break;
|
||||||
|
case KINETIS_MCG_FBE:
|
||||||
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();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case KINETIS_MCG_FEI:
|
||||||
|
kinetis_mcg_set_fei();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* KINETIS_CPU_USE_MCG */
|
#endif /* KINETIS_CPU_USE_MCG */
|
||||||
|
/** @} */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user