Skip to content

Commit 17fcb33

Browse files
FRASTMnashif
authored andcommitted
samples: boards: stm32 mco output control
This sample enables and configures the MCO1/2 output for stm32 target boards. MCO_PRE_DIV_n is defined by the stm32XX_clock.h Signed-off-by: Francois Ramu <francois.ramu@st.com>
1 parent a103d63 commit 17fcb33

File tree

7 files changed

+86
-24
lines changed

7 files changed

+86
-24
lines changed

samples/boards/st/mco/README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ Requirements
1616
The SoC should support MCO functionality and use a pin that has the MCO alternate function.
1717
To support another board, add a dts overlay file in boards folder.
1818
Make sure that the output clock is enabled in dts overlay file.
19+
Depending on the stm32 serie, several clock source and prescaler are possible for each MCOx.
20+
The clock source is set by the DTS among the possible values for each stm32 serie.
21+
The prescaler is set by the DTS, through the property ``prescaler = <MCOx_PRE(MCO_PRE_DIV_n)>;``
22+
23+
See :zephyr_file:`dts/bindings/clock/st,stm32-clock-mco.yaml`
24+
25+
It is required to check the Reference Manual to configure the DTS correctly.
1926

2027

2128
Building and Running
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Enable the PLLI2s and set it as clock source for the MCO2 (with prescaler 5) */
2+
3+
&plli2s {
4+
div-m = <8>;
5+
mul-n = <100>;
6+
div-r = <2>;
7+
clocks = <&clk_hse>;
8+
status = "okay";
9+
};
10+
11+
/* see RefMan RM0383 */
12+
&mco1 {
13+
/* Select One of the line below for clock source */
14+
clocks = <&rcc STM32_SRC_HSI MCO1_SEL(0)>;
15+
/* clocks = <&rcc STM32_SRC_LSE MCO1_SEL(1)>; */
16+
/* clocks = <&rcc STM32_SRC_HSE MCO1_SEL(2)>; */
17+
/* clocks = <&rcc STM32_SRC_PLL_P MCO1_SEL(3)>; */
18+
prescaler = <MCO1_PRE(MCO_PRE_DIV_2)>;
19+
pinctrl-0 = <&rcc_mco_1_pa8>;
20+
pinctrl-names = "default";
21+
status = "okay";
22+
};
23+
24+
&mco2 {
25+
clocks = <&rcc STM32_SRC_PLLI2S_R MCO2_SEL(1)>;
26+
prescaler = <MCO2_PRE(MCO_PRE_DIV_5)>;
27+
pinctrl-0 = <&rcc_mco_2_pc9>;
28+
pinctrl-names = "default";
29+
status = "okay";
30+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Enable the PLLI2s and set it as clock source for the MCO2 (with prescaler 2) : 25MHz */
2+
3+
&plli2s {
4+
div-m = <8>;
5+
mul-n = <100>;
6+
div-r = <2>;
7+
clocks = <&clk_hse>;
8+
status = "okay";
9+
};
10+
11+
/* see RefMan RM0390 */
12+
&mco1 {
13+
/* Select One of the line below for clock source */
14+
/* clocks = <&rcc STM32_SRC_HSI MCO1_SEL(0)>; */
15+
/* clocks = <&rcc STM32_SRC_LSE MCO1_SEL(1)>; */
16+
clocks = <&rcc STM32_SRC_HSE MCO1_SEL(2)>;
17+
/* clocks = <&rcc STM32_SRC_PLL_P MCO1_SEL(3)>;*/
18+
prescaler = <MCO1_PRE(MCO_PRE_DIV_1)>;
19+
pinctrl-0 = <&rcc_mco_1_pa8>;
20+
pinctrl-names = "default";
21+
status = "okay";
22+
};
23+
24+
&mco2 {
25+
clocks = <&rcc STM32_SRC_PLLI2S_R MCO2_SEL(1)>;
26+
prescaler = <MCO2_PRE(MCO_PRE_DIV_2)>;
27+
pinctrl-0 = <&rcc_mco_2_pc9>;
28+
pinctrl-names = "default";
29+
status = "okay";
30+
};

samples/boards/st/mco/boards/nucleo_u5a5zj_q.overlay

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,10 @@
88
*/
99
#define MCO1_SEL_LSE 7
1010

11-
/* See reference manual (RM0456):
12-
* 0b001: MCO divided by 2
13-
*/
14-
#define MCO1_PRE_DIV_2 1
15-
1611
&mco1 {
1712
status = "okay";
1813
clocks = <&rcc STM32_SRC_LSE MCO1_SEL(MCO1_SEL_LSE)>;
19-
prescaler = <MCO1_PRE(MCO1_PRE_DIV_2)>;
14+
prescaler = <MCO1_PRE(MCO_PRE_DIV_2)>;
2015
pinctrl-0 = <&rcc_mco_pa8>;
2116
pinctrl-names = "default";
2217
};

samples/boards/st/mco/boards/stm32f746g_disco.overlay

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,10 @@
1212
*/
1313
#define MCO1_SEL_LSE 1
1414

15-
/* See reference manual (RM0385):
16-
* 0b100: division by 2
17-
*/
18-
#define MCO1_PRE_DIV_2 4
19-
2015
&mco1 {
2116
status = "okay";
2217
clocks = <&rcc STM32_SRC_LSE MCO1_SEL(MCO1_SEL_LSE)>;
23-
prescaler = <MCO1_PRE(MCO1_PRE_DIV_2)>;
18+
prescaler = <MCO1_PRE(MCO_PRE_DIV_2)>;
2419
pinctrl-0 = <&rcc_mco_1_pa8>; /* D10 (CN7) */
2520
pinctrl-names = "default";
2621
};
@@ -30,15 +25,10 @@
3025
*/
3126
#define MCO2_SEL_HSE 2
3227

33-
/* See reference manual (RM0385):
34-
* 0b111: division by 5
35-
*/
36-
#define MCO2_PRE_DIV_5 7
37-
3828
&mco2 {
3929
status = "okay";
4030
clocks = <&rcc STM32_SRC_HSE MCO2_SEL(MCO2_SEL_HSE)>;
41-
prescaler = <MCO2_PRE(MCO2_PRE_DIV_5)>;
31+
prescaler = <MCO2_PRE(MCO_PRE_DIV_5)>;
4232
pinctrl-0 = <&rcc_mco_2_pc9>; /* uSD_D1 (CN3 pin 8) */
4333
pinctrl-names = "default";
4434
};

samples/boards/st/mco/sample.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ sample:
33
tests:
44
sample.board.stm32.mco:
55
platform_allow:
6+
- nucleo_f411re
7+
- nucleo_f446ze
8+
- stm32f746g_disco
69
- nucleo_u5a5zj_q
10+
integration_platforms:
711
- stm32f746g_disco
812
tags: board

samples/boards/st/mco/src/main.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,37 @@
99

1010
int main(void)
1111
{
12-
const struct device *dev;
1312

1413
/* This sample demonstrates MCO usage via Device Tree.
1514
* MCO configuration is performed in the Device Tree overlay files.
1615
* Each MCO will be enabled automatically by the driver during device
1716
* initialization. This sample checks that all MCOs are ready - if so,
1817
* the selected clock should be visible on the chosen GPIO pin.
1918
*/
20-
dev = DEVICE_DT_GET(DT_NODELABEL(mco1));
21-
if (device_is_ready(dev)) {
19+
20+
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mco1))
21+
const struct device *dev1;
22+
23+
dev1 = DEVICE_DT_GET(DT_NODELABEL(mco1));
24+
if (device_is_ready(dev1)) {
2225
printk("MCO1 device successfully configured\n");
2326
} else {
2427
printk("MCO1 device not ready\n");
2528
return -1;
2629
}
30+
#endif /* mco1 */
2731

2832
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mco2))
29-
dev = DEVICE_DT_GET(DT_NODELABEL(mco2));
30-
if (device_is_ready(dev)) {
33+
const struct device *dev2;
34+
35+
dev2 = DEVICE_DT_GET(DT_NODELABEL(mco2));
36+
if (device_is_ready(dev2)) {
3137
printk("MCO2 device successfully configured\n");
3238
} else {
3339
printk("MCO2 device not ready\n");
3440
return -1;
3541
}
36-
#endif
42+
#endif /* mco2 */
3743

3844
printk("\nDisplayed the status of all MCO devices - end of example.\n");
3945
return 0;

0 commit comments

Comments
 (0)