Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KW45 SoC, and KW45B41-EVK board support #82034

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions soc/nxp/kinetis/kw45/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 NXP
#
# SPDX-License-Identifier: Apache-2.0

zephyr_sources(../../mcx/mcxw/soc.c ../../mcx/mcxw/mcxw71_platform_init.S)

zephyr_include_directories(../../mcx/mcxw/)

zephyr_sources_ifdef(CONFIG_NXP_NBU
../../common/nxp_nbu.c
)

zephyr_include_directories(.)

zephyr_sources_ifdef(
CONFIG_PM
power.c
)

set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../../mcx/mcxw/linker.ld CACHE INTERNAL "")

zephyr_linker_sources_ifdef(CONFIG_BT RAM_SECTIONS ../../mcx/mcxw/sections.ld)
23 changes: 23 additions & 0 deletions soc/nxp/kinetis/kw45/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# KW45 Series

# Copyright 2025 NXP
# SPDX-License-Identifier: Apache-2.0

config SOC_SERIES_KINETIS_KW45
select ARM
select CPU_CORTEX_M33
select CPU_CORTEX_M_HAS_DWT
select HAS_MCUX
select CLOCK_CONTROL
select SOC_RESET_HOOK
select SOC_EARLY_INIT_HOOK

config SOC_KW45B41Z83
select ARM_TRUSTZONE_M
select CPU_CORTEX_M_HAS_SYSTICK
select CPU_HAS_FPU
select CPU_HAS_ARM_SAU
select CPU_HAS_ARM_MPU
select ARMV8_M_DSP

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually why is a driver even here? Driver should be a driver in driver folder, it has no place being in SoC Kconfig tree

rsource "../../common/Kconfig.nbu"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no indent

53 changes: 53 additions & 0 deletions soc/nxp/kinetis/kw45/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# KW45 series configuration options

# Copyright 2025 NXP
# SPDX-License-Identifier: Apache-2.0

if SOC_SERIES_KINETIS_KW45

config SYS_CLOCK_HW_CYCLES_PER_SEC
default 96000000 if CORTEX_M_SYSTICK

config MCUX_FLASH_K4_API
default y

config WDOG_INIT
default n

config SOC_SERIES
default "kw45"

config NUM_IRQS
default 74

if BT

# Include intercore messaging component
config NXP_RF_IMU
default y

# Set the controller's public identity using NXP vendor command
config BT_HCI_SET_PUBLIC_ADDR
default y

# HCI RX buffers are received in ISR context. RX messages
# need to be queued and processed by a dedicated thread
config HCI_NXP_RX_THREAD
default y

endif # BT

config PM
select COUNTER

config FLASH
default y if BT

config BT_BUF_EVT_DISCARDABLE_SIZE
default 84 if BT

choice LIBC_IMPLEMENTATION
default NEWLIB_LIBC if PM
endchoice

endif # SOC_SERIES_KINETIS_KW45
24 changes: 24 additions & 0 deletions soc/nxp/kinetis/kw45/Kconfig.soc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# KW45 Series

# Copyright 2025 NXP
# SPDX-License-Identifier: Apache-2.0

config SOC_SERIES_KINETIS_KW45
bool
select SOC_FAMILY_KINETIS

config SOC_SERIES
default "kw45" if SOC_SERIES_KINETIS_KW45
Comment on lines +10 to +11
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name does not match text


config SOC_KW45B41Z83
bool
select SOC_SERIES_KINETIS_KW45

config SOC
default "kw45b41z83" if SOC_KW45B41Z83

config SOC_PART_NUMBER_KW45B41Z83AFTA
bool

config SOC_PART_NUMBER
default "KW45B41Z83AFTA" if SOC_PART_NUMBER_KW45B41Z83AFTA
146 changes: 146 additions & 0 deletions soc/nxp/kinetis/kw45/power.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright 2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/pm/pm.h>
#include <zephyr/timeout_q.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/drivers/timer/system_timer.h>

#include "fsl_pm_core.h"
#include "fsl_pm_board.h"

#include "fwk_platform_lowpower.h"

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);

#define LPTMR0_DEV DT_NODELABEL(lptmr0)
const struct device *const counter_dev = DEVICE_DT_GET(LPTMR0_DEV);

