diff --git a/boards/nxp/frdm_ke16z/Kconfig.frdm_ke16z b/boards/nxp/frdm_ke16z/Kconfig.frdm_ke16z new file mode 100644 index 0000000000000..dc4eff77a714e --- /dev/null +++ b/boards/nxp/frdm_ke16z/Kconfig.frdm_ke16z @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_KE16Z + select SOC_MKE16Z4 + select SOC_PART_NUMBER_MKE16Z64VLF4 diff --git a/boards/nxp/frdm_ke16z/board.cmake b/boards/nxp/frdm_ke16z/board.cmake new file mode 100644 index 0000000000000..30c1748c742d6 --- /dev/null +++ b/boards/nxp/frdm_ke16z/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(linkserver "--device=MKE16Z64xxx4:FRDM-KE16Z") +board_runner_args(jlink "--device=MKE16Z64xxx4" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_ke16z/board.yml b/boards/nxp/frdm_ke16z/board.yml new file mode 100644 index 0000000000000..60af40a110a2d --- /dev/null +++ b/boards/nxp/frdm_ke16z/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_ke16z + full_name: FRDM-KE16Z + vendor: nxp + socs: + - name: mke16z4 diff --git a/boards/nxp/frdm_ke16z/doc/frdm_ke16z.jpg b/boards/nxp/frdm_ke16z/doc/frdm_ke16z.jpg new file mode 100644 index 0000000000000..363b9ee33df77 Binary files /dev/null and b/boards/nxp/frdm_ke16z/doc/frdm_ke16z.jpg differ diff --git a/boards/nxp/frdm_ke16z/doc/index.rst b/boards/nxp/frdm_ke16z/doc/index.rst new file mode 100644 index 0000000000000..9d1d30d5c92e9 --- /dev/null +++ b/boards/nxp/frdm_ke16z/doc/index.rst @@ -0,0 +1,163 @@ +.. zephyr:board:: frdm_ke16z + +Overview +******** + +The FRDM-KE16Z is a development board for NXP Kinetis KE1xZ 32-bit +MCU-based platforms. The FRDM-KE16Z contains a robust TSI module +with up to 25 channels which makes this board highly flexible +for touch keys. Offers options for serial +communication, flash programming, and run-control debugging. + +Hardware +******** + +- MKE16Z64VLF4 MCU (up to 48 MHz, 64 KB flash memory, 8 KB RAM) +- OpenSDA Debug Circuit with a virtual serial port +- Touch electrodes in the self-capacitive mode +- Compatible with FRDM-TOUCH, FRDM-MC-LVBLDC, and Arduino® boards +- User Components such as Reset; RGB LED and two user buttons +- 6-axis FXOS8700CQ digital accelerometer and magnetometer + +For more information about the KE1xZ SoC and the FRDM-KE16Z board, see +these NXP reference documents: + +- `KE1XZ SOC Website`_ +- `FRDM-KE16Z Datasheet`_ +- `FRDM-KE16Z Reference Manual`_ +- `FRDM-KE16Z Website`_ +- `FRDM-KE16Z User Guide`_ +- `FRDM-KE16Z Schematics`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +System Clock +============ + +The KE16 SoC is configured to run at 48 MHz using the FIRC. + +Serial Port +=========== + +The KE16 SoC has three UARTs. UART0 (PTB1, PTB0) is configured for the console. + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use Linkserver. + +Early versions of this board have an outdated version of the OpenSDA bootloader +and require an update. Please see the `DAPLink Bootloader Update`_ page for +instructions to update from the CMSIS-DAP bootloader to the DAPLink bootloader. + +Option 1: Linkserver +------------------------------------------------------- + +Install the :ref:`linkserver-debug-host-tools` and make sure they are in your +search path. LinkServer works with the default CMSIS-DAP firmware included in +the on-board debugger. + +Linkserver is the default for this board, ``west flash`` and ``west debug`` will +call the linkserver runner. + +Option 2: :ref:`opensda-jlink-onboard-debug-probe` +-------------------------------------------------- + +Install the :ref:`jlink-debug-host-tools` and make sure they are in your search +path. + +Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program +the `OpenSDA J-Link Firmware for FRDM-KE15Z`_. +Use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Regardless of your choice in debug probe, we will use the OpenSDA +microcontroller as a usb-to-serial adapter for the serial console. + +Connect a USB cable from your PC to J6. + +Use the following settings with your serial terminal of choice (minicom, putty, +etc.): + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_ke16z + :goals: flash + +Open a serial terminal, reset the board (press the SW1 button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.6.0-3478-gb923667860b1 *** + Hello World! frdm_ke16z/mke16z4 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_ke16z + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + ***** Booting Zephyr OS v3.6.0-xxx-gxxxxxxxxxxxx ***** + Hello World! frdm_ke16z + +.. include:: ../../common/board-footer.rst + :start-after: nxp-board-footer + +.. _KE1XZ SoC Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/ke-series-arm-cortex-m4-m0-plus/ke1xz-arm-cortex-m0-plus-5v-main-stream-mcu-with-nxp-touch-and-can-control:KE1xZ + +.. _FRDM-KE16Z Datasheet: + https://www.nxp.com/docs/en/data-sheet/KE1xZP48M48SF0.pdf + +.. _FRDM-KE16Z Reference Manual: + https://www.nxp.com/docs/en/reference-manual/KE1xZP48M48SF0RM.pdf + +.. _FRDM-KE16Z Website: + https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-ke1xmcus:FRDM-KE16Z + +.. _FRDM-KE16Z User Guide: + https://www.nxp.com/document/guide/get-started-with-the-frdm-ke16z:NGS-FRDM-KE16Z + +.. _FRDM-KE16Z Schematics: + https://www.nxp.com/downloads/en/schematics/FRDM-KE16ZSCH.zip + +.. _DAPLink Bootloader Update: + https://os.mbed.com/blog/entry/DAPLink-bootloader-update/ diff --git a/boards/nxp/frdm_ke16z/frdm_ke16z-pinctrl.dtsi b/boards/nxp/frdm_ke16z/frdm_ke16z-pinctrl.dtsi new file mode 100644 index 0000000000000..84f546cb88714 --- /dev/null +++ b/boards/nxp/frdm_ke16z/frdm_ke16z-pinctrl.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + lpuart0_default: lpuart0_default { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; +}; diff --git a/boards/nxp/frdm_ke16z/frdm_ke16z.dts b/boards/nxp/frdm_ke16z/frdm_ke16z.dts new file mode 100644 index 0000000000000..4146108ce4c51 --- /dev/null +++ b/boards/nxp/frdm_ke16z/frdm_ke16z.dts @@ -0,0 +1,76 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_ke16z-pinctrl.dtsi" +#include + +/ { + model = "NXP Freedom KE16Z board"; + compatible = "nxp,ke16z", "nxp,mke16z4"; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &user_button_0; + sw1 = &user_button_1; + }; + + chosen { + zephyr,sram = &sram_u; + zephyr,flash = &flash0; + zephyr,console = &lpuart0; + zephyr,shell-uart = &lpuart0; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + gpios = <&gpiob 5 GPIO_ACTIVE_LOW>; + label = "RED LED"; + }; + green_led: led_1 { + gpios = <&gpiob 4 GPIO_ACTIVE_LOW>; + label = "GREEN LED"; + }; + blue_led: led_2 { + gpios = <&gpiod 1 GPIO_ACTIVE_LOW>; + label = "BLUE LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_0: button_0 { + label = "User SW2"; + gpios = <&gpiod 3 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + user_button_1: button_1 { + label = "User SW3"; + gpios = <&gpiod 2 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&lpuart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&lpuart0_default>; + pinctrl-names = "default"; +}; + +&gpiob { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; diff --git a/boards/nxp/frdm_ke16z/frdm_ke16z.yaml b/boards/nxp/frdm_ke16z/frdm_ke16z.yaml new file mode 100644 index 0000000000000..9e5834514dfdd --- /dev/null +++ b/boards/nxp/frdm_ke16z/frdm_ke16z.yaml @@ -0,0 +1,13 @@ +identifier: frdm_ke16z +name: NXP FRDM-KE16Z +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +flash: 64 +ram: 8 +supported: + - flash + - gpio + - uart diff --git a/boards/nxp/frdm_ke16z/frdm_ke16z_defconfig b/boards/nxp/frdm_ke16z/frdm_ke16z_defconfig new file mode 100644 index 0000000000000..eb3936d7e4fe9 --- /dev/null +++ b/boards/nxp/frdm_ke16z/frdm_ke16z_defconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y + +# Clock Control +CONFIG_CLOCK_CONTROL=y diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts index aa6eec2348a04..555a94a00a051 100644 --- a/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts @@ -116,7 +116,7 @@ &scg { bus_clk { - clock-div = <2>; + clock-div = <4>; }; }; diff --git a/drivers/clock_control/clock_control_mcux_scg.c b/drivers/clock_control/clock_control_mcux_scg.c index c1e7470abb9ab..17becd2a52e17 100644 --- a/drivers/clock_control/clock_control_mcux_scg.c +++ b/drivers/clock_control/clock_control_mcux_scg.c @@ -46,7 +46,8 @@ static int mcux_scg_get_rate(const struct device *dev, case KINETIS_SCG_BUS_CLK: clock_name = kCLOCK_BusClk; break; -#if !(defined(CONFIG_SOC_MKE17Z7) || defined(CONFIG_SOC_MKE17Z9)) +#if !(defined(CONFIG_SOC_MKE17Z7) || defined(CONFIG_SOC_MKE17Z9) || defined(CONFIG_SOC_MKE15Z7)\ + || defined(CONFIG_SOC_MKE15Z4) || defined(CONFIG_SOC_MKE16Z4)) case KINETIS_SCG_FLEXBUS_CLK: clock_name = kCLOCK_FlexBusClk; break; @@ -69,7 +70,7 @@ static int mcux_scg_get_rate(const struct device *dev, break; #endif /* (defined(FSL_FEATURE_SCG_HAS_SPLL) && FSL_FEATURE_SCG_HAS_SPLL) */ #if (defined(FSL_FEATURE_SCG_HAS_LPFLL) && FSL_FEATURE_SCG_HAS_LPFLL) - case KINETIS_SCG_SPLL_CLK: + case KINETIS_SCG_LPFLL_CLK: clock_name = kCLOCK_ScgLpFllClk; break; #endif /* (defined(FSL_FEATURE_SCG_HAS_LPFLL) && FSL_FEATURE_SCG_HAS_LPFLL) */ @@ -136,6 +137,8 @@ static int mcux_scg_init(const struct device *dev) CLOCK_SetClkOutSel(kClockClkoutSelFirc); #elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(spll_clk)) CLOCK_SetClkOutSel(kClockClkoutSelSysPll); +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(lpfll_clk)) + CLOCK_SetClkOutSel(kClockClkoutSelSysLpfll); #else #error Unsupported SCG clkout clock source #endif diff --git a/dts/arm/nxp/nxp_ke17z.dtsi b/dts/arm/nxp/nxp_ke17z.dtsi index 04c331c32b043..c2e32a70563b3 100644 --- a/dts/arm/nxp/nxp_ke17z.dtsi +++ b/dts/arm/nxp/nxp_ke17z.dtsi @@ -47,6 +47,14 @@ }; }; + tsi1: tsi@40047000 { + compatible = "nxp,tsi"; + reg = <0x40047000 0x1000>; + status = "okay"; + interrupts = <25 0>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + }; + /* Remove rtc, it doesn't exist on KE17Z */ /delete-node/ rtc@4003d000; }; diff --git a/dts/arm/nxp/nxp_ke17z512.dtsi b/dts/arm/nxp/nxp_ke17z512.dtsi index 92a1240e0709c..3d5630145a51c 100644 --- a/dts/arm/nxp/nxp_ke17z512.dtsi +++ b/dts/arm/nxp/nxp_ke17z512.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -61,5 +61,23 @@ clocks = <&scg KINETIS_SCG_BUS_CLK>; status = "disabled"; }; + + scg@40064000 { + /delete-node/ lpfll_clk; + + lpfll_clk: lpfll_clk { + compatible = "fixed-clock"; + clock-frequency = <96000000>; + #clock-cells = <0>; + }; + }; + + tsi1: tsi@40047000 { + compatible = "nxp,tsi"; + reg = <0x40047000 0x1000>; + status = "okay"; + interrupts = <25 0>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + }; }; }; diff --git a/dts/arm/nxp/nxp_ke1xz.dtsi b/dts/arm/nxp/nxp_ke1xz.dtsi index fe6b93c28764a..bc7318f86dce6 100644 --- a/dts/arm/nxp/nxp_ke1xz.dtsi +++ b/dts/arm/nxp/nxp_ke1xz.dtsi @@ -89,9 +89,16 @@ #clock-cells = <0>; }; + lpfll_clk: lpfll_clk { + compatible = "fixed-clock"; + clock-frequency = <72000000>; + #clock-cells = <0>; + }; + core_clk: core_clk { compatible = "fixed-factor-clock"; - clocks = <&firc_clk>; + #clocks = <&firc_clk>; + clocks = <&lpfll_clk>; clock-div = <1>; #clock-cells = <0>; }; @@ -116,6 +123,13 @@ clock-div = <1>; #clock-cells = <0>; }; + + flldiv2_clk: flldiv2_clk { + compatible = "fixed-factor-clock"; + clocks = <&lpfll_clk>; + clock-div = <2>; + #clock-cells = <0>; + }; }; pcc: pcc@40065000 { @@ -466,6 +480,49 @@ interrupts = <23 0>; clocks = <&pcc 0x168 KINETIS_PCC_SRC_FIRC_ASYNC>; }; + + pit0: pit@40037000 { + compatible = "nxp,pit"; + reg = <0x40037000 0x1000>; + clocks = <&pcc 0x1a8 KINETIS_PCC_SRC_FIRC_ASYNC>; + interrupts = <22 0>; + max-load-value = <0xffffffff>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + pit0_channel0: pit0_channel@0 { + compatible = "nxp,pit-channel"; + reg = <0>; + status = "disabled"; + }; + + pit0_channel1: pit0_channel@1 { + compatible = "nxp,pit-channel"; + reg = <1>; + status = "disabled"; + }; + + pit0_channel2: pit0_channel@2 { + compatible = "nxp,pit-channel"; + reg = <2>; + status = "disabled"; + }; + + pit0_channel3: pit0_channel@3 { + compatible = "nxp,pit-channel"; + reg = <3>; + status = "disabled"; + }; + }; + + tsi0: tsi@40045000 { + compatible = "nxp,tsi"; + reg = <0x40045000 0x1000>; + status = "okay"; + interrupts = <24 0>; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + }; }; }; diff --git a/dts/arm/nxp/nxp_ke1xz64.dtsi b/dts/arm/nxp/nxp_ke1xz64.dtsi new file mode 100644 index 0000000000000..33e0059e70676 --- /dev/null +++ b/dts/arm/nxp/nxp_ke1xz64.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/delete-node/ &sram_l; +/delete-node/ &sram_u; + +/* Remove non-supported peripherals on 64kB silicon */ +/delete-node/ &ftm2; +/delete-node/ &lpi2c1; +/delete-node/ &lpspi1; +/delete-node/ &edma; +/delete-node/ &flexio; + +/ { + chosen { + zephyr,flash-controller = &ftfa; + }; + + /* Fix sram_l and sram_u, they have different addr and size on KE16Z */ + sram_l: memory@1ffff800 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x1ffff800 DT_SIZE_K(2)>; + zephyr,memory-region = "SRAML"; + }; + + sram_u: memory@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(6)>; + zephyr,memory-region = "SRAMU"; + }; + + soc{ + /* Remove ftfe, it doesn't exist on KE16Z */ + /delete-node/ ftfe; + + ftfa: flash-controller@40020000 { + compatible = "nxp,kinetis-ftfa"; + reg = <0x40020000 0x1000>; + interrupts = <5 0>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(64)>; + erase-block-size = ; + write-block-size = <8>; + }; + }; + + scg@40064000 { + /delete-node/ lpfll_clk; + + lpfll_clk: lpfll_clk { + compatible = "fixed-clock"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + }; + }; +}; diff --git a/include/zephyr/dt-bindings/clock/kinetis_scg.h b/include/zephyr/dt-bindings/clock/kinetis_scg.h index 638cef1c955cd..012258e996b7b 100644 --- a/include/zephyr/dt-bindings/clock/kinetis_scg.h +++ b/include/zephyr/dt-bindings/clock/kinetis_scg.h @@ -29,5 +29,6 @@ #define KINETIS_SCG_FIRC_ASYNC_DIV2_CLK 13U #define KINETIS_SCG_SPLL_ASYNC_DIV1_CLK 14U #define KINETIS_SCG_SPLL_ASYNC_DIV2_CLK 15U +#define KINETIS_SCG_LPFLL_CLK 16U #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_KINETIS_SCG_H_ */ diff --git a/soc/nxp/kinetis/ke1xz/Kconfig.soc b/soc/nxp/kinetis/ke1xz/Kconfig.soc index 962db64482cf8..f3fe903793e27 100644 --- a/soc/nxp/kinetis/ke1xz/Kconfig.soc +++ b/soc/nxp/kinetis/ke1xz/Kconfig.soc @@ -11,6 +11,14 @@ config SOC_SERIES_KE1XZ config SOC_SERIES default "ke1xz" if SOC_SERIES_KE1XZ +config SOC_MKE15Z4 + bool + select SOC_SERIES_KE1XZ + +config SOC_MKE16Z4 + bool + select SOC_SERIES_KE1XZ + config SOC_MKE15Z7 bool select SOC_SERIES_KE1XZ @@ -24,10 +32,30 @@ config SOC_MKE17Z9 select SOC_SERIES_KE1XZ config SOC + default "mke15z4" if SOC_MKE15Z4 + default "mke16z4" if SOC_MKE16Z4 default "mke15z7" if SOC_MKE15Z7 default "mke17z7" if SOC_MKE17Z7 default "mke17z9" if SOC_MKE17Z9 +config SOC_PART_NUMBER_MKE15Z64VFP4 + bool + +config SOC_PART_NUMBER_MKE15Z64VLD4 + bool + +config SOC_PART_NUMBER_MKE15Z64VLF4 + bool + +config SOC_PART_NUMBER_MKE16Z64VFP4 + bool + +config SOC_PART_NUMBER_MKE16Z64VLD4 + bool + +config SOC_PART_NUMBER_MKE16Z64VLF4 + bool + config SOC_PART_NUMBER_MKE15Z128VLL7 bool @@ -65,6 +93,12 @@ config SOC_PART_NUMBER_MKE17Z512VLL9 bool config SOC_PART_NUMBER + default "MKE15Z64VFP4" if SOC_PART_NUMBER_MKE15Z64VFP4 + default "MKE15Z64VLD4" if SOC_PART_NUMBER_MKE15Z64VLD4 + default "MKE15Z64VLF4" if SOC_PART_NUMBER_MKE15Z64VLF4 + default "MKE16Z64VFP4" if SOC_PART_NUMBER_MKE16Z64VFP4 + default "MKE16Z64VLD4" if SOC_PART_NUMBER_MKE16Z64VLD4 + default "MKE16Z64VLF4" if SOC_PART_NUMBER_MKE16Z64VLF4 default "MKE15Z128VLL7" if SOC_PART_NUMBER_MKE15Z128VLL7 default "MKE15Z128VLH7" if SOC_PART_NUMBER_MKE15Z128VLH7 default "MKE15Z256VLL7" if SOC_PART_NUMBER_MKE15Z256VLL7 diff --git a/soc/nxp/kinetis/ke1xz/soc.c b/soc/nxp/kinetis/ke1xz/soc.c index d3b8e156dd4cd..cc0c0e04aaae4 100644 --- a/soc/nxp/kinetis/ke1xz/soc.c +++ b/soc/nxp/kinetis/ke1xz/soc.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * Copyright (c) 2019-2021 Vestas Wind Systems A/S * * Based on NXP k6x soc.c, which is: @@ -43,6 +43,12 @@ static const scg_sys_clk_config_t scg_sys_clk_config = { .src = kSCG_SysClkSrcSirc, #elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(firc_clk)) .src = kSCG_SysClkSrcFirc, +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(lpfll_clk)) + .src = kSCG_SysClkSrcLpFll, +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(sosc_clk)) + .src = kSCG_SysClkSrcSysOsc, +#else +#error Invalid SCG core clock selected #endif }; @@ -66,7 +72,7 @@ ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv2_clk), "Invalid SCG FIRC divider 2 value"); static const scg_firc_config_t scg_firc_config = { .enableMode = kSCG_FircEnable, - .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), /* b20253 */ + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), #if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) .range = kSCG_FircRange48M, #elif MHZ(52) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) @@ -81,31 +87,90 @@ static const scg_firc_config_t scg_firc_config = { .trimConfig = NULL }; -__weak void clk_init(void) +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) +/* System Oscillator (SOSC) configuration */ +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(soscdiv2_clk)), + "Invalid SCG SOSC divider 2 value"); +static const scg_sosc_config_t scg_sosc_config = { + .freq = DT_PROP(SCG_CLOCK_NODE(sosc_clk), clock_frequency), + .monitorMode = kSCG_SysOscMonitorDisable, + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableInLowPower, + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(soscdiv2_clk)), + .workMode = DT_PROP(DT_INST(0, nxp_kinetis_scg), sosc_mode) +}; +#endif + + +static const scg_lpfll_config_t scg_lpfll_config = { + .enableMode = kSCG_LpFllEnable, + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(flldiv2_clk)), +#if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) + .range = kSCG_LpFllRange48M, +#elif MHZ(72) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) + .range = kSCG_LpFllRange72M, +#elif MHZ(96) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) + .range = kSCG_LpFllRange96M, +#else +#error Invalid SCG FLL clock frequency +#endif + .trimConfig = NULL, +}; + + +static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) { - const scg_sys_clk_config_t scg_sys_clk_config_safe = { - .divSlow = kSCG_SysClkDivBy4, - .divCore = kSCG_SysClkDivBy1, - .src = kSCG_SysClkSrcSirc + scg_sys_clk_config_t curConfig; + const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, + .div2 = kSCG_AsyncClkDivBy2, + .range = kSCG_SircRangeHigh}; + scg_sys_clk_config_t sysClkSafeConfigSource = { + .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ + .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ + .src = kSCG_SysClkSrcSirc /* System clock source */ }; - scg_sys_clk_config_t current; + /* Init Sirc. */ + CLOCK_InitSirc(&scgSircConfig); + /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); + + /* Init Firc. */ + CLOCK_InitFirc(fircConfig); + /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ + sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); +} - /* Configure SIRC */ - CLOCK_InitSirc(&scg_sirc_config); - /* Temporary switch to safe SIRC in order to configure FIRC */ - CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config_safe); - do { - CLOCK_GetCurSysClkConfig(¤t); - } while (current.src != scg_sys_clk_config_safe.src); - CLOCK_InitFirc(&scg_firc_config); +__weak void clk_init(void) +{ + scg_sys_clk_config_t current; - /* Only RUN mode supported for now */ +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&scg_sosc_config); + CLOCK_SetXtal0Freq(scg_sosc_config.freq); +#endif + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&scg_firc_config); + /* Init SIRC. */ + CLOCK_InitSirc(&scg_sirc_config); + /* Init LPFLL. */ + CLOCK_InitLpFll(&scg_lpfll_config); + /* Finally init the App desired clock */ CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config); do { CLOCK_GetCurSysClkConfig(¤t); } while (current.src != scg_sys_clk_config.src); + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) CLOCK_SetIpSrc(kCLOCK_Lpuart0, DT_CLOCKS_CELL(DT_NODELABEL(lpuart0), ip_source)); diff --git a/soc/nxp/kinetis/soc.yml b/soc/nxp/kinetis/soc.yml index 38db9d3ebd160..550ff9f998c68 100644 --- a/soc/nxp/kinetis/soc.yml +++ b/soc/nxp/kinetis/soc.yml @@ -31,7 +31,9 @@ family: - name: mkv58f24 - name: ke1xz socs: + - name: mke15z4 - name: mke15z7 + - name: mke16z4 - name: mke17z7 - name: mke17z9 - name: k32lx diff --git a/west.yml b/west.yml index 21ead917837eb..462cf1c289180 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 7a52cbb7cb56db3a276cbd617db3ea7cc3435d12 + revision: pull/595/head path: modules/hal/nxp groups: - hal