Skip to content

Conversation

@ZhaoxiangJin
Copy link
Contributor

@ZhaoxiangJin ZhaoxiangJin commented Nov 21, 2025

Originally, function 'mcux_lptmr_get_pending_int' checks if both
TCF and TIE flags are set to determine if an interrupt is pending.
But function 'LPTMR_GetStatusFlags' only returns the status flags,
that is we will never get TIE flag from it. then the function
always returns false.

The correct approach is to read the CSR register directly and check
if both TIE and TCF bits are 1. If yes, there's a pending interrupt;
if not, there isn't.

@ZhaoxiangJin
Copy link
Contributor Author

CC @FelixWang47831

.mode = DT_INST_PROP(n, timer_mode_sel), \
.pin = DT_INST_PROP_OR(n, input_pin, 0), \
.polarity = DT_INST_PROP(n, active_low), \
.free_running = DT_INST_PROP(n, free_running), \
Copy link
Contributor

Choose a reason for hiding this comment

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

You used DT_INST_PROP(n, free_running) which requires the property to exist, but binding does not mark free-running as required, builds will fail if older DTS files omit it.

Suggested change
.free_running = DT_INST_PROP(n, free_running), \
.free_running = DT_INST_PROP_OR(n, free_running, 0), \

Copy link
Contributor Author

Choose a reason for hiding this comment

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

boolean property default false, so there is no build issue if this property is not set.

@Holt-Sun Holt-Sun self-requested a review November 21, 2025 09:43
Holt-Sun
Holt-Sun previously approved these changes Nov 21, 2025
@ZhaoxiangJin ZhaoxiangJin force-pushed the add-dt-property-for-free-running branch from 865840c to b596705 Compare November 24, 2025 07:19
@zejiang0jason
Copy link
Contributor

Hi, I am not sure about the purpose, from the counter driver model, my understanding is the peripheral counter should be reset when reached the top value. What is the purpose of free-running mode?

@ZhaoxiangJin
Copy link
Contributor Author

ZhaoxiangJin commented Nov 24, 2025

Hi, I am not sure about the purpose, from the counter driver model, my understanding is the peripheral counter should be reset when reached the top value. What is the purpose of free-running mode?

When reaching the top, the API expects "can be reset and optional callback is periodically called", which doesn't seem to mandate counter reset.
In my current development, LPTMR serves as a system timer companion low-power mode timer. If it doesn't work in free running mode, it will cause the scheduler to fail to work properly after wakeup.

Enabling free-running mode is one of the solutions. The fundamental solution is to fix the defect in the systick driver. Although I will ultimately use the latter, the former is still an improvement for the lptmr driver.

@zejiang0jason
Copy link
Contributor

Hi, I am not sure about the purpose, from the counter driver model, my understanding is the peripheral counter should be reset when reached the top value. What is the purpose of free-running mode?

When reaching the top, the API expects "can be reset and optional callback is periodically called", which doesn't seem to mandate counter reset. In my current development, LPTMR serves as a system timer companion low-power mode timer. If it doesn't work in free running mode, it will cause the scheduler to fail to work properly after wakeup.

Enabling free-running mode is one of the solutions. The fundamental solution is to fix the defect in the systick driver. Although I will ultimately use the latter, the former is still an improvement for the lptmr driver.

Hi, I would like to ask @nordic-krch 's help to understand the expected behavior. Thanks

@zejiang0jason
Copy link
Contributor

similar as #95143?

@ZhaoxiangJin
Copy link
Contributor Author

similar as #95143?

Seems he is doing something in timer/lptmr, I am not intend to use lptmr for system timer, using lptmr as system timer in all power modes means we should use FRO16K as clock source, but the FRO16K is inaccurate.
image

flags = LPTMR_GetStatusFlags(config->base);

return ((flags & mask) == mask);
return return (uint32_t)!!LPTMR_GetStatusFlags(config->base);
Copy link
Contributor

@FelixWang47831 FelixWang47831 Nov 27, 2025

Choose a reason for hiding this comment

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

TCF(Timer Compare Flag) is set when counter equals compared value even if TIE(Timer Interrupt Enable) is not set.
Since this API is to get pending interrupt, so I think it's necessary to check TIE:

return (config->base->CSR & mask) == mask;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you are correct, i have updated the patch

@ZhaoxiangJin ZhaoxiangJin force-pushed the add-dt-property-for-free-running branch from 349308c to 3a3a9f8 Compare November 27, 2025 02:46
@ZhaoxiangJin
Copy link
Contributor Author

Hello @Holt-Sun, @FelixWang47831, any comments regarding this topic? Thanks.

@Holt-Sun
Copy link
Contributor

Hi, I am not sure about the purpose, from the counter driver model, my understanding is the peripheral counter should be reset when reached the top value. What is the purpose of free-running mode?

