Skip to content

Commit 96497d3

Browse files
committed
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 10246f2 commit 96497d3

File tree

7 files changed

+151
-17
lines changed

7 files changed

+151
-17
lines changed

drivers/clock_control/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ if(CONFIG_CLOCK_CONTROL_STM32_CUBE)
1616
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F7X stm32f7x_ll_clock.c)
1717
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L0X stm32l0x_ll_clock.c)
1818
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L4X stm32l4x_ll_clock.c)
19+
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32WBX stm32wbx_ll_clock.c)
1920
endif()

drivers/clock_control/Kconfig.stm32

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

4444
config CLOCK_STM32_SYSCLK_SRC_MSI
4545
bool "MSI"
46-
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X
46+
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
4747
help
4848
Use MSI as source of SYSCLK
4949

@@ -93,7 +93,7 @@ default CLOCK_STM32_PLL_SRC_HSI
9393

9494
config CLOCK_STM32_PLL_SRC_MSI
9595
bool "MSI"
96-
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X
96+
depends on SOC_SERIES_STM32L0X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
9797
help
9898
Use MSI as source of PLL
9999

@@ -322,7 +322,7 @@ config CLOCK_STM32_PLL_DIVISOR
322322

323323
endif # SOC_SERIES_STM32L0X
324324

325-
if SOC_SERIES_STM32L4X
325+
if SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
326326

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

381-
endif # SOC_SERIES_STM32L4X
381+
endif # SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX
382382

383383
config CLOCK_STM32_AHB_PRESCALER
384384
int "AHB prescaler"
385385
default 1
386386
range 1 512
387+
depends on !SOC_SERIES_STM32WBX
387388
help
388389
AHB prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
389390
256, 512.
@@ -408,6 +409,34 @@ config CLOCK_STM32_APB2_PRESCALER
408409

409410
endif # SOC_SERIES_STM32F0X!=y
410411

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

drivers/clock_control/stm32_ll_clock.c

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,30 @@
3131
#define _mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
3232
#define mco2_prescaler(v) _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

@@ -273,6 +303,7 @@ static int stm32_clock_control_init(struct device *dev)
273303
#endif /* CONFIG_CLOCK_STM32_PLL_Q_DIVISOR */
274304

275305
#ifdef CONFIG_CLOCK_STM32_PLL_SRC_MSI
306+
276307
/* Switch to PLL with MSI as clock source */
277308
LL_PLL_ConfigSystemClock_MSI(&s_PLLInitStruct, &s_ClkInitStruct);
278309

@@ -296,9 +327,13 @@ static int stm32_clock_control_init(struct device *dev)
296327
#endif /* CONFIG_CLOCK_STM32_HSE_BYPASS */
297328

298329
/* Switch to PLL with HSE as clock source */
299-
LL_PLL_ConfigSystemClock_HSE(CONFIG_CLOCK_STM32_HSE_CLOCK, hse_bypass,
300-
&s_PLLInitStruct,
301-
&s_ClkInitStruct);
330+
LL_PLL_ConfigSystemClock_HSE(
331+
#ifndef CONFIG_SOC_SERIES_STM32WBX
332+
CONFIG_CLOCK_STM32_HSE_CLOCK,
333+
#endif
334+
hse_bypass,
335+
&s_PLLInitStruct,
336+
&s_ClkInitStruct);
302337

303338
/* Disable other clocks */
304339
LL_RCC_HSI_Disable();
@@ -326,14 +361,14 @@ static int stm32_clock_control_init(struct device *dev)
326361

327362
/* Set HSE as SYSCLCK source */
328363
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
329-
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
364+
LL_RCC_SetAHBPrescaler(hclk_prescaler);
330365
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
331366
}
332367

333368
/* Update SystemCoreClock variable */
334369
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(
335370
CONFIG_CLOCK_STM32_HSE_CLOCK,
336-
s_ClkInitStruct.AHBCLKDivider));
371+
hclk_prescaler));
337372

338373
/* Set APB1 & APB2 prescaler*/
339374
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
@@ -371,7 +406,7 @@ static int stm32_clock_control_init(struct device *dev)
371406

372407
/* Set MSI as SYSCLCK source */
373408
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
374-
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
409+
LL_RCC_SetAHBPrescaler(hclk_prescaler);
375410
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
376411
}
377412

@@ -383,6 +418,11 @@ static int stm32_clock_control_init(struct device *dev)
383418
/* Set APB1 & APB2 prescaler*/
384419
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
385420
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
421+
#ifdef CONFIG_SOC_SERIES_STM32WBX
422+
/* Set C2 AHB & AHB4 prescalers */
423+
LL_C2_RCC_SetAHBPrescaler(s_ClkInitStruct->CPU2CLKDivider);
424+
LL_RCC_SetAHB4Prescaler(s_ClkInitStruct->AHB4CLKDivider);
425+
#endif /* CONFIG_SOC_SERIES_STM32WBX */
386426

387427
/* Set flash latency */
388428
/* MSI used as SYSCLK (16MHz), set latency to 0 */
@@ -395,11 +435,11 @@ static int stm32_clock_control_init(struct device *dev)
395435

396436
#elif CONFIG_CLOCK_STM32_SYSCLK_SRC_HSI
397437

398-
stm32_clock_switch_to_hsi(s_ClkInitStruct.AHBCLKDivider);
438+
stm32_clock_switch_to_hsi(hclk_prescaler);
399439

400440
/* Update SystemCoreClock variable */
401441
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(HSI_VALUE,
402-
s_ClkInitStruct.AHBCLKDivider));
442+
hclk_prescaler));
403443

404444
/* Set APB1 & APB2 prescaler*/
405445
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@
3939
};
4040
};
4141

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+
};
49+
};
50+
4251
};
4352
};
4453

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)