Skip to content

Commit 7cc190a

Browse files
erwangogalak
authored andcommitted
drivers/clock_control: Add support to stm32wb series
Add support to stm32wb series in stm32 clock_control driver. Ip is similar to stm32l4 one but AHB bus presacler is renamed to "CPU1" and CPU2 and AHB4 prescalers should be defined. Signed-off-by: Erwan Gouriou <[email protected]>
1 parent c2dc17d commit 7cc190a

File tree

7 files changed

+149
-17
lines changed

7 files changed

+149
-17
lines changed

drivers/clock_control/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ if(CONFIG_CLOCK_CONTROL_STM32_CUBE)
1818
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F7X stm32f7x_ll_clock.c)
1919
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L0X stm32l0x_ll_clock.c)
2020
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L4X stm32l4x_ll_clock.c)
21+
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32WBX stm32wbx_ll_clock.c)
2122
endif()

drivers/clock_control/Kconfig.stm32

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ config CLOCK_STM32_SYSCLK_SRC_HSI
4242

4343
config CLOCK_STM32_SYSCLK_SRC_MSI
4444
bool "MSI"
45-
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X
45+
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
4646
help
4747
Use MSI as source of SYSCLK
4848

@@ -92,7 +92,7 @@ default CLOCK_STM32_PLL_SRC_HSI
9292

9393
config CLOCK_STM32_PLL_SRC_MSI
9494
bool "MSI"
95-
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X
95+
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
9696
help
9797
Use MSI as source of PLL
9898

@@ -321,7 +321,7 @@ config CLOCK_STM32_PLL_DIVISOR
321321

322322
endif # SOC_SERIES_STM32L0X
323323

324-
if SOC_SERIES_STM32L4X
324+
if SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
325325

326326
config CLOCK_STM32_PLL_M_DIVISOR
327327
int "PLL divisor"
@@ -377,12 +377,13 @@ config CLOCK_STM32_MSI_PLL_MODE
377377
help
378378
Enable hardware auto-calibration with LSE.
379379

380-
endif # SOC_SERIES_STM32L4X
380+
endif # SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
381381

382382
config CLOCK_STM32_AHB_PRESCALER
383383
int "AHB prescaler"
384384
default 1
385385
range 1 512
386+
depends on !SOC_SERIES_STM32WBX
386387
help
387388
AHB prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
388389
256, 512.
@@ -407,6 +408,34 @@ config CLOCK_STM32_APB2_PRESCALER
407408

408409
endif # SOC_SERIES_STM32F0X!=y
409410

411+
if SOC_SERIES_STM32WBX
412+
413+
config CLOCK_STM32_CPU1_PRESCALER
414+
int "CPU1 HCLK prescaler"
415+
default 1
416+
range 1 512
417+
help
418+
CPU1 HCLK prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
419+
256, 512.
420+
421+
config CLOCK_STM32_CPU2_PRESCALER
422+
int "CPU2 HCLK prescaler"
423+
default 1
424+
range 1 512
425+
help
426+
CPU2 HCLK prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
427+
256, 512.
428+
429+
config CLOCK_STM32_AHB4_PRESCALER
430+
int "AHB4 HCLK prescaler"
431+
default 1
432+
range 1 512
433+
help
434+
HCLK4 prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
435+
256, 512.
436+
437+
endif # SOC_SERIES_STM32WBX
438+
410439
choice
411440
prompt "STM32 MCO1 Clock Source"
412441
default CLOCK_STM32_MCO1_SRC_NOCLOCK

drivers/clock_control/stm32_ll_clock.c

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,30 @@
3131
#define z_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
3232
#define mco2_prescaler(v) z_mco2_prescaler(v)
3333