When reaching the top, the API expects "can be reset and optional callback is periodically called", which doesn't seem to mandate counter reset. In my current development, LPTMR serves as a system timer companion low-power mode timer. If it doesn't work in free running mode, it will cause the scheduler to fail to work properly after wakeup.
Enabling free-running mode is one of the solutions. The fundamental solution is to fix the defect in the systick driver. Although I will ultimately use the latter, the former is still an improvement for the lptmr driver.

Hi, I would like to ask @nordic-krch 's help to understand the expected behavior. Thanks

See my comment: #100081 (comment)
I rhink the current top callback can meet your free-running alarm needs.

@nordic-krch
Copy link
Contributor

I rhink the current top callback can meet your free-running alarm needs.

Yes, top feature allows to set lower value at which counter will reset. In implementations that i did i actually use one of the compare channels to set that. If not set then counter resets after reaching it's HW top value.

@ZhaoxiangJin
Copy link
Contributor Author

I rhink the current top callback can meet your free-running alarm needs.

Yes, top feature allows to set lower value at which counter will reset. In implementations that i did i actually use one of the compare channels to set that. If not set then counter resets after reaching it's HW top value.

So in reality, whether to reset after reaching top is decided by the driver itself rather than being mandated by the API.

@ZhaoxiangJin
Copy link
Contributor Author

Add Holt as the PR assignee since he is the NXP counter expert and this PR only changes the NXP driver part.

@zejiang0jason
Copy link
Contributor

zejiang0jason commented Dec 3, 2025

Whether the counter will reset or not after reaching top is an important behavior, generally the behaviors should be defined clearly in spec, otherwise when application migrate from one platform to another, the function will be broken.

So in reality, whether to reset after reaching top is decided by the driver itself rather than being mandated by the API.

flags = LPTMR_GetStatusFlags(config->base);

return ((flags & mask) == mask);
return (uint32_t)!!((config->base->CSR & mask) == mask);
Copy link
Contributor

Choose a reason for hiding this comment

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

this doesn't match the commit message description:

The correct behavior is to check only the TCF
(Timer Compare Flag) to see if an interrupt is pending,
regardless of the TIE (Timer Interrupt Enable) status.
This commit updates the function to return the TCF flag
directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

commit message updated.

@ZhaoxiangJin ZhaoxiangJin force-pushed the add-dt-property-for-free-running branch from 3a3a9f8 to a2f16a0 Compare December 3, 2025 05:41
@ZhaoxiangJin
Copy link
Contributor Author

ZhaoxiangJin commented Dec 3, 2025

Whether the counter will reset or not after reaching top is an important behavior, generally the behaviors should be defined clearly in spec, otherwise when application migrate from one platform to another, the function will be broken.

So in reality, whether to reset after reaching top is decided by the driver itself rather than being mandated by the API.

I think it's strange to assume that software should restrict counter hardware from performing a hardware wrap when reaching top. Do all counter hardware implementations even have this feature? I think what we need to define is: counting is free-running modulo the top value, and boundary events should be represented through callbacks/guard periods.

@dleach02 dleach02 removed their assignment Dec 3, 2025
@Holt-Sun Holt-Sun self-requested a review December 4, 2025 01:32
Holt-Sun
Holt-Sun previously approved these changes Dec 4, 2025
@nordic-krch
Copy link
Contributor

I think it's strange to assume that software should restrict counter hardware from performing a hardware wrap when reaching top.

I don't recall such assumption. Counter API assumes that counter always wraps after reaching top. There is the flag COUNTER_TOP_CFG_DONT_RESET but it only indicates what to do just after updating the top (reset or continue to run as is).

Originally, function 'mcux_lptmr_get_pending_int' checks if both
TCF and TIE flags are set to determine if an interrupt is pending.
But function 'LPTMR_GetStatusFlags' only returns the status flags,
that is we will never get TIE flag from it. then the function
always returns false.

The correct approach is to read the CSR register directly and check
if both TIE and TCF bits are 1. If yes, there's a pending interrupt;
if not, there isn't.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
@ZhaoxiangJin ZhaoxiangJin force-pushed the add-dt-property-for-free-running branch from a2f16a0 to 636fca7 Compare December 4, 2025 14:14
@ZhaoxiangJin ZhaoxiangJin changed the title drivers: counter: mcux_lptmr: Add support for free-running mode drivers: counter: lptmr: Fix get_pending_int wrong implementation Dec 4, 2025
@ZhaoxiangJin ZhaoxiangJin requested a review from Holt-Sun December 4, 2025 14:15
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 4, 2025

@jhedberg jhedberg merged commit f052dbb into zephyrproject-rtos:main Dec 5, 2025
28 of 29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants