drivers: counter: nrfx_timer: Add option to use ZLI interrupt

Extended driver configuration in device tree to enable ZLI interrupt.
When zli is set in the device tree then event handlers for alarm and
top is called in ZLI interrupt context. It means that kernel primitives
cannot be used there.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-02-23 11:51:00 +01:00 committed by Carles Cufí
parent 53333d58bf
commit 0419ff72aa
2 changed files with 44 additions and 3 deletions

View file

@ -13,30 +13,55 @@ config COUNTER_TIMER0
depends on !NRF_HW_TIMER0_RESERVED
select COUNTER_NRF_TIMER
config COUNTER_TIMER0_ZLI
bool "Event in ZLI interrupt context"
depends on COUNTER_TIMER0
depends on ZERO_LATENCY_IRQS
config COUNTER_TIMER1
bool "Enable Counter on TIMER1"
depends on HAS_HW_NRF_TIMER1
depends on !NRF_HW_TIMER1_RESERVED
select COUNTER_NRF_TIMER
config COUNTER_TIMER1_ZLI
bool "Event in ZLI interrupt context"
depends on COUNTER_TIMER1
depends on ZERO_LATENCY_IRQS
config COUNTER_TIMER2
bool "Enable Counter on TIMER2"
depends on HAS_HW_NRF_TIMER2
depends on !NRF_HW_TIMER2_RESERVED
select COUNTER_NRF_TIMER
config COUNTER_TIMER2_ZLI
bool "Event in ZLI interrupt context"
depends on COUNTER_TIMER2
depends on ZERO_LATENCY_IRQS
config COUNTER_TIMER3
bool "Enable Counter on TIMER3"
depends on HAS_HW_NRF_TIMER3
depends on !NRF_HW_TIMER3_RESERVED
select COUNTER_NRF_TIMER
config COUNTER_TIMER3_ZLI
bool "Event in ZLI interrupt context"
depends on COUNTER_TIMER3
depends on ZERO_LATENCY_IRQS
config COUNTER_TIMER4
bool "Enable Counter on TIMER4"
depends on HAS_HW_NRF_TIMER4
depends on !NRF_HW_TIMER4_RESERVED
select COUNTER_NRF_TIMER
config COUNTER_TIMER4_ZLI
bool "Event in ZLI interrupt context"
depends on COUNTER_TIMER4
depends on ZERO_LATENCY_IRQS
config COUNTER_RTC0
bool "Enable Counter on RTC0"
depends on HAS_HW_NRF_RTC0

View file

@ -387,14 +387,30 @@ static const struct counter_driver_api counter_nrfx_driver_api = {
#define TIMER(idx) DT_NODELABEL(timer##idx)
#define TIMER_PROP(idx, prop) DT_PROP(TIMER(idx), prop)
#define TIMER_IRQ_CONNECT(idx) \
COND_CODE_1(CONFIG_COUNTER_TIMER##idx##_ZLI, \
(IRQ_DIRECT_CONNECT(DT_IRQN(TIMER(idx)), \
DT_IRQ(TIMER(idx), priority), \
counter_timer##idx##_isr_wrapper, \
IRQ_ZERO_LATENCY)), \
(IRQ_CONNECT(DT_IRQN(TIMER(idx)), DT_IRQ(TIMER(idx), priority),\
irq_handler, DEVICE_DT_GET(TIMER(idx)), 0)) \
)
#define COUNTER_NRFX_TIMER_DEVICE(idx) \
BUILD_ASSERT(TIMER_PROP(idx, prescaler) <= \
TIMER_PRESCALER_PRESCALER_Msk, \
"TIMER prescaler out of range"); \
static int counter_##idx##_init(const struct device *dev) \
COND_CODE_1(CONFIG_COUNTER_TIMER##idx##_ZLI, ( \
ISR_DIRECT_DECLARE(counter_timer##idx##_isr_wrapper) \
{ \
irq_handler(DEVICE_DT_GET(TIMER(idx))); \
/* No rescheduling, it shall not access zephyr primitives. */ \
return 0; \
}), ()) \
static int counter_##idx##_init(const struct device *dev) \
{ \
IRQ_CONNECT(DT_IRQN(TIMER(idx)), DT_IRQ(TIMER(idx), priority), \
irq_handler, DEVICE_DT_GET(TIMER(idx)), 0); \
TIMER_IRQ_CONNECT(idx); \
static const struct counter_timer_config config = { \
.freq = TIMER_PROP(idx, prescaler), \
.mode = NRF_TIMER_MODE_TIMER, \