-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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) |
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 | ||
|
||
rsource "../../common/Kconfig.nbu" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no indent |
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 |
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
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) { | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. soc hook |
There was a problem hiding this comment.
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