34+
#ifdef CONFIG_SOC_SERIES_STM32WBX
35+
#define __LL_RCC_CALC_HCLK_FREQ __LL_RCC_CALC_HCLK1_FREQ
36+
#endif /* CONFIG_SOC_SERIES_STM32F0X */
37+
3438
/**
3539
* @brief fill in AHB/APB buses configuration structure
3640
*/
3741
static void config_bus_clk_init(LL_UTILS_ClkInitTypeDef *clk_init)
3842
{
43+
#ifdef CONFIG_SOC_SERIES_STM32WBX
44+
clk_init->CPU1CLKDivider = ahb_prescaler(
45+
CONFIG_CLOCK_STM32_CPU1_PRESCALER);
46+
clk_init->CPU2CLKDivider = ahb_prescaler(
47+
CONFIG_CLOCK_STM32_CPU2_PRESCALER);
48+
clk_init->AHB4CLKDivider = ahb_prescaler(
49+
CONFIG_CLOCK_STM32_AHB4_PRESCALER);
50+
#else
3951
clk_init->AHBCLKDivider = ahb_prescaler(
4052
CONFIG_CLOCK_STM32_AHB_PRESCALER);
53+
#endif /* CONFIG_SOC_SERIES_STM32WBX */
54+
4155
clk_init->APB1CLKDivider = apb1_prescaler(
4256
CONFIG_CLOCK_STM32_APB1_PRESCALER);
57+
4358
#ifndef CONFIG_SOC_SERIES_STM32F0X
4459
clk_init->APB2CLKDivider = apb2_prescaler(
4560
CONFIG_CLOCK_STM32_APB2_PRESCALER);
@@ -65,7 +80,8 @@ static inline int stm32_clock_control_on(struct device *dev,
6580
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
6681
defined(CONFIG_SOC_SERIES_STM32F4X) || \
6782
defined(CONFIG_SOC_SERIES_STM32F7X) || \
68-
defined(CONFIG_SOC_SERIES_STM32F2X)
83+
defined(CONFIG_SOC_SERIES_STM32F2X) || \
84+
defined(CONFIG_SOC_SERIES_STM32WBX)
6985
case STM32_CLOCK_BUS_AHB2:
7086
LL_AHB2_GRP1_EnableClock(pclken->enr);
7187
break;
@@ -74,7 +90,9 @@ static inline int stm32_clock_control_on(struct device *dev,
7490
case STM32_CLOCK_BUS_APB1:
7591
LL_APB1_GRP1_EnableClock(pclken->enr);
7692
break;
77-
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
93+
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
94+
defined(CONFIG_SOC_SERIES_STM32F0X) || \
95+
defined(CONFIG_SOC_SERIES_STM32WBX)
7896
case STM32_CLOCK_BUS_APB1_2:
7997
LL_APB1_GRP2_EnableClock(pclken->enr);
8098
break;
@@ -120,7 +138,9 @@ static inline int stm32_clock_control_off(struct device *dev,
120138
case STM32_CLOCK_BUS_APB1:
121139
LL_APB1_GRP1_DisableClock(pclken->enr);
122140
break;
123-
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
141+
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
142+
defined(CONFIG_SOC_SERIES_STM32F0X) || \
143+
defined(CONFIG_SOC_SERIES_STM32WBX)
124144
case STM32_CLOCK_BUS_APB1_2:
125145
LL_APB1_GRP2_DisableClock(pclken->enr);
126146
break;
@@ -173,9 +193,11 @@ static int stm32_clock_control_get_subsys_rate(struct device *clock,
173193
*rate = ahb_clock;
174194
break;
175195
case STM32_CLOCK_BUS_APB1:
176-
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
196+
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
197+
defined(CONFIG_SOC_SERIES_STM32F0X) || \
198+
defined(CONFIG_SOC_SERIES_STM32WBX)
177199
case STM32_CLOCK_BUS_APB1_2:
178-
#endif /* CONFIG_SOC_SERIES_STM32L4X || CONFIG_SOC_SERIES_STM32F0X */
200+
#endif
179201
*rate = apb1_clock;
180202
break;
181203
#ifndef CONFIG_SOC_SERIES_STM32F0X
@@ -238,12 +260,20 @@ static inline void stm32_clock_control_mco_init(void)
238260
static int stm32_clock_control_init(struct device *dev)
239261
{
240262
LL_UTILS_ClkInitTypeDef s_ClkInitStruct;
263+
u32_t hclk_prescaler;
241264

242265
ARG_UNUSED(dev);
243266

244267
/* configure clock for AHB/APB buses */
245268
config_bus_clk_init((LL_UTILS_ClkInitTypeDef *)&s_ClkInitStruct);
246269

270+
/* update local hclk prescaler variable */
271+
#ifdef CONFIG_SOC_SERIES_STM32WBX
272+
hclk_prescaler = s_ClkInitStruct.CPU1CLKDivider;
273+
#else
274+
hclk_prescaler = s_ClkInitStruct.AHBCLKDivider;
275+
#endif /* CONFIG_SOC_SERIES_STM32WBX */
276+
247277
/* Some clocks would be activated by default */
248278
config_enable_default_clocks();
249279

@@ -302,9 +332,13 @@ static int stm32_clock_control_init(struct device *dev)
302332
#endif /* CONFIG_CLOCK_STM32_HSE_BYPASS */
303333

304334
/* Switch to PLL with HSE as clock source */
305-
LL_PLL_ConfigSystemClock_HSE(CONFIG_CLOCK_STM32_HSE_CLOCK, hse_bypass,
306-
&s_PLLInitStruct,
307-
&s_ClkInitStruct);
335+
LL_PLL_ConfigSystemClock_HSE(
336+
#ifndef CONFIG_SOC_SERIES_STM32WBX
337+
CONFIG_CLOCK_STM32_HSE_CLOCK,
338+
#endif
339+
hse_bypass,
340+
&s_PLLInitStruct,
341+
&s_ClkInitStruct);
308342

309343
/* Disable other clocks */
310344
LL_RCC_HSI_Disable();
@@ -332,14 +366,14 @@ static int stm32_clock_control_init(struct device *dev)
332366

333367
/* Set HSE as SYSCLCK source */
334368
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
335-
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
369+
LL_RCC_SetAHBPrescaler(hclk_prescaler);
336370
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
337371
}
338372

339373
/* Update SystemCoreClock variable */
340374
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(
341375
CONFIG_CLOCK_STM32_HSE_CLOCK,
342-
s_ClkInitStruct.AHBCLKDivider));
376+
hclk_prescaler));
343377

344378
/* Set APB1 & APB2 prescaler*/
345379
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
@@ -377,7 +411,7 @@ static int stm32_clock_control_init(struct device *dev)
377411

378412
/* Set MSI as SYSCLCK source */
379413
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
380-
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
414+
LL_RCC_SetAHBPrescaler(hclk_prescaler);
381415
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
382416
}
383417

@@ -389,6 +423,11 @@ static int stm32_clock_control_init(struct device *dev)
389423
/* Set APB1 & APB2 prescaler*/
390424
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
391425
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
426+
#ifdef CONFIG_SOC_SERIES_STM32WBX
427+
/* Set C2 AHB & AHB4 prescalers */
428+
LL_C2_RCC_SetAHBPrescaler(s_ClkInitStruct->CPU2CLKDivider);
429+
LL_RCC_SetAHB4Prescaler(s_ClkInitStruct->AHB4CLKDivider);
430+
#endif /* CONFIG_SOC_SERIES_STM32WBX */
392431

393432
/* Set flash latency */
394433
/* MSI used as SYSCLK (16MHz), set latency to 0 */
@@ -401,11 +440,11 @@ static int stm32_clock_control_init(struct device *dev)
401440

402441
#elif CONFIG_CLOCK_STM32_SYSCLK_SRC_HSI
403442

404-
stm32_clock_switch_to_hsi(s_ClkInitStruct.AHBCLKDivider);
443+
stm32_clock_switch_to_hsi(hclk_prescaler);
405444

406445
/* Update SystemCoreClock variable */
407446
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(HSI_VALUE,
408-
s_ClkInitStruct.AHBCLKDivider));
447+
hclk_prescaler));
409448

