1
0
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:
Gilles DOFFE 2019-11-07 00:10:45 +01:00
parent 5e30e60fec
commit d78e13e906
2 changed files with 111 additions and 10 deletions

View File

@ -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",

View File

@ -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