mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 14:33:52 +01:00
cpu/stm32: add stm32mp1 support to clk_conf
clk_conf is a useful tool to produce clock headers for new boards.
But it only supports STM32Fx families.
This commits add the definition of a new family: STM32MP1.
Only the STM32MP157 is supported for now.
First build clk_conf:
$ make -C cpu/stm32/dist/clk_conf/
Clock header can be generated with the following command once clk_conf is
built:
$ cpu/stm32/dist/clk_conf/clk_conf stm32mp157 208000000 24000000 1
This command line will produce a core clock of 208MHz with a 24MHz HSE
oscillator and will use LSE clock which corresponds to the STM32MP157C-DK2
board configuration.
The command will output the header to copy paste into the periph_conf.h of
the board:
/**
* @name Clock settings
*
* @note This is auto-generated from
* `cpu/stm32/dist/clk_conf/clk_conf.c`
* @{
*/
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 209MHz */
#define CLOCK_CORECLOCK (208000000U)
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (24000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1U)
/* peripheral clock setup */
#define CLOCK_MCU_DIV RCC_MCUDIVR_MCUDIV_1 /* max 209MHz */
#define CLOCK_MCU (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_APB1DIVR_APB1DIV_2 /* max 104MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_APB2DIVR_APB2DIV_2 /* max 104MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB3_DIV RCC_APB3DIVR_APB3DIV_2 /* max 104MHz */
#define CLOCK_APB3 (CLOCK_CORECLOCK / 2)
/* Main PLL factors */
#define CLOCK_PLL_M (2)
#define CLOCK_PLL_N (52)
#define CLOCK_PLL_P (3)
#define CLOCK_PLL_Q (13)
/** @} */
This result has been verified with STM32CubeMX, the official ST tool.
Signed-off-by: Gilles DOFFE <gilles.doffe@savoirfairelinux.com>
This commit is contained in:
parent
5e30e60fec
commit
d78e13e906
57
cpu/stm32/dist/clk_conf/clk_conf.c
vendored
57
cpu/stm32/dist/clk_conf/clk_conf.c
vendored
@ -188,6 +188,10 @@ static void usage(char **argv)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int char_offset = 0;
|
||||
const unsigned int* stm32_model_p = stm32_f_model;
|
||||
const clk_cfg_t* stm32_clk_cfg_p = stm32_f_clk_cfg;
|
||||
int model_max = MODEL_F_MAX;
|
||||
if (argc < 2) {
|
||||
usage(argv);
|
||||
return 1;
|
||||
@ -199,23 +203,36 @@ int main(int argc, char **argv)
|
||||
|| !isdigit(argv[1][8])
|
||||
|| ((argv[1][5] != 'f') && (argv[1][5] != 'F')
|
||||
/* && (argv[1][5] != 'l') && (argv[1][5] != 'L') */)) {
|
||||
fprintf(stderr, "Invalid model : %s\n", argv[1]);
|
||||
return 1;
|
||||
if (strlen(argv[1]) < 10
|
||||
|| !isdigit(argv[1][7])
|
||||
|| !isdigit(argv[1][8])
|
||||
|| !isdigit(argv[1][9])
|
||||
|| ((argv[1][5] != 'm') && (argv[1][5] != 'M'))
|
||||
|| ((argv[1][6] != 'p') && (argv[1][5] != 'p'))
|
||||
) {
|
||||
fprintf(stderr, "Invalid model : %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char_offset = 1;
|
||||
stm32_model_p = stm32_model_mp;
|
||||
stm32_clk_cfg_p = stm32_mp_clk_cfg;
|
||||
model_max = MODEL_MP_MAX;
|
||||
}
|
||||
|
||||
int model = atoi(argv[1] + 6);
|
||||
int model = atoi(argv[1] + 6 + char_offset);
|
||||
int i;
|
||||
for (i = 0; i < MODEL_MAX; i++) {
|
||||
if (stm32_model[i] == model) {
|
||||
for (i = 0; i < model_max; i++) {
|
||||
if (stm32_model_p[i] == model) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == MODEL_MAX) {
|
||||
if (i == model_max) {
|
||||
fprintf(stderr, "Unsupported CPU model %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const clk_cfg_t *cfg = &stm32_clk_cfg[i];
|
||||
const clk_cfg_t *cfg = &stm32_clk_cfg_p[i];
|
||||
|
||||
/* print help for given cpu */
|
||||
if (argc < 5) {
|
||||
@ -399,6 +416,7 @@ int main(int argc, char **argv)
|
||||
/* APB prescalers */
|
||||
unsigned apb1_pre;
|
||||
unsigned apb2_pre;
|
||||
unsigned apb3_pre;
|
||||
|
||||
for (apb1_pre = 1; apb1_pre <= 16; apb1_pre <<= 1) {
|
||||
if (coreclock / apb1_pre <= cfg->max_apb1) {
|
||||
@ -412,6 +430,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg->family == STM32MP1) {
|
||||
for (apb3_pre = 1; apb3_pre <= 16; apb3_pre <<= 1) {
|
||||
if (coreclock / apb3_pre <= cfg->max_apb3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print constants */
|
||||
@ -435,14 +460,32 @@ int main(int argc, char **argv)
|
||||
" * 1: external crystal available (always 32.768kHz) */\n"
|
||||
"#define CLOCK_LSE (%uU)\n", is_lse);
|
||||
printf("/* peripheral clock setup */\n");
|
||||
|
||||
if (cfg->family != STM32MP1) {
|
||||
printf("#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1\n"
|
||||
"#define CLOCK_AHB (CLOCK_CORECLOCK / 1)\n");
|
||||
}
|
||||
if (cfg->family == STM32F0) {
|
||||
printf("#define CLOCK_APB1_DIV RCC_CFGR_PPRE_DIV%u /* max %uMHz */\n"
|
||||
"#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n",
|
||||
apb1_pre, cfg->max_apb1 / 1000000U, apb1_pre);
|
||||
printf("#define CLOCK_APB2 (CLOCK_APB1)\n");
|
||||
}
|
||||
else if (cfg->family == STM32MP1) {
|
||||
/* TODO: Set to 1 by default, conf_clk is not able to handle this parameter */
|
||||
printf("#define CLOCK_MCU_DIV RCC_MCUDIVR_MCUDIV_1 /* max %uMHz */\n"
|
||||
"#define CLOCK_MCU (CLOCK_CORECLOCK / 1)\n",
|
||||
cfg->max_coreclock / 1000000U);
|
||||
printf("#define CLOCK_APB1_DIV RCC_APB1DIVR_APB1DIV_%u /* max %uMHz */\n"
|
||||
"#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n",
|
||||
apb1_pre, cfg->max_apb1 / 1000000U, apb1_pre);
|
||||
printf("#define CLOCK_APB2_DIV RCC_APB2DIVR_APB2DIV_%u /* max %uMHz */\n"
|
||||
"#define CLOCK_APB2 (CLOCK_CORECLOCK / %u)\n",
|
||||
apb2_pre, cfg->max_apb2 / 1000000U, apb2_pre);
|
||||
printf("#define CLOCK_APB3_DIV RCC_APB3DIVR_APB3DIV_%u /* max %uMHz */\n"
|
||||
"#define CLOCK_APB3 (CLOCK_CORECLOCK / %u)\n",
|
||||
apb3_pre, cfg->max_apb3 / 1000000U, apb3_pre);
|
||||
}
|
||||
else {
|
||||
printf("#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV%u /* max %uMHz */\n"
|
||||
"#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n",
|
||||
|
||||
64
cpu/stm32/dist/clk_conf/clk_conf.h
vendored
64
cpu/stm32/dist/clk_conf/clk_conf.h
vendored
@ -35,6 +35,7 @@ enum fam {
|
||||
STM32F3,
|
||||
STM32F4,
|
||||
STM32F7,
|
||||
STM32MP1,
|
||||
FAM_MAX,
|
||||
};
|
||||
/** @} */
|
||||
@ -106,8 +107,15 @@ enum {
|
||||
STM32F777,
|
||||
STM32F779,
|
||||
|
||||
MODEL_MAX,
|
||||
MODEL_F_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
STM32MP157,
|
||||
|
||||
MODEL_MP_MAX,
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -167,6 +175,7 @@ typedef struct {
|
||||
unsigned max_coreclock; /**< Max coreclock */
|
||||
unsigned max_apb1; /**< Max APB1 clock */
|
||||
unsigned max_apb2; /**< Max APB2 clock */
|
||||
unsigned max_apb3; /**< Max APB3 clock */
|
||||
|
||||
unsigned hsi; /**< HSI frequency */
|
||||
|
||||
@ -200,7 +209,7 @@ typedef struct {
|
||||
#define STM32F0(x) [STM32F0##x] = x
|
||||
|
||||
/** List of supported models */
|
||||
static const unsigned stm32_model[] = {
|
||||
static const unsigned stm32_f_model[] = {
|
||||
STM32F0(30),
|
||||
STM32F0(70),
|
||||
STM32F0(31),
|
||||
@ -264,6 +273,13 @@ static const unsigned stm32_model[] = {
|
||||
STM32F(779),
|
||||
};
|
||||
|
||||
#define STM32MP(x) [STM32MP##x] = x
|
||||
|
||||
/** List of supported models */
|
||||
static const unsigned stm32_model_mp[] = {
|
||||
STM32MP(157),
|
||||
};
|
||||
|
||||
/** STM32F2xx / STM32F401 PLL config */
|
||||
#define stm32f2_4_192_pll_cfg { \
|
||||
.min_vco_input = 1000000U, \
|
||||
@ -304,10 +320,30 @@ static const unsigned stm32_model[] = {
|
||||
.inc_q = 1, \
|
||||
}
|
||||
|
||||
/** STM32MP1 PLL config */
|
||||
#define stm32mp1_pll_cfg { \
|
||||
.min_vco_input = 4000000U, \
|
||||
.max_vco_input = 16000000U, \
|
||||
.min_vco_output = 400000000U, \
|
||||
.max_vco_output = 800000000U, \
|
||||
.min_n = 25, \
|
||||
.max_n = 100, \
|
||||
.inc_n = 1, \
|
||||
.min_m = 2, \
|
||||
.max_m = 63, \
|
||||
.inc_m = 1, \
|
||||
.min_p = 2, \
|
||||
.max_p = 127, \
|
||||
.inc_p = 1, \
|
||||
.min_q = 2, \
|
||||
.max_q = 127, \
|
||||
.inc_q = 1, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clock config for supported cpu
|
||||
*/
|
||||
static const clk_cfg_t stm32_clk_cfg[] = {
|
||||
static const clk_cfg_t stm32_f_clk_cfg[] = {
|
||||
[STM32F030 ... STM32F098] = {
|
||||
.family = STM32F0,
|
||||
.max_coreclock = 48000000U,
|
||||
@ -595,6 +631,28 @@ static const clk_cfg_t stm32_clk_cfg[] = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Clock config for supported cpu
|
||||
*/
|
||||
static const clk_cfg_t stm32_mp_clk_cfg[] = {
|
||||
[STM32MP157] = {
|
||||
.family = STM32MP1,
|
||||
.max_coreclock = 209000000U,
|
||||
.max_apb1 = 104500000U,
|
||||
.max_apb2 = 104500000U,
|
||||
.max_apb3 = 104500000U,
|
||||
.hsi = 64000000U,
|
||||
.pll = stm32mp1_pll_cfg,
|
||||
.has_pll_i2s = false,
|
||||
.has_pll_sai = false,
|
||||
.has_pll_i2s_m = false,
|
||||
.has_pll_sai_m = false,
|
||||
.has_pll_i2s_alt_input = false,
|
||||
.has_alt_48MHz = 0,
|
||||
.need_48MHz = true,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user