/* TODO: change this line when PowerDown is enabled
* This definition is needed for compilation, but only used on PowerDown
*/
uint32_t m_warmboot_stack_end __section("RetainedMem");

/* -------------------------------------------------------------------------- */
/* Private variables */
/* -------------------------------------------------------------------------- */

static pm_handle_t pm_hdl;
static bool unsupported_state;
static uint8_t lowest_state;

/* -------------------------------------------------------------------------- */
/* Public functions */
/* -------------------------------------------------------------------------- */

__weak void pm_state_set(enum pm_state state, uint8_t substate_id)
{
int32_t timeout_expiry;
struct counter_top_cfg counter_info;

ARG_UNUSED(substate_id);

__ASSERT(device_is_ready(counter_dev), "ERROR: Counter is not ready to be used");

__disable_irq();
irq_unlock(0);

unsupported_state = false;

switch (state) {
case PM_STATE_SUSPEND_TO_IDLE:
lowest_state = PM_LP_STATE_DEEP_SLEEP;
break;

default:
LOG_DBG("Unsupported power state %u", state);
unsupported_state = true;
break;
}

if (!unsupported_state) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

if (PM_SetConstraints(lowest_state, 0) != 0) {
__ASSERT(0, "ERROR: to set constraint");
}

timeout_expiry = z_get_next_timeout_expiry();

counter_info.ticks =
counter_us_to_ticks(counter_dev, k_ticks_to_us_floor32(timeout_expiry));
counter_info.callback = NULL;
counter_info.user_data = NULL;

counter_set_top_value(counter_dev, &counter_info);
/* Disable systick before going to low power */
SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
/* LPTMR (counter) is set to wakeup the system after the requested time */
if (counter_start(counter_dev) != 0) {
__ASSERT(0, "ERROR: can't start timer to wakeup");
}

PM_EnterLowPower(k_ticks_to_us_floor64(timeout_expiry));
}
}

/* Handle SOC specific activity after Low Power Mode Exit */
__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
{
uint32_t slept_time_ticks;
uint32_t slept_time_us;

ARG_UNUSED(state);
ARG_UNUSED(substate_id);

if (!unsupported_state) {
counter_get_value(counter_dev, &slept_time_ticks);
/* Reactivate systick */
SysTick->CTRL |= (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);

counter_stop(counter_dev);
slept_time_us = counter_ticks_to_us(counter_dev, slept_time_ticks);
/* Announce the time slept to the kernel*/
sys_clock_announce(k_us_to_ticks_near32(slept_time_us));

if (PM_ReleaseConstraints(lowest_state, 0) != 0) {
__ASSERT(0, "ERROR: to release constraint");
}
}
/* Clear PRIMASK */
__enable_irq();
}

static int kw45_power_init(void)
{
int ret = 0;

PM_CreateHandle(&pm_hdl);
PM_EnablePowerManager(true);

PLATFORM_LowPowerInit();
#if !defined(CONFIG_BT)
RFMC->CTRL |= RFMC_CTRL_RFMC_RST(0x1U);
RFMC->CTRL &= ~RFMC_CTRL_RFMC_RST_MASK;

/* NBU was probably in low power before the RFMC reset, so we need to wait for
* the FRO clock to be valid before accessing RF_CMC
*/
while ((RFMC->RF2P4GHZ_STAT & RFMC_RF2P4GHZ_STAT_FRO_CLK_VLD_STAT_MASK) == 0U) {
;
}

RF_CMC1->RADIO_LP |= RF_CMC1_RADIO_LP_CK(0x2);

/* Force low power entry request to the radio domain */
RFMC->RF2P4GHZ_CTRL |= RFMC_RF2P4GHZ_CTRL_LP_ENTER(0x1U);
#endif
return ret;
}

SYS_INIT(kw45_power_init, PRE_KERNEL_2, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

soc hook

3 changes: 3 additions & 0 deletions soc/nxp/kinetis/soc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ family:
- name: mke15z7
- name: mke17z7
- name: mke17z9
- name: kw45
socs:
- name: kw45b41z83
runners:
run_once:
'--erase':
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ manifest:
groups:
- hal
- name: hal_nxp
revision: be4d59d9c84e9519f3c05645f410b6dd63aeac4f
revision: pull/502/head
path: modules/hal/nxp
groups:
- hal
Expand Down