410449
/* Set APB1 & APB2 prescaler*/
411450
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
*
3+
* Copyright (c) 2019 Linaro Limited.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
9+
#include <soc.h>
10+
#include <soc_registers.h>
11+
#include <clock_control.h>
12+
#include <misc/util.h>
13+
#include <clock_control/stm32_clock_control.h>
14+
#include "stm32_ll_clock.h"
15+
16+
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
17+
18+
/* Macros to fill up division factors values */
19+
#define _pllm(v) LL_RCC_PLLM_DIV_ ## v
20+
#define pllm(v) _pllm(v)
21+
22+
#define _pllr(v) LL_RCC_PLLR_DIV_ ## v
23+
#define pllr(v) _pllr(v)
24+
25+
26+
/**
27+
* @brief fill in pll configuration structure
28+
*/
29+
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
30+
{
31+
pllinit->PLLM = pllm(CONFIG_CLOCK_STM32_PLL_M_DIVISOR);
32+
pllinit->PLLN = CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER;
33+
pllinit->PLLR = pllr(CONFIG_CLOCK_STM32_PLL_R_DIVISOR);
34+
}
35+
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */
36+
37+
/**
38+
* @brief Activate default clocks
39+
*/
40+
void config_enable_default_clocks(void)
41+
{
42+
/* Nothing for now */
43+
}

dts/arm/st/wb/stm32wb.dtsi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@
3838
label = "FLASH_STM32";
3939
};
4040
};
41+
42+
rcc: rcc@58000000 {
43+
compatible = "st,stm32-rcc";
44+
clocks-controller;
45+
#clock-cells = <2>;
46+
reg = <0x58000000 0x400>;
47+
label = "STM32_CLK_RCC";
48+
};
4149
};
4250
};
4351

soc/arm/st_stm32/stm32wb/Kconfig.series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ config SOC_SERIES_STM32WBX
1313
select HAS_STM32CUBE
1414
select CPU_HAS_ARM_MPU
1515
select CPU_HAS_SYSTICK
16+
select CLOCK_CONTROL_STM32_CUBE if CLOCK_CONTROL
1617
help
1718
Enable support for STM32WB MCU series

soc/arm/st_stm32/stm32wb/soc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
/**
88
* @file SoC configuration macros for the STM32WB family processors.
99
*
10+
* Based on reference manual:
11+
* TODO: Provide reference when known
12+
*
13+
* Chapter 2.2.2: Memory map and register boundary addresses
1014
*/
1115

1216

@@ -23,6 +27,13 @@
2327
*/
2428
#include <kernel_includes.h>
2529

30+
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
31+
#include <stm32wbxx_ll_utils.h>
32+
#include <stm32wbxx_ll_bus.h>
33+
#include <stm32wbxx_ll_rcc.h>
34+
#include <stm32wbxx_ll_system.h>
35+
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
36+
2637
#endif /* !_ASMLANGUAGE */
2738

2839
#endif /* _STM32WBX_SOC_H_ */

0 commit comments

Comments
 (0)