Skip to content

Commit 35e267d

Browse files
manuarguecarlescufi
authored andcommitted
drivers: pwm: mcux_ftm: support multiple interrupts
Rework the interrupt handlers of the FTM driver to support SoCs on which FTM channels and overflow are routed through individual interrupts, as opposed to a single OR'ed interrupt. Signed-off-by: Manuel Argüelles <[email protected]>
1 parent 747aacb commit 35e267d

File tree

1 file changed

+68
-8
lines changed

1 file changed

+68
-8
lines changed

drivers/pwm/pwm_mcux_ftm.c

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,24 @@ static void mcux_ftm_capture_second_edge(const struct device *dev, uint32_t chan
383383
}
384384
}
385385

386-
static void mcux_ftm_isr(const struct device *dev)
386+
static bool mcux_ftm_handle_overflow(const struct device *dev)
387387
{
388388
const struct mcux_ftm_config *config = dev->config;
389389
struct mcux_ftm_data *data = dev->data;
390-
bool overflow = false;
390+
391+
if (FTM_GetStatusFlags(config->base) & kFTM_TimeOverflowFlag) {
392+
data->overflows++;
393+
FTM_ClearStatusFlags(config->base, kFTM_TimeOverflowFlag);
394+
return true;
395+
}
396+
397+
return false;
398+
}
399+
400+
static void mcux_ftm_irq_handler(const struct device *dev, uint32_t chan_start, uint32_t chan_end)
401+
{
402+
const struct mcux_ftm_config *config = dev->config;
403+
bool overflow;
391404
uint32_t flags;
392405
uint32_t irqs;
393406
uint16_t cnt;
@@ -397,13 +410,9 @@ static void mcux_ftm_isr(const struct device *dev)
397410
irqs = FTM_GetEnabledInterrupts(config->base);
398411
cnt = config->base->CNT;
399412

400-
if (flags & kFTM_TimeOverflowFlag) {
401-
data->overflows++;
402-
overflow = true;
403-
FTM_ClearStatusFlags(config->base, kFTM_TimeOverflowFlag);
404-
}
413+
overflow = mcux_ftm_handle_overflow(dev);
405414

406-
for (ch = 0; ch < MAX_CHANNELS; ch++) {
415+
for (ch = chan_start; ch < chan_end; ch++) {
407416
if ((flags & BIT(ch)) && (irqs & BIT(ch))) {
408417
if (ch & 1) {
409418
mcux_ftm_capture_second_edge(dev, ch, cnt, overflow);
@@ -496,13 +505,64 @@ static const struct pwm_driver_api mcux_ftm_driver_api = {
496505
#define TO_FTM_PRESCALE_DIVIDE(val) _DO_CONCAT(kFTM_Prescale_Divide_, val)
497506

498507
#ifdef CONFIG_PWM_CAPTURE
508+
#if IS_EQ(DT_NUM_IRQS(DT_DRV_INST(0)), 1)
509+
static void mcux_ftm_isr(const struct device *dev)
510+
{
511+
const struct mcux_ftm_config *cfg = dev->config;
512+
513+
mcux_ftm_irq_handler(dev, 0, cfg->channel_count);
514+
}
515+
499516
#define FTM_CONFIG_FUNC(n) \
500517
static void mcux_ftm_config_func_##n(const struct device *dev) \
501518
{ \
502519
IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
503520
mcux_ftm_isr, DEVICE_DT_INST_GET(n), 0); \
504521
irq_enable(DT_INST_IRQN(n)); \
505522
}
523+
#else /* Multiple interrupts */
524+
#define FTM_ISR_FUNC_NAME(suffix) _DO_CONCAT(mcux_ftm_isr_, suffix)
525+
#define FTM_ISR_FUNC(chan_start, chan_end) \
526+
static void mcux_ftm_isr_##chan_start##_##chan_end(const struct device *dev) \
527+
{ \
528+
mcux_ftm_irq_handler(dev, chan_start, chan_end + 1); \
529+
}
530+
531+
#define FTM_ISR_CONFIG(node_id, prop, idx) \
532+
do { \
533+
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
534+
DT_IRQ_BY_IDX(node_id, idx, priority), \
535+
FTM_ISR_FUNC_NAME(DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), \
536+
DEVICE_DT_GET(node_id), \
537+
0); \
538+
irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \
539+
} while (false);
540+
541+
#define FTM_CONFIG_FUNC(n) \
542+
static void mcux_ftm_config_func_##n(const struct device *dev) \
543+
{ \
544+
DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, FTM_ISR_CONFIG) \
545+
}
546+
547+
#if DT_INST_IRQ_HAS_NAME(0, overflow)
548+
static void mcux_ftm_isr_overflow(const struct device *dev)
549+
{
550+
mcux_ftm_handle_overflow(dev);
551+
}
552+
#endif
553+
#if DT_INST_IRQ_HAS_NAME(0, 0_1)
554+
FTM_ISR_FUNC(0, 1)
555+
#endif
556+
#if DT_INST_IRQ_HAS_NAME(0, 2_3)
557+
FTM_ISR_FUNC(2, 3)
558+
#endif
559+
#if DT_INST_IRQ_HAS_NAME(0, 4_5)
560+
FTM_ISR_FUNC(4, 5)
561+
#endif
562+
#if DT_INST_IRQ_HAS_NAME(0, 6_7)
563+
FTM_ISR_FUNC(6, 7)
564+
#endif
565+
#endif /* IS_EQ(DT_NUM_IRQS(DT_DRV_INST(0)), 1) */
506566
#define FTM_CFG_CAPTURE_INIT(n) \
507567
.irq_config_func = mcux_ftm_config_func_##n
508568
#define FTM_INIT_CFG(n) FTM_DECLARE_CFG(n, FTM_CFG_CAPTURE_INIT(n))

0 commit comments

Comments
 (0)