This is an automated email from the ASF dual-hosted git repository.

kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 77c7a8a2b hw/mcu/stm32h5: Add shell module mcu with info command
77c7a8a2b is described below

commit 77c7a8a2b6a2fa78fb68e8a841c835b8a8a6c1b2
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Mon Jun 1 11:01:28 2026 +0200

    hw/mcu/stm32h5: Add shell module mcu with info command
    
    This adds package that can display all enabled clocks.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/mcu/stm/stm32h5xx/mcu_cli/pkg.yml       |  35 ++
 hw/mcu/stm/stm32h5xx/mcu_cli/src/mcu_cli.c | 679 +++++++++++++++++++++++++++++
 hw/mcu/stm/stm32h5xx/mcu_cli/syscfg.yml    |  24 +
 3 files changed, 738 insertions(+)

diff --git a/hw/mcu/stm/stm32h5xx/mcu_cli/pkg.yml 
b/hw/mcu/stm/stm32h5xx/mcu_cli/pkg.yml
new file mode 100644
index 000000000..6306612e0
--- /dev/null
+++ b/hw/mcu/stm/stm32h5xx/mcu_cli/pkg.yml
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/mcu/stm/stm32h5xx/mcu_cli
+pkg.description: MCU cli for STM32H5 chips.
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.keywords:
+    - stm32
+    - stm32h5
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/mcu/stm/stm32h5xx"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/util/parse"
+
+pkg.req_apis:
+    - console
+
+pkg.whole_archive: true
diff --git a/hw/mcu/stm/stm32h5xx/mcu_cli/src/mcu_cli.c 
b/hw/mcu/stm/stm32h5xx/mcu_cli/src/mcu_cli.c
new file mode 100644
index 000000000..69fe003e6
--- /dev/null
+++ b/hw/mcu/stm/stm32h5xx/mcu_cli/src/mcu_cli.c
@@ -0,0 +1,679 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/mynewt.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stm32h5xx_hal.h>
+#include <parse/parse.h>
+#include <sys/types.h>
+
+#include "stm32h5xx_ll_rcc.h"
+#include "shell/shell.h"
+#include "console/console.h"
+
+extern uint32_t SystemCoreClock;
+
+static const char *system_clock_source[4] = {"HSI", "CSI", "HSE", "PLL1_P"};
+static const char *pll_source[4] = {"---", "HSI", "CSI", "HSE"};
+
+static const char *
+on_off_state(uint32_t on)
+{
+    return on ? "on" : "off";
+}
+
+char *freq_str(uint32_t freq, char buf[])
+{
+    int freq_m = (int)(freq / 1000000);
+    int freq_m_rem = (int)(freq % 1000000);
+    int freq_k = (int)(freq / 1000);
+    int freq_k_rem = (int)(freq % 1000);
+
+    if (freq == 0) {
+        strcpy(buf, "---");
+    } else if (freq_m && freq_m_rem == 0) {
+        sprintf(buf, "%d MHz", freq_m);
+    } else if (freq_m) {
+        while (freq_m_rem % 10 == 0) {
+            freq_m_rem /= 10;
+        }
+        sprintf(buf, "%d.%d MHz", freq_m, freq_m_rem);
+    } else if (freq_k && freq_k_rem == 0) {
+        sprintf(buf, "%d kHz", freq_k);
+    } else {
+        sprintf(buf, "%d Hz", (int)freq);
+    }
+    return buf;
+}
+
+static void
+print_ahb1_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+
+    streamer_printf(streamer, "  AHB HCLK: %s\n", 
freq_str(HAL_RCC_GetHCLKFreq(), buf));
+
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_GPDMA1EN) {
+        streamer_printf(streamer, "    GPDMA1  %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_GPDMA1EN));
+    }
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_GPDMA2EN) {
+        streamer_printf(streamer, "    GPDMA2  %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_GPDMA2EN));
+    }
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_FLITFEN) {
+        streamer_printf(streamer, "    FLITF   %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_FLITFEN));
+    }
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_CRCEN) {
+        streamer_printf(streamer, "    CRC     %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_CRCEN));
+    }
+#ifdef RCC_AHB1ENR_CORDICEN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_CORDICEN) {
+        streamer_printf(streamer, "    CORDIC  %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_CORDICEN));
+    }
+#endif
+#ifdef RCC_AHB1ENR_FMACEN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_FMACEN) {
+        streamer_printf(streamer, "    FMAC    %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_FMACEN));
+    }
+#endif
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_RAMCFGEN) {
+        streamer_printf(streamer, "    RAMCFG  %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_RAMCFGEN));
+    }
+#ifdef RCC_AHB1ENR_ETHEN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_ETHEN) {
+        streamer_printf(streamer, "    ETH     %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_ETHEN));
+    }
+#endif
+#ifdef RCC_AHB1ENR_ETHTXEN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_ETHTXEN) {
+        streamer_printf(streamer, "    ETHTX   %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_ETHTXEN));
+    }
+#endif
+#ifdef RCC_AHB1ENR_ETHRXEN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_ETHRXEN) {
+        streamer_printf(streamer, "    ETHRX   %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_ETHRXEN));
+    }
+#endif
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_TZSC1EN) {
+        streamer_printf(streamer, "    TZSC1   %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_TZSC1EN));
+    }
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_BKPRAMEN) {
+        streamer_printf(streamer, "    BKPRAM  %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_BKPRAMEN));
+    }
+#ifdef RCC_AHB1ENR_DCACHE1EN
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_DCACHE1EN) {
+        streamer_printf(streamer, "    DCACHE1 %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_DCACHE1EN));
+    }
+#endif
+    if (all || RCC->AHB1ENR & RCC_AHB1ENR_SRAM1EN) {
+        streamer_printf(streamer, "    SRAM1   %s\n", 
on_off_state(RCC->AHB1ENR & RCC_AHB1ENR_SRAM1EN));
+    }
+}
+
+static const uint16_t adc_prescs[] = { 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 
256 };
+
+static void
+print_ahb2_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOAEN) {
+        streamer_printf(streamer, "    GPIOA   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOAEN));
+    }
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOBEN) {
+        streamer_printf(streamer, "    GPIOB   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOBEN));
+    }
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOCEN) {
+        streamer_printf(streamer, "    GPIOC   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOCEN));
+    }
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIODEN) {
+        streamer_printf(streamer, "    GPIOD   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIODEN));
+    }
+#ifdef RCC_AHB2ENR_GPIOEEN
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOEEN) {
+        streamer_printf(streamer, "    GPIOE   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOEEN));
+    }
+#endif
+#ifdef RCC_AHB2ENR_GPIOFEN
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOFEN) {
+        streamer_printf(streamer, "    GPIOF   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOFEN));
+    }
+#endif
+#ifdef RCC_AHB2ENR_GPIOGEN
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOGEN) {
+        streamer_printf(streamer, "    GPIOG   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOGEN));
+    }
+#endif
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOHEN) {
+        streamer_printf(streamer, "    GPIOH   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOHEN));
+    }
+#if defined(RCC_AHB2ENR_GPIOIEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_GPIOIEN) {
+        streamer_printf(streamer, "    GPIOI   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_GPIOIEN));
+    }
+#endif
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_ADCEN) {
+        int prsc = (__LL_ADC_COMMON_INSTANCE(ADC1)->CCR & ADC_CCR_PRESC) >> 
ADC_CCR_PRESC_Pos;
+        streamer_printf(streamer, "    ADC     %s %s\n",
+                        on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_ADCEN),
+                        freq_str(HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC) 
/ adc_prescs[prsc], buf));
+    }
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_DAC1EN) {
+        streamer_printf(streamer, "    DAC1    %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_DAC1EN));
+    }
+#if defined(RCC_AHB2ENR_DCMI_PSSIEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_DCMI_PSSIEN) {
+        streamer_printf(streamer, "    DCMI    %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_DCMI_PSSIEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_AESEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_AESEN) {
+        streamer_printf(streamer, "    AES     %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_AESEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_HASHEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_HASHEN) {
+        streamer_printf(streamer, "    HASH    %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_HASHEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_RNGEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_RNGEN) {
+        streamer_printf(streamer, "    RNG     %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_RNGEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_PKAEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_PKAEN) {
+        streamer_printf(streamer, "    PKA     %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_PKAEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_SAESEN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_SAESEN) {
+        streamer_printf(streamer, "    SAES    %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_SAESEN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_SRAM2EN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_SRAM2EN) {
+        streamer_printf(streamer, "    SRAM2   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_SRAM2EN));
+    }
+#endif
+#if defined(RCC_AHB2ENR_SRAM3EN)
+    if (all || RCC->AHB2ENR & RCC_AHB2ENR_SRAM3EN) {
+        streamer_printf(streamer, "    SRAM3   %s\n", 
on_off_state(RCC->AHB2ENR & RCC_AHB2ENR_SRAM3EN));
+    }
+#endif
+}
+
+uint32_t sdmmc_sck_freq(uint32_t f, SDMMC_TypeDef *sdmmc)
+{
+    uint32_t div = ((sdmmc->CLKCR & SDMMC_CLKCR_CLKDIV_Msk) >> 
SDMMC_CLKCR_CLKDIV_Pos) * 2;
+    if (div == 0) div = 1;
+    return f / div;
+}
+
+static void
+print_ahb4_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+    char buf1[20];
+    static const char bus_width[4] = "148?";
+    uint32_t freq;
+
+#if defined(RCC_AHB4ENR_OTFDEC1EN)
+    if (all || RCC->AHB4ENR & RCC_AHB4ENR_OTFDEC1EN) {
+        streamer_printf(streamer, "    OTFDEC1 %s\n", 
on_off_state(RCC->AHB4ENR & RCC_AHB4ENR_OTFDEC1EN));
+    }
+#endif
+#if defined(RCC_AHB4ENR_SDMMC1EN)
+    if (all || RCC->AHB4ENR & RCC_AHB4ENR_SDMMC1EN) {
+        freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
+        streamer_printf(streamer, "    SDMMC1  %s %s SD_CK %s BUS %cb\n",
+                        on_off_state(RCC->AHB4ENR & RCC_AHB4ENR_SDMMC1EN),
+                        freq_str(freq, buf), freq_str(sdmmc_sck_freq(freq, 
SDMMC1), buf1),
+                        bus_width[(SDMMC1->CLKCR & SDMMC_CLKCR_WIDBUS_Msk) >> 
SDMMC_CLKCR_WIDBUS_Pos]);
+    }
+#endif
+#if defined(RCC_AHB4ENR_SDMMC2EN)
+    if (all || RCC->AHB4ENR & RCC_AHB4ENR_SDMMC2EN) {
+        freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2);
+        streamer_printf(streamer, "    SDMMC2  %s %s SD_CK %s BUS %cb\n",
+                        on_off_state(RCC->AHB4ENR & RCC_AHB4ENR_SDMMC2EN),
+                        freq_str(freq, buf), freq_str(sdmmc_sck_freq(freq, 
SDMMC2), buf1),
+                        bus_width[(SDMMC2->CLKCR & SDMMC_CLKCR_WIDBUS_Msk) >> 
SDMMC_CLKCR_WIDBUS_Pos]);
+    }
+#endif
+#if defined(RCC_AHB4ENR_FMCEN)
+    if (all || RCC->AHB4ENR & RCC_AHB4ENR_FMCEN) {
+        streamer_printf(streamer, "    FMC     %s\n", 
on_off_state(RCC->AHB4ENR & RCC_AHB4ENR_FMCEN));
+    }
+#endif
+#if defined(RCC_AHB4ENR_OCTOSPI1EN)
+    if (all || RCC->AHB4ENR & RCC_AHB4ENR_OCTOSPI1EN) {
+        streamer_printf(streamer, "    OCTOSPI1 %s\n", 
on_off_state(RCC->AHB4ENR & RCC_AHB4ENR_OCTOSPI1EN));
+    }
+#endif
+}
+
+static uint32_t
+i2c_freq(uint32_t i2c_clock, uint32_t timingr)
+{
+    return i2c_clock / ((1 + ((timingr & I2C_TIMINGR_PRESC) >> 
I2C_TIMINGR_PRESC_Pos))) /
+        ((((timingr & I2C_TIMINGR_SCLL) >> I2C_TIMINGR_SCLL_Pos) + 1 + 4 +
+                              ((timingr & I2C_TIMINGR_SCLH) >> 
I2C_TIMINGR_SCLH_Pos) + 1));
+}
+
+static uint32_t
+spi_freq(uint64_t periph_clk, uint32_t cfg1)
+{
+    uint32_t source_clock = HAL_RCCEx_GetPeriphCLKFreq(periph_clk);
+
+    return source_clock >> (1 + ((cfg1 & SPI_CFG1_MBR_Msk) >> 
SPI_CFG1_MBR_Pos));
+}
+
+void stream_tim(struct streamer *streamer, TIM_TypeDef *tim, const char *name, 
uint32_t base_freq, bool on)
+{
+    char buf1[20];
+    char buf2[20];
+    streamer_printf(streamer, "    %-5s   %s %s (ARR %u) (UP %s)\n", name, 
on_off_state(on),
+                    freq_str(base_freq / (tim->PSC + 1), buf1), (tim->ARR + 1),
+                    ((tim->ARR + 1) != 0) ? freq_str(base_freq / (tim->PSC + 
1) / (tim->ARR + 1), buf2) : "---");
+}
+
+static void
+print_apb1_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+    uint32_t pckl1 = HAL_RCC_GetPCLK1Freq();
+    uint32_t timmul = RCC->CFGR2 & RCC_CFGR2_PPRE1_2 ? 2 : 1;
+    streamer_printf(streamer, "  APB1 PCLK1: %s\n", freq_str(pckl1, buf));
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM2EN) {
+        stream_tim(streamer, TIM2, "TIM2", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM2EN);
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM3EN) {
+        stream_tim(streamer, TIM3, "TIM3", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM3EN);
+    }
+#ifdef RCC_APB1LENR_TIM4EN
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM4EN) {
+        stream_tim(streamer, TIM4, "TIM4", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM4EN);
+    }
+#endif
+#ifdef RCC_APB1LENR_TIM5EN
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM5EN) {
+        stream_tim(streamer, TIM5, "TIM5", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM5EN);
+    }
+#endif
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM6EN) {
+        stream_tim(streamer, TIM6, "TIM6", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM6EN);
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM7EN) {
+        stream_tim(streamer, TIM7, "TIM7", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM7EN);
+    }
+#ifdef RCC_APB1LENR_TIM12EN
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM12EN) {
+        stream_tim(streamer, TIM12, "TIM12", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM12EN);
+    }
+#endif
+#ifdef RCC_APB1LENR_TIM13EN
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM13EN) {
+        stream_tim(streamer, TIM13, "TIM13", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM13EN);
+    }
+#endif
+#ifdef RCC_APB1LENR_TIM14EN
+    if (all || RCC->APB1LENR & RCC_APB1LENR_TIM14EN) {
+        stream_tim(streamer, TIM14, "TIM14", pckl1 * timmul, RCC->APB1LENR & 
RCC_APB1LENR_TIM14EN);
+    }
+#endif
+    if (all || RCC->APB1LENR & RCC_APB1LENR_WWDGEN) {
+        streamer_printf(streamer, "    WWD     %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_WWDGEN));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_SPI2EN) {
+        streamer_printf(streamer, "    SPI2    %s %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_SPI2EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI2, SPI2->CFG1), 
buf));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_SPI3EN) {
+        streamer_printf(streamer, "    SPI3    %s %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_SPI3EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI3, SPI3->CFG1), 
buf));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART2EN) {
+        streamer_printf(streamer, "    USART2  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART2EN));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART3EN) {
+        streamer_printf(streamer, "    USART3  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART3EN));
+    }
+#if defined(RCC_APB1LENR_USART4EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART4EN) {
+        streamer_printf(streamer, "    USART4  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART4EN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART5EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART5EN) {
+        streamer_printf(streamer, "    USART5  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART5EN));
+    }
+#endif
+    if (all || RCC->APB1LENR & RCC_APB1LENR_I2C1EN) {
+        streamer_printf(streamer, "    I2C1    %s %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_I2C1EN),
+                        freq_str(i2c_freq(pckl1, I2C1->TIMINGR), buf));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_I2C2EN) {
+        streamer_printf(streamer, "    I2C2    %s %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_I2C2EN),
+                        freq_str(i2c_freq(pckl1, I2C2->TIMINGR), buf));
+    }
+    if (all || RCC->APB1LENR & RCC_APB1LENR_I3C1EN) {
+        streamer_printf(streamer, "    I3C1    %s %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_I2C1EN),
+                        freq_str(i2c_freq(pckl1, I3C1->TIMINGR0), buf));
+    }
+#if defined(RCC_APB1LENR_CRSEN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_CRSEN) {
+        streamer_printf(streamer, "    CRS     %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_CRSEN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART6EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART6EN) {
+        streamer_printf(streamer, "    USART6  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART6EN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART10EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART10EN) {
+        streamer_printf(streamer, "    USART10 %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART10EN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART11EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART11EN) {
+        streamer_printf(streamer, "    USART11 %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART11EN));
+    }
+#endif
+#if defined(RCC_APB1LENR_CECEN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_CECEN) {
+        streamer_printf(streamer, "    CEC     %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_CECEN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART7EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART7EN) {
+        streamer_printf(streamer, "    USART7  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART7EN));
+    }
+#endif
+#if defined(RCC_APB1LENR_USART8EN)
+    if (all || RCC->APB1LENR & RCC_APB1LENR_USART8EN) {
+        streamer_printf(streamer, "    USART8  %s\n", 
on_off_state(RCC->APB1LENR & RCC_APB1LENR_USART8EN));
+    }
+#endif
+#if defined(RCC_APB1HENR_UART9EN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_UART9EN) {
+        streamer_printf(streamer, "    UART9   %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_UART9EN));
+    }
+#endif
+#if defined(RCC_APB1HENR_UART12EN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_UART12EN) {
+        streamer_printf(streamer, "    UART12  %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_UART12EN));
+    }
+#endif
+#if defined(RCC_APB1HENR_DTSEN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_DTSEN) {
+        streamer_printf(streamer, "    DTS     %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_DTSEN));
+    }
+#endif
+#if defined(RCC_APB1HENR_LPTIM2EN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_LPTIM2EN) {
+        streamer_printf(streamer, "    LPTIM2  %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_LPTIM2EN));
+    }
+#endif
+#if defined(RCC_APB1HENR_FDCANEN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_FDCANEN) {
+        streamer_printf(streamer, "    FDCAN   %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_FDCANEN));
+    }
+#endif
+#if defined(RCC_APB1HENR_UCPD1EN)
+    if (all || RCC->APB1HENR & RCC_APB1HENR_UCPD1EN) {
+        streamer_printf(streamer, "    UCPD1   %s\n", 
on_off_state(RCC->APB1HENR & RCC_APB1HENR_UCPD1EN));
+    }
+#endif
+}
+
+static const char *sai_clk_src[] = {"pll1_q_ck", "pll2_p_ck", "pll3_p_ck", 
"AUDIOCLK", "per_ck"};
+static const char *usb_clk_src[] = {"---", "pll1_q_ck", "pll3_q_ck", 
"hsi48_ker_ck"};
+
+static void
+print_apb2_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+    uint32_t pckl = HAL_RCC_GetPCLK2Freq();
+    uint32_t timmul = RCC->CFGR2 & RCC_CFGR2_PPRE2_2 ? 2 : 1;
+
+    streamer_printf(streamer, "  APB2 PCLK2: %s\n", freq_str(pckl, buf));
+    if (all || RCC->APB2ENR & RCC_APB2ENR_TIM1EN) {
+        stream_tim(streamer, TIM1, "TIM1", pckl * timmul, RCC->APB2ENR & 
RCC_APB2ENR_TIM1EN);
+    }
+    if (all || RCC->APB2ENR & RCC_APB2ENR_SPI1EN) {
+        streamer_printf(streamer, "    SPI1    %s %s\n", 
on_off_state(RCC->APB2ENR & RCC_APB2ENR_SPI1EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI1, SPI1->CFG1), 
buf));
+    }
+#ifdef RCC_APB2ENR_TIM8EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_TIM8EN) {
+        stream_tim(streamer, TIM1, "TIM8", pckl * timmul, RCC->APB2ENR & 
RCC_APB2ENR_TIM8EN);
+    }
+#endif
+    if (all || RCC->APB2ENR & RCC_APB2ENR_USART1EN) {
+        streamer_printf(streamer, "    USART1  %s\n", 
on_off_state(RCC->APB2ENR & RCC_APB2ENR_USART1EN));
+    }
+#ifdef RCC_APB2ENR_TIM15EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_TIM15EN) {
+        stream_tim(streamer, TIM15, "TIM15", pckl * timmul, RCC->APB2ENR & 
RCC_APB2ENR_TIM15EN);
+    }
+#endif
+#ifdef RCC_APB2ENR_TIM16EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_TIM16EN) {
+        stream_tim(streamer, TIM16, "TIM16", pckl * timmul, RCC->APB2ENR & 
RCC_APB2ENR_TIM16EN);
+    }
+#endif
+#ifdef RCC_APB2ENR_TIM17EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_TIM17EN) {
+        stream_tim(streamer, TIM17, "TIM17", pckl * timmul, RCC->APB2ENR & 
RCC_APB2ENR_TIM17EN);
+    }
+#endif
+#ifdef RCC_APB2ENR_SPI4EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_SPI4EN) {
+        streamer_printf(streamer, "    SPI4    %s %s\n", 
on_off_state(RCC->APB2ENR & RCC_APB2ENR_SPI4EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI2, SPI2->CFG1), 
buf));
+    }
+#endif
+#ifdef RCC_APB2ENR_SPI6EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_SPI6EN) {
+        streamer_printf(streamer, "    SPI6    %s %s\n", 
on_off_state(RCC->APB2ENR & RCC_APB2ENR_SPI6EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI6, SPI6->CFG1), 
buf));
+    }
+#endif
+#ifdef RCC_APB2ENR_SAI1EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_SAI1EN) {
+        streamer_printf(streamer, "    SAI1    %s %s (%s)\n",
+                        on_off_state(RCC->APB2ENR & RCC_APB2ENR_SAI1EN),
+                        
freq_str(HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1), buf),
+                        sai_clk_src[(RCC->CCIPR5 >> RCC_CCIPR5_SAI1SEL_Pos) & 
7]);
+    }
+#endif
+#ifdef RCC_APB2ENR_SAI2EN
+    if (all || RCC->APB2ENR & RCC_APB2ENR_SAI2EN) {
+        streamer_printf(streamer, "    SAI2    %s %s (%s)\n",
+                        on_off_state(RCC->APB2ENR & RCC_APB2ENR_SAI2EN),
+                        
freq_str(HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2), buf),
+                        sai_clk_src[(RCC->CCIPR5 >> RCC_CCIPR5_SAI2SEL_Pos) & 
7]);
+    }
+#endif
+    if (all || RCC->APB2ENR & RCC_APB2ENR_USBEN) {
+        streamer_printf(streamer, "    USB     %s (%s)\n",
+                        on_off_state(RCC->APB2ENR & RCC_APB2ENR_USBEN),
+                        usb_clk_src[(RCC->CCIPR4 >> RCC_CCIPR4_USBSEL_Pos) & 
3]);
+    }
+}
+
+static void
+print_apb3_peripherals(struct streamer *streamer, bool all)
+{
+    char buf[20];
+
+    streamer_printf(streamer, "  APB2 PCLK3: %s\n", 
freq_str(HAL_RCC_GetPCLK3Freq(), buf));
+    if (all || RCC->APB3ENR & RCC_APB3ENR_SBSEN) {
+        streamer_printf(streamer, "    SBS     %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_SBSEN));
+    }
+#ifdef RCC_APB3ENR_SPI5EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_SPI5EN) {
+        streamer_printf(streamer, "    SPI5    %s %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_SPI5EN),
+                        freq_str(spi_freq(RCC_PERIPHCLK_SPI5, SPI5->CFG1), 
buf));
+    }
+#endif
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPUART1EN) {
+        streamer_printf(streamer, "    LPUART1 %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPUART1EN));
+    }
+#ifdef RCC_APB3ENR_I2C3EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_I2C3EN) {
+        streamer_printf(streamer, "    I2C3    %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_I2C3EN));
+    }
+#endif
+#ifdef RCC_APB3ENR_I2C4EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_I2C4EN) {
+        streamer_printf(streamer, "    I2C4    %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_I2C4EN));
+    }
+#endif
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPTIM1EN) {
+        streamer_printf(streamer, "    LPTIM1  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPTIM1EN));
+    }
+#ifdef RCC_APB3ENR_LPTIM3EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPTIM3EN) {
+        streamer_printf(streamer, "    LPTIM3  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPTIM3EN));
+    }
+#endif
+#ifdef RCC_APB3ENR_LPTIM4EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPTIM4EN) {
+        streamer_printf(streamer, "    LPTIM4  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPTIM4EN));
+    }
+#endif
+#ifdef RCC_APB3ENR_LPTIM5EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPTIM5EN) {
+        streamer_printf(streamer, "    LPTIM5  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPTIM5EN));
+    }
+#endif
+#ifdef RCC_APB3ENR_LPTIM6EN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_LPTIM6EN) {
+        streamer_printf(streamer, "    LPTIM6  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_LPTIM6EN));
+    }
+#endif
+#ifdef RCC_APB3ENR_VREFEN
+    if (all || RCC->APB3ENR & RCC_APB3ENR_VREFEN) {
+        streamer_printf(streamer, "    VREF    %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_VREFEN));
+    }
+#endif
+    if (all || RCC->APB3ENR & RCC_APB3ENR_RTCAPBEN) {
+        streamer_printf(streamer, "    RTCAPB  %s\n", 
on_off_state(RCC->APB3ENR & RCC_APB3ENR_RTCAPBEN));
+    }
+}
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+static const struct shell_param mcu_cli_info_params[] = {
+    {"all", "show also disabled peripherals."},
+    {NULL, NULL}
+};
+
+static const struct shell_cmd_help mcu_cli_info_help = {
+    .summary = "show mcu info",
+    .usage = "\n"
+             "info\n"
+             "  Shows clocks, and enabled peripherals.\n"
+             "info all\n"
+             "  Shows clocks and all peripherals.\n",
+    .params = mcu_cli_info_params,
+};
+#endif
+
+static int
+mcu_cli_info_cmd(const struct shell_cmd *cmd, int argc, char **argv,
+                 struct streamer *streamer)
+{
+    char buf[20];
+    bool all;
+    int sw = ((RCC->CFGR1 & RCC_CFGR1_SWS) >> RCC_CFGR1_SWS_Pos);
+
+    all = argc > 1 && strcmp(argv[1], "all") == 0;
+
+    streamer_printf(streamer, "Clocks:\n");
+    if (all || RCC->CR & RCC_CR_HSION) {
+        const int div = (int)(LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos);
+        streamer_printf(streamer, "  HSI: %s %s (div: %d)\n", 
on_off_state(RCC->CR & RCC_CR_HSION),
+            freq_str(64000000 >> div, buf), 1 << div);
+    }
+    if (all || RCC->CR & RCC_CR_CSION) {
+        streamer_printf(streamer, "  CSI: %s\n", on_off_state(RCC->CR & 
RCC_CR_CSION));
+    }
+    if (all || RCC->CR & RCC_CR_HSI48ON) {
+        streamer_printf(streamer, "  HSI48: %s\n", on_off_state(RCC->CR & 
RCC_CR_HSI48ON));
+    }
+    if (all || RCC->CR & RCC_CR_HSEON) {
+        streamer_printf(streamer, "  HSE: %s %s\n", on_off_state(RCC->CR & 
RCC_CR_HSEON),
+            freq_str(HSE_VALUE, buf));
+    }
+    if (all || RCC->CR & RCC_CR_PLL1ON) {
+        PLL1_ClocksTypeDef clocks;
+        HAL_RCCEx_GetPLL1ClockFreq(&clocks);
+        streamer_printf(streamer, "  PLL1: %s src: %s\n", on_off_state(RCC->CR 
& RCC_CR_PLL1ON),
+                        pll_source[RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC]);
+        streamer_printf(streamer, "    PLL1P: %s\n", 
freq_str(clocks.PLL1_P_Frequency, buf));
+        streamer_printf(streamer, "    PLL1Q: %s\n", 
freq_str(clocks.PLL1_Q_Frequency, buf));
+        streamer_printf(streamer, "    PLL1R: %s\n", 
freq_str(clocks.PLL1_R_Frequency, buf));
+    }
+    if (all || RCC->CR & RCC_CR_PLL2ON) {
+        PLL2_ClocksTypeDef clocks;
+        HAL_RCCEx_GetPLL2ClockFreq(&clocks);
+        streamer_printf(streamer, "  PLL2: %s src: %s\n", on_off_state(RCC->CR 
& RCC_CR_PLL2ON),
+                        pll_source[RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2SRC]);
+        streamer_printf(streamer, "    PLL2P: %s\n", 
freq_str(clocks.PLL2_P_Frequency, buf));
+        streamer_printf(streamer, "    PLL2Q: %s\n", 
freq_str(clocks.PLL2_Q_Frequency, buf));
+        streamer_printf(streamer, "    PLL2R: %s\n", 
freq_str(clocks.PLL2_R_Frequency, buf));
+    }
+#ifdef RCC_CR_PLL3ON
+    if (all || RCC->CR & RCC_CR_PLL3ON) {
+        streamer_printf(streamer, "  PLL3: %s src: %s\n", on_off_state(RCC->CR 
& RCC_CR_PLL3ON),
+                        pll_source[RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3SRC]);
+    }
+#endif
+    if (all || RCC->BDCR & RCC_BDCR_LSION) {
+        streamer_printf(streamer, "  LSI: %s\n", on_off_state(RCC->BDCR & 
RCC_BDCR_LSION));
+    }
+    if (all || RCC->BDCR & RCC_BDCR_LSEON) {
+        streamer_printf(streamer, "  LSE: %s\n", on_off_state(RCC->BDCR & 
RCC_BDCR_LSEON));
+    }
+    if (all || RCC->BDCR & RCC_BDCR_RTCEN) {
+        streamer_printf(streamer, "  RTC: %s\n", on_off_state(RCC->BDCR & 
RCC_BDCR_RTCEN));
+    }
+    streamer_printf(streamer, "  SYSCLK: %s\n", freq_str(SystemCoreClock, 
buf));
+    streamer_printf(streamer, "    source: %s\n", system_clock_source[sw]);
+    streamer_printf(streamer, "Peripherals:\n");
+    print_ahb1_peripherals(streamer, all);
+    print_ahb2_peripherals(streamer, all);
+    print_ahb4_peripherals(streamer, all);
+    print_apb1_peripherals(streamer, all);
+    print_apb2_peripherals(streamer, all);
+    print_apb3_peripherals(streamer, all);
+
+    return 0;
+}
+
+static const struct shell_cmd mcu_cli_commands[] = {
+    SHELL_CMD_EXT("info", mcu_cli_info_cmd, &mcu_cli_info_help),
+};
+
+SHELL_MODULE_WITH_TABLE(mcu, mcu_cli_commands);
diff --git a/hw/mcu/stm/stm32h5xx/mcu_cli/syscfg.yml 
b/hw/mcu/stm/stm32h5xx/mcu_cli/syscfg.yml
new file mode 100644
index 000000000..20ce2029e
--- /dev/null
+++ b/hw/mcu/stm/stm32h5xx/mcu_cli/syscfg.yml
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    MCU_CLI_SYSINIT_STAGE:
+        description: >
+            Sysinit stage for mcu info cli.
+        value: 501

Reply